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 demande pas de solutions de contournement.
Comme mentionné, ce comportement est spécifié dans section 10.6.2 de CSS2.1, et est resté inchangé par rapport à CSS2 .
Les boîtes à blocs sont empilées verticalement de haut en bas dans un flux normal. De plus, les marges verticales peuvent s'effondrer , et ne le faites 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 s'effondrer avec les siennes). Si vous ne disposez que d'une seule case de bloc et que la hauteur du bloc contenant est auto, 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 en flux (dans le cas de clairance par exemple), comment feriez-vous attendez-vous à ce que les marges automatiques se résolvent pour ces boîtes d'entrée?
C'est pourquoi les marges gauche et droite automatiques sont également mises à zéro pour les éléments en ligne (y compris les lignes atomiques) et les flottants (bien que les marges horizontales ne se réduisent jamais). Les boîtes de niveau en ligne sont posées le long des boîtes de ligne , et les flotteurs obéissent trop règles de mise en page uniques .
Les boîtes absolument positionnées sont une autre histoire: puisqu'elles ne connaissent jamais d'autres boîtes dans le même contexte de positionnement qu'eux-mêmes, les marges supérieure et inférieure automatiques peuvent être calculé pour eux par rapport à leurs blocs contenant sans avoir à se soucier de toute autre boîte qui interfère jamais.
Flexbox est également une autre histoire: ce qui distingue la mise en page flexible de la mise en page par blocs, c'est que les éléments flexibles sont par définition toujours conscients des autres éléments flexibles dans le même contexte de mise en forme flexible, y compris le fait qu'il n'y en a pas. En particulier, ni les flottants ne peuvent s'immiscer dans le conteneur flex, ni les éléments flex pour les inverser (bien que vous puissiez toujours supprimer complètement un élément enfant de la disposition flex avec positionnement absol =). 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 .
Pourquoi ... parce que le W3C spec le dit.
Si "margin-top" ou "margin-bottom" sont "auto", leur valeur utilisée est 0.
Quant au "pourquoi" réel ... la requête devrait vraiment y être adressée.
Il ne centre pas l'élément verticalement car il s'agit d'un élément de niveau bloc dans le flux normal. Ainsi, la la règle suivante s'applique :
Si
margin-top
, oumargin-bottom
sontauto
, leur valeur utilisée est 0.
Il convient également de noter que la règle ci-dessus s'applique également aux éléments suivants: (voir points 10.6.2 et 10.6. pour plus d'informations et conditions).
inline-block
éléments remplacés en écoulement normaloverflow
calcule en visible
Cela étant dit, les éléments non positionnés et absolument remplacés qui n'ont pas les valeurs top
, height
et bottom
de auto
sont une exception à cette règle. Ce qui suit s'applique à partir de point 10.6.4 :
Si aucun des trois
top
,height
etbottom
n'estauto
et si les deuxmargin-top
etmargin-bottom
sontauto
, résolvent l'équation sous la contrainte supplémentaire que les deux marges obtiennent des valeurs égales .
Voir l'exemple ci-dessous montrant comment un élément absolument positionné est centré verticalement à l'aide de margin: auto
. Cela fonctionne car aucune des trois propriétés top
, height
et bottom
n'a la valeur 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>
De plus, il vaut probablement la peine de souligner également règle suivante :
Si l'un des
margin-top
oumargin-bottom
estauto
, résolvez l'équation pour cette valeur. Si les valeurs sont trop contraintes, ignorez la valeur debottom
et résolvez pour cette valeur.
Cela signifie que si l'élément absolument positionné a un margin-top
valeur de auto
et d'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>
Pourquoi
margin:auto
travailler verticalement?
En fait, c'est le cas, mais pas pour chaque valeur de display
.
Si display
est flex
, margin: auto
centre verticalement et horizontalement.
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>
C'est en raison de la possibilité réelle de connaître la hauteur réelle de l'élément dans lequel vous souhaitez centrer verticalement. Pour comprendre cela, pensez d'abord au fonctionnement du centrage horizontal automatique. Vous avez un div auquel vous lui avez donné une largeur (fixe ou pourcentage). La largeur peut être calculée dans une certaine mesure. Si c'est une largeur fixe, tant mieux. S'il est flexible ou réactif (pourcentage) au moins, vous avez une plage que la largeur couvrira avant d'atteindre le prochain point d'arrêt. Vous prenez cette largeur, moins ce qu'elle est à l'intérieur et vous divisez le reste des deux côtés.
Maintenant, avec ces informations, comment le navigateur pourrait-il calculer la quantité infinie de variations dans lesquelles votre div grandira verticalement? Gardez à l'esprit la taille de l'élément, l'habillage du texte, les rembourrages et la réactivité modifieront également la largeur et forceront le texte à envelopper davantage, et ainsi de suite.
Est-ce une tâche impossible? Pas vraiment, CSS a-t-il consacré du temps et des efforts à couvrir cela? Ne vaut pas leur temps, je suppose.
Et c'est essentiellement la réponse que je dis à mes élèves.
Mais ... ne vous inquiétez pas! Bootstrap v4 alpha a compris centrage vertical !
[~ # ~] modifier [~ # ~]
Désolé d'éditer cela tard mais j'ai pensé que vous voudrez peut-être considérer ces solutions pour centrer verticalement et c'est assez simple en utilisant la fonction calc
<div class="foo"></div>
.foo {
background-color: red;
height: 6em;
left: calc(50% - 3em);
position: absolute;
top: calc(50% - 3em);
width: 6em;
}
Voir [~ # ~] ici [~ # ~]