Centrer un bloc div sans la largeur

241

J'ai un problème lorsque j'essaie de centrer les "produits" du bloc div car je ne connais pas à l'avance la largeur du div. Quelqu'un a une solution?

Mise à jour: Le problème que j'ai est que je ne sais pas combien de produits je vais afficher, je peux avoir 1, 2 ou 3 produits, je peux les centrer si c'était un nombre fixe car je connais la largeur du parent div, je ne sais tout simplement pas comment le faire lorsque le contenu est dynamique.

.product_container {
  text-align: center;
  height: 150px;
}

.products {
  height: 140px;
  text-align: center;
  margin: 0 auto;
  clear: ccc both; 
}
.price {
  margin: 6px 2px;
  width: 137px;
  color: #666;
  font-size: 14pt;
  font-style: normal;
  border: 1px solid #CCC;
  background-color:	#EFEFEF;
}
<div class="product_container">
  <div class="products" id="products">
    <div id="product_15">
      <img src="/images/ecommerce/card_default.png">
      <div class="price">R$ 0,01</div>
    </div>

    <div id="product_15">
      <img src="/images/ecommerce/card_default.png">
      <div class="price">R$ 0,01</div>
    </div>   

    <div id="product_15">
      <img src="/images/ecommerce/card_default.png">
      <div class="price">R$ 0,01</div>
    </div>
  </div>
</div>

Nhan
la source
Quel est exactement le problème que vous rencontrez?
anand.trex

Réponses:

256

Mise à jour du 27 février 2015: ma réponse d'origine continue d'être votée, mais maintenant j'utilise plutôt l'approche de @ bobince à la place.

.child { /* This is the item to center... */
  display: inline-block;
}
.parent { /* ...and this is its parent container. */
  text-align: center;
}

Mon message d'origine à des fins historiques:

Vous voudrez peut-être essayer cette approche.

<div class="product_container">
    <div class="outer-center">
        <div class="product inner-center">
        </div>
    </div>
    <div class="clear"/>
</div>

Voici le style correspondant:

.outer-center {
    float: right;
    right: 50%;
    position: relative;
}
.inner-center {
    float: right;
    right: -50%;
    position: relative;
}
.clear {
    clear: both;
}

JSFiddle

L'idée ici est que vous conteniez le contenu que vous souhaitez centrer en deux divisions, une externe et une interne. Vous faites flotter les deux div de sorte que leur largeur diminue automatiquement pour s'adapter à votre contenu. Ensuite, vous positionnez relativement la div externe avec son bord droit au centre du conteneur. Enfin, vous positionnez relativement la div intérieure dans la direction opposée de la moitié de sa propre largeur (en fait la largeur de la div extérieure, mais elles sont les mêmes). En fin de compte, cela centre le contenu dans le conteneur dans lequel il se trouve.

Vous pouvez avoir besoin de ce div vide à la fin si vous dépendez du contenu de votre "produit" pour dimensionner la hauteur du "product_container".

Mike M. Lin
la source
1
Si vous ne fournissez overflow:hiddenpour .product_containerla outer-centerdiv chevauchera autres contenus à proximité à droite de celui - ci. Tous les liens ou boutons à droite outer-centerne fonctionneront pas. Essayez la couleur d'arrière-plan pour outer-centercomprendre la nécessité overflow :hidden. Il s'agit d'une modification suggérée par Cicil Thomas
Benjol
Cette approche est parfaite pour les sites Web de bureau ... sur les mobiles, les divisions internes semblent cependant se fixer à droite. Y a-t-il une solution?
Mich Dart
3
Parle-moi de ça! Parfois, nous avons simplement besoin d'une solution et n'avons pas le luxe d'en choisir une bonne. Un tableau à une seule cellule est une autre option, bien qu'un tableau avec une cellule ne soit pas vraiment un tableau, n'est-ce pas?
Mike M. Lin
@fgysin D'accord, c'est un hack contre-intuitif. Et les concepteurs se demandent pourquoi les gens envisagent toujours de revenir à des dispositions basées sur des tableaux.
Beurk
1
Cette question a cinq ans. Cette réponse est obsolète mais n'a jamais été très élégante au départ. Ce que vous devez faire est d'utiliser display: inline-block
Wray Bowling
140

Un élément avec 'display: block' (comme div est par défaut) a une largeur déterminée par la largeur de son conteneur. Vous ne pouvez pas faire dépendre la largeur d'un bloc de la largeur de son contenu (rétrécir pour s'adapter).

(Sauf pour les blocs qui sont «float: left / right» dans CSS 2.1, mais ce n'est pas utile pour le centrage.)

Vous pouvez définir la propriété 'display' sur 'inline-block' pour transformer un bloc en objet rétréci pour s'adapter qui peut être contrôlé par la propriété text-align de son parent, mais la prise en charge du navigateur est inégale. Vous pouvez surtout vous en tirer en utilisant des hacks (par exemple, voir -moz-inline-stack) si vous voulez aller dans ce sens.

L'autre voie à suivre est les tableaux. Cela peut être nécessaire lorsque vous avez des colonnes dont la largeur ne peut vraiment pas être connue à l'avance. Je ne peux pas vraiment dire ce que vous essayez de faire à partir de l'exemple de code - il n'y a rien d'évident là-dedans qui aurait besoin d' un bloc rétractable - mais une liste de produits pourrait éventuellement être considérée comme tabulaire.

[PS. n'utilisez jamais 'pt' pour les tailles de police sur le web. 'px' est plus fiable si vous avez vraiment besoin d'un texte de taille fixe, sinon les unités relatives comme '%' sont meilleures. Et "clear: ccc both" - une faute de frappe?]

.center{
   text-align:center; 
}

.center > div{ /* N.B. child combinators don't work in IE6 or less */
   display:inline-block;
}

JSFiddle

bobince
la source
53
parent -> text-align: center | enfant-> affichage: bloc en ligne
mdskinner
5
display: inline-blockn'est pas pris en charge dans IE7 et les anciennes versions de Firefox
Jake Wilson
1
@Jakobud, pour IE7, utilisez "display: inline; zoom: 1;" au lieu de "display: inline-block;". Cela fonctionne pour les éléments de bloc.
mihail-haritonov
1
consultez ce lien pour plus d'informations sur la façon d'utiliser cette méthode cross browser - blog.mozilla.org/webdev/2009/02/20/cross-browser-inline-block
keyoke
1
J'ai utilisé ce scss pour l'implémenter, qui fonctionnera tant que votre structure html existera pour le supporter: .center {text-align: center; &: premier enfant {display: inline-block; }}
Dovev Hefetz
95

La plupart des navigateurs prennent en charge la display: table;règle CSS. C'est une bonne astuce pour centrer une div dans un conteneur sans ajouter de code HTML supplémentaire ni appliquer de styles contraignants au conteneur (comme text-align: center;ce qui centrerait tout autre contenu en ligne dans le conteneur), tout en conservant la largeur dynamique pour la div contenue:

HTML:

<div class="container">
  <div class="centered">This content is centered</div>
</div>

CSS:

.centered { display: table; margin: 0 auto; }


Mise à jour (2015-03-09):

La bonne façon de le faire aujourd'hui est en fait d'utiliser des règles flexbox. La prise en charge du navigateur est un peu plus restreinte ( prise en charge des tables CSS vs prise en charge de Flexbox ) mais cette méthode permet également bien d'autres choses, et est une règle CSS dédiée pour ce type de comportement:

HTML:

<div class="container">
  <div class="centered">This content is centered</div>
</div>

CSS:

.container {
  display: flex;
  flex-direction: column; /* put this if you want to stack elements vertically */
}
.centered { margin: 0 auto; }

Maxime Rossini
la source
11
Je pense que c'est certainement la meilleure solution. N'implique aucun piratage étrange avec des divs imbriqués flottants, ou quelque chose comme ça. Je pense que la seule raison pour laquelle il n'est pas mieux noté est que les gens sont allés trop loin contre les tables. Ce n'est pas un tableau, donc je pense que c'est une méthode parfaitement légitime.
Dan Jones
1
D'accord, cela semble être la meilleure solution. Bien que la solution de @ bobince soit également simple, elle a pour effet secondaire de modifier les styles dans l'élément interne.
jorgeh
La display: table;variante est idéale pour les pseudo-éléments ( ::before, ::after) où vous ne pouvez pas ajouter de balisage supplémentaire et vous voulez éviter de perturber les styles d'éléments adjacents.
Walf
20

six façons d'écorcher ce chat:

Bouton un: tout élément de type display: blockprendra la largeur totale des parents. (sauf si combiné avec floatou un display: flexparent). Vrai. Mauvais exemple.

Bouton 2: aller pour display: inline-blockentraînera une largeur automatique (plutôt que pleine). Vous pouvez ensuite centrer l'aide text-align: center sur le bloc d'emballage . Probablement le plus simple et le plus compatible, même avec les navigateurs `` vintage '' ...

.wrapTwo
  text-align: center;
.two
  display: inline-block; // instantly shrinks width

Bouton 3: pas besoin de mettre quoi que ce soit sur l'emballage. C'est peut-être la solution la plus élégante. Fonctionne également verticalement. (Le support du navigateur pour la traduction est assez bon (≥IE9) de nos jours ...).

position: relative;
display: inline-block; // instantly shrinks width
left: 50%;
transform: translateX(-50%);

Btw: également un excellent moyen de centrer verticalement des blocs de hauteur inconnue (en relation avec un positionnement absolu).

Bouton 4: positionnement absolu. Assurez-vous simplement de réserver suffisamment de hauteur dans le wrapper, car personne d'autre ne le fera (ni clearfix ni implicite ...)

.four
  position absolute
  top 0
  left 50%
  transform translateX(-50%)
.wrapFour
  position relative // otherwise, absolute positioning will be relative to page!
  height 50px // ensure height
  background lightgreen // just a marker

Bouton 5: float (qui amène également les éléments de niveau bloc à la largeur dynamique) et un décalage relatif. Bien que je n'aie jamais vu ça dans la nature. Il y a peut-être des inconvénients ...

.wrapFive
  &:after // aka 'clearfix'
    content ''
    display table
    clear both

.five  
  float left
  position relative
  left 50%
  transform translateX(-50%)

Mise à jour: Bouton 6: Et de nos jours, vous pouvez également utiliser la boîte flexible. Notez que les styles s'appliquent au wrapper de l'objet centré.

.wrapSix
  display: flex
  justify-content: center

→ code source complet (syntaxe du stylet)

Frank Nocke
la source
17

J'ai trouvé une solution plus élégante, combinant "inline-block" pour éviter d'utiliser float et le hacky clear: les deux. Cela nécessite toujours des divs imbriqués, ce qui n'est pas très sémantique mais cela fonctionne juste ...

div.outer{
    display:inline-block;
    position:relative;
    left:50%;
}

div.inner{
    position:relative;
    left:-50%;
}

J'espère que ça aide!

JavierIEH
la source
4
<div class="outer">
   <div class="target">
      <div class="filler">
      </div>
   </div>
</div>

.outer{
   width:100%;
   height: 100px;
}

.target{
   position: absolute;
   width: auto;
   height: 100px;
   left: 50%;
   transform: translateX(-50%);
}

.filler{
   position:relative;
   width:150px;
   height:20px;
}

Si l'élément cible est absolument positionné, vous pouvez le centrer en le déplaçant de 50% dans une direction ( left: 50%) puis en le transformant de 50% dans la direction d'opposition ( transform:translateX(-50%)). Cela fonctionne sans définir la largeur de l'élément cible (ou avec width:auto). La position de l'élément parent peut être statique, absolue, relative ou fixe.

Ouest1
la source
1
Ce sera décentré de la moitié de la largeur de l'objet que vous centrez.
4imble
@ 4imble Non, ce ne sera pas le cas. La propriété "left" le déplace de 50% (50% de la largeur de son parent), et translateX (-50%) le déplace de 50% dans l'autre sens (50% de la largeur de l'élément cible).
West1
Ahh oui, j'ai raté le translateX. Pas sûr que ce soit fiable dans n'importe quel IE avant IE 11. Mais vous avez raison.
4imble
3

Par défaut, les divéléments sont affichés en tant qu'éléments de bloc, ils ont donc une largeur de 100%, ce qui les rend centrés sans signification. Comme suggéré par Arief, vous devez spécifier un widthet vous pouvez ensuite utiliser autolors de la spécification marginafin de centrer a div.

Alternativement, vous pouvez également forcer display: inline, mais vous auriez alors quelque chose qui se comporte à peu près comme un spanau lieu d'un div, donc cela n'a pas beaucoup de sens.

Adam Bellaire
la source
3

Cela centrera un élément tel qu'une liste ordonnée, une liste non ordonnée ou tout autre élément. Enveloppez-le simplement avec un Div avec la classe de externalElement et donnez à l'élément interne la classe de innerElement.

La classe des éléments externes représente IE, l'ancien Mozilla et la plupart des nouveaux navigateurs.

 .outerElement {
        display: -moz-inline-stack;
        display: inline-block;
        vertical-align: middle;
        zoom: 1;
        position: relative;
        left: 50%;
    }

.innerElement {
    position: relative;
    left: -50%;
} 
Greg Benner
la source
Veuillez ajouter une description avec votre code. Publier du code seul ne signifie pas grand-chose pour les futurs visiteurs de SO.
Ren
3

utiliser css3 flexbox avec justification-contenu: centre;

    <div class="row">
         <div class="col" style="background:red;">content1</div>
          <div class="col" style="">content2</div>
    </div>


.row {
    display: flex; /* equal height of the children */
    height:100px;
    border:1px solid red;
    width: 400px;
    justify-content:center;
}
zloctb
la source
1

Légère variation sur la réponse de Mike M. Lin

Si vous ajoutez overflow: auto;(ou hidden) à div.product_container, vous n'avez pas besoin div.clear.

Ceci est dérivé de cet article -> http://www.quirksmode.org/css/clearing.html

Voici le HTML modifié:

<div class="product_container">
    <div class="outer-center">
        <div class="product inner-center">
        </div>
    </div>
</div>

Et voici le CSS modifié:

.product_container {
  overflow: auto;
  /* width property only required if you want to support IE6 */
  width: 100%;
}

.outer-center {
  float: right;
  right: 50%;
  position: relative;
}

.inner-center {
  float: right;
  right: -50%;
  position: relative;
}

La raison pour laquelle il vaut mieux sans div.clear(à part le fait d'avoir un élément vide) est l'attribution de marge trop zélée de Firefox.

Si, par exemple, vous avez ce html:

<div class="product_container">
    <div class="outer-center">
        <div class="product inner-center">
        </div>
    </div>
    <div style="clear: both;"></div>
</div>
<p style="margin-top: 11px;">Some text</p>

puis, dans Firefox (8.0 au moment de la rédaction), vous verrez une 11pxmarge avant product_container . Le pire, c'est que vous obtiendrez une barre de défilement verticale pour toute la page, même si le contenu correspond bien aux dimensions de l'écran.

Alexander Pogrebnyak
la source
1

Essayez ce nouveau CSS et balisage

Voici le HTML modifié:

<div class="product_container">
<div class="products" id="products">
   <div id="product_15" class="products_box">
       <img src="/images/ecommerce/card_default.png">
       <div class="price">R$ 0,01</div>
   </div>
   <div id="product_15" class="products_box">
       <img src="/images/ecommerce/card_default.png">
       <div class="price">R$ 0,01</div>
   </div>   
   <div id="product_15" class="products_box">
       <img src="/images/ecommerce/card_default.png">
       <div class="price">R$ 0,01</div>
   </div>
</div>

Et voici le CSS modifié:

<pre>
.product_container 
 {
 text-align:    center;
 height:        150px;
 }

.products {
    left: 50%;
height:35px;
float:left;
position: relative;
margin: 0 auto;
width:auto;
}
.products .products_box
{
width:auto;
height:auto;
float:left;
  right: 50%;
  position: relative;
}
.price {
    margin:        6px 2px;
    width:         137px;
    color:         #666;
    font-size:     14pt;
    font-style:    normal;
    border:        1px solid #CCC;
    background-color:   #EFEFEF;
}

Shinov T
la source
1
<div class="product_container">
<div class="outer-center">
<div class="product inner-center">
    </div>
</div>
<div class="clear"></div>
</div>

.outer-center
{
float: right;
right: 50%;
position: relative;
}
.inner-center 
{
float: right;
right: -50%;
position: relative;
}
.clear 
{
clear: both;
}

.product_container
{
overflow:hidden;
}

Si vous ne fournissez pas "overflow: hidden" pour ".product_container", la div "centre extérieur" chevauchera les autres contenus à proximité à sa droite. Tout lien ou bouton à droite de "centre extérieur" ne fonctionnera pas. Essayez la couleur d'arrière-plan pour "centre extérieur" pour comprendre la nécessité de "débordement: caché"

Cicil Thomas
la source
1

J'ai trouvé une solution intéressante, je faisais des curseurs et je devais centrer les contrôles des diapositives et je l'ai fait et ça fonctionne bien. Vous pouvez également ajouter une position relative au parent et déplacer la position de l'enfant verticalement. Jetez un œil http://jsfiddle.net/bergb/6DvJz/

CSS:

#parent{
        width:600px;
        height:400px;
        background:#ffcc00;
        text-align:center;
    }

#child{
        display:inline-block;
        margin:0 auto;
        background:#fff;
    }  

HTML:

<div id="parent">
    <div id="child">voila</div>
</div>
Nikola
la source
1

Faire display:table;et définir marginsurauto

Bit de code important:

.relatedProducts {
    display: table;
    margin-left: auto;
    margin-right: auto;
}

Peu importe le nombre d'éléments que vous avez maintenant, il s'alignera automatiquement au centre

Exemple dans l'extrait de code:

hahaha
la source
0

J'ai peur que la seule façon de le faire sans spécifier explicitement la largeur soit d'utiliser des tables (haletantes).

Kon
la source
5
reformulé: Si vous ne voulez pas passer une heure à essayer toutes sortes de combinaisons de CSS, de DIV imbriqués et de navigateurs, allez directement aux tableaux.
Eduardo Molteni
Les tableaux ne sont pas conçus pour être utilisés comme éléments de conception. C'est du mauvais style.
Sebi2020
0

Correction de merde, mais ça marche ...

CSS:

#mainContent {
    position:absolute;
    width:600px;
    background:#FFFF99;
}

#sidebar {
    float:left;
    margin-left:610px;
    max-width:300;
    background:#FFCCCC;
}
#sidebar{


    text-align:center;
}

HTML:

<center>
<table border="0" cellspacing="0">
  <tr>
    <td>
<div id="mainContent">
1<br/>
<br/>
123<br/>
123<br/>
123<br/>
</div><div id="sidebar"><br/>
</div></td>
</tr>
</table>
</center>
Lionel
la source
0

Correctif simple qui fonctionne dans les anciens navigateurs (mais utilise des tableaux et nécessite une hauteur à définir):

<div style="width:100%;height:40px;position:absolute;top:50%;margin-top:-20px;">
  <table style="width:100%"><tr><td align="center">
    In the middle
  </td></tr></table>
</div>
Craigo
la source
0
<style type="text/css">
.container_box{
    text-align:center
}
.content{
    padding:10px;
    background:#ff0000;
    color:#ffffff;

}

utiliser la durée de vie des divisions internes

<div class="container_box">
   <span class="content">Hello</span>
</div>
quelqu'un
la source
0

Je sais que cette question est ancienne, mais j'y prends une fissure. Très similaire à la réponse de Bobince mais avec un exemple de code fonctionnel.

Faites de chaque produit un bloc en ligne. Centrez le contenu du conteneur. Terminé.

http://jsfiddle.net/rgbk/6Z2Re/

<style>
.products{
    text-align:center;
}

.product{
    display:inline-block;
    text-align:left;

    background-image: url('http://www.color.co.uk/wp-content/uploads/2013/11/New_Product.jpg');
    background-size:25px;
    padding-left:25px;
    background-position:0 50%;
    background-repeat:no-repeat;
}

.price {
    margin:        6px 2px;
    width:         137px;
    color:         #666;
    font-size:     14pt;
    font-style:    normal;
    border:        1px solid #CCC;
    background-color:   #EFEFEF;
}
</style>


<div class="products">
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
</div>

Voir aussi: Centrer les blocs en ligne avec une largeur dynamique en CSS

Wray Bowling
la source
Cette réponse ne fournit-elle pas déjà la même solution? stackoverflow.com/a/284064/547733
Maxime Rossini
1
vous avez raison, madmox! Ce n'est pas aussi robuste cependant. Je me rends également compte que la définition de l'alignement du texte à gauche ou à droite signifie que cela ne fonctionnera jamais sur un site avec des traductions qui incluent la commutation de l'ordre de lecture de gauche à droite de droite à gauche. text-align sert à aligner du texte, pas des éléments. Idéalement, dans un avenir proche, nous dépendrons de l'affichage: flex pour ce genre de chose.
Wray Bowling
0

C'est une façon de centrer quoi que ce soit à l'intérieur d'un div sans connaître la largeur intérieure des éléments.

#product_15{
    position: relative;
    margin: 0 auto;
    display: table;
}
.price, img{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
Shirley Ashby
la source
-1

ma solution était:

.parent {
    display: flex;
    flex-wrap: wrap;
}

.product {
    width: 240px;
    margin-left: auto;
    height: 127px;
    margin-right: auto;
}
Byron
la source
-7

ajoutez ce css à votre classe product_container

    margin: 0px auto;
    padding: 0px;
    border:0;
    width: 700px;
Bref
la source
La question dit spécifiquement "sans largeur"
Dez Udezue