52 votes

Pourquoi "margin : auto" ne centre-t-il pas un élément verticalement ?

Comme vous pouvez le voir dans la démo ci-dessous, margin: auto; centre le bleu div horizontalement, mais pas verticalement. Pourquoi pas ?

.box {
  border: 1px solid red;
  width: 100px;
  height: 100px;
}
.center {
  background: blue;
  width: 50px;
  height: 50px;
  margin: auto;
}

<div class="box">
  <div class="center"></div>
</div>

Ma question ne porte pas sur les solutions de contournement.

0 votes

Ce n'est pas le cas. Le cas d'utilisation pour centrer le contenu horizontalement était vraisemblablement beaucoup plus courant que pour le faire verticalement.

0 votes

@TZHX Techniquement, c'est peut centre verticalement. Voir cet exemple - jsfiddle.net/skdjhpo8

0 votes

L'alignement vertical en CSS est un mythe

37voto

BoltClock Points 249668

Comme mentionné, ce comportement est spécifié dans section 10.6.2 de CSS2.1, et est resté inchangé depuis CSS2 .

Les boîtes de blocs sont empilées verticalement de haut en bas dans un flux normal. De plus, les marges verticales peuvent s'effondrer et ne le font que dans certaines circonstances (dans votre démo, la bordure de l'élément parent empêchera les marges de l'élément enfant de se réduire avec les siennes). Si vous n'avez qu'un seul bloc de ce type et que la hauteur du bloc qui le contient est automatique, ses marges supérieure et inférieure seront de toute façon nulles. Mais si vous avez plus d'une boîte de bloc dans le même flux, ou même des boîtes hors flux affectant la disposition des boîtes dans le flux (dans le cas de dédouanement par exemple), comment voulez-vous que les marges automatiques soient résolues pour ces boîtes en flux ?

C'est pourquoi les marges automatiques gauche et droite sont également réduites à zéro pour les éléments inline (y compris les inlines atomiques) et les flottants (bien que les marges horizontales ne se réduisent jamais). Les boîtes de niveau inline sont posées le long de boîtes de lignes et flotte aussi pour obéir règles uniques de mise en page .

Les boîtes positionnées de manière absolue sont une autre histoire : elles ne sont jamais conscientes de l'existence d'autres boîtes dans le même contexte de positionnement qu'elles, marges supérieures et inférieures automatiques peut sont calculés pour eux par rapport aux blocs qui les contiennent. sans avoir à se soucier de l'interférence d'autres boîtes.

Le Flexbox est également une autre histoire : ce qui distingue la mise en page flex de la mise en page en bloc est que les éléments flex sont par définition toujours conscients des autres éléments flex dans le même contexte de mise en forme flex, y compris le fait qu'il n'y en a pas. En particulier, les flotteurs ne peuvent pas non plus s'immiscer dans le conteneur flex, et vous ne pouvez pas non plus faire flotter des éléments flex pour subvertir ce conteneur. (bien que vous puissiez toujours supprimer complètement un élément enfant de la disposition de flex avec positionnement absolu ). Les marges se comportent très différemment avec les éléments flexibles, en partie à cause de cela. Voir les sections 4.2 , 9.5 et 9.6 .

35voto

Paulie_D Points 10153

Pourquoi... parce que le Spécification du W3C le dit.

Si 'margin-top' ou 'margin-bottom' sont 'auto', leur valeur utilisée est 0.

Quant au "pourquoi" proprement dit... c'est là que la question devrait être abordée.

22voto

Josh Crozier Points 30040

Il ne centre pas l'élément verticalement car il s'agit d'un élément de niveau bloc dans le flux normal. Ainsi, le La règle suivante s'applique :

Si margin-top ou margin-bottom sont auto leur valeur usuelle est de 0.

Il convient également de souligner que la règle ci-dessus s'applique également aux éléments suivants : (voir points 10.6.2 et 10.6.3 pour plus d'informations et de conditions).

  • Éléments remplacés en ligne
  • Éléments remplacés au niveau du bloc dans le flux normal
  • inline-block éléments remplacés en flux normal
  • Éléments remplacés flottants
  • Éléments non remplacés au niveau du bloc dans le flux normal lorsque overflow se calcule en visible

Ceci étant dit, les éléments absolument positionnés, non remplacés et qui n'ont pas de top , height et bottom valeurs de auto constituent une exception à cette règle. Ce qui suit s'applique à partir de point 10.6.4 :

Si aucun des trois top , height et bottom sont auto et si les deux margin-top et margin-bottom sont auto , résoudre l'équation sous la contrainte supplémentaire que les deux marges obtiennent des valeurs égales .

L'exemple ci-dessous montre comment un élément positionné de manière absolue est centré verticalement à l'aide de la fonction margin: auto . Cela fonctionne parce qu'aucune des trois propriétés top , height et bottom ont une valeur de auto :

.box {
  border: 1px solid red;
  width: 100px;
  height: 100px;
  position: relative;
}
.center {
  background: blue;
  width: 50px;
  height: 50px;
  margin: auto;
  position: absolute;
  top: 0; right: 0;
  bottom: 0; left: 0;
}

<div class="box">
  <div class="center"></div>
</div>

En outre, il est sans doute utile de signaler que la règle suivante également :

Si l'un des margin-top ou margin-bottom est auto résoudre l'équation pour cette valeur. Si les valeurs sont surcontraintes, ignorez la valeur de bottom et résoudre cette valeur.

Cela signifie que si l'élément positionné de manière absolue a une valeur de margin-top valeur de auto et un margin-bottom valeur de 0 (c'est-à-dire, margin: auto auto 0 ), l'élément serait absolument positionné en bas par rapport au parent comme dans l'exemple ci-dessous :

.box {
  border: 1px solid red;
  width: 100px;
  height: 100px;
  position: relative;
}
.center {
  background: blue;
  width: 50px;
  height: 50px;
  margin: auto auto 0;
  position: absolute;
  top: 0; right: 0;
  bottom: 0; left: 0;
}

<div class="box">
  <div class="center"></div>
</div>

16voto

Michael_B Points 15556

Pourquoi est-ce que margin:auto travailler verticalement ?

En fait, c'est le cas, mais pas pour tout le monde. display valeur.

Si display est flex , margin: auto à la fois verticalement et horizontalement.

Il en va de même pour display: inline-flex , display: grid et display: inline-grid .

.box {
  border: 1px solid red;
  width: 100px;
  height: 100px;
  display: flex; /* new */
}
.center {
  background: blue;
  width: 50px;
  height: 50px;
  margin: auto;
}

<div class="box">
  <div class="center"></div>
</div>

3voto

LOTUSMS Points 3988

C'est à cause de la possibilité réelle de connaître la hauteur réelle de l'élément dans lequel vous voulez vous centrer verticalement. Pour comprendre cela, pensez d'abord au fonctionnement du centrage horizontal automatique. Vous avez un div auquel vous avez donné une largeur (fixe ou en pourcentage). La largeur peut être calculée dans une certaine mesure. Si la largeur est fixe, c'est parfait. S'il s'agit d'une largeur flexible ou réactive (pourcentage), vous disposez au moins d'une plage que la largeur couvrira avant d'atteindre le prochain point de rupture. Vous prenez cette largeur, moins ce qui se trouve à l'intérieur et divisez le reste des deux côtés.

Maintenant, avec cette information, comment le navigateur pourrait-il calculer la quantité infinie de variations dans lesquelles votre div va croître verticalement ? N'oubliez pas que la taille de l'élément, l'habillage du texte, les marges et la réactivité modifieront également la largeur et obligeront le texte à s'enrouler davantage, et ainsi de suite.

Est-ce une tâche impossible ? Pas vraiment, est-ce que le CSS a consacré du temps et des efforts pour couvrir ce sujet ? Cela ne vaut pas la peine de perdre son temps, je suppose.

Et c'est en gros la réponse que je donne à mes étudiants.

Mais....fret not ! Bootstrap v4 alpha a compris que centrage vertical !

EDIT

Désolé d'éditer cette page tardivement mais j'ai pensé que vous voudriez considérer cette solution pour centrer verticalement et c'est assez simple en utilisant la fonction de calcul.

<div class="foo"></div>

.foo {
  background-color: red;
  height: 6em;
  left: calc(50% - 3em);
  position: absolute;
  top: calc(50% - 3em);
  width: 6em;
}

Voir ICI

5 votes

Il serait plus juste de dire que Flexbox a compris notre centrage vertical et B4a a sauté sur le train en marche.

0 votes

Ça, je ne le savais pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X