web-dev-qa-db-fra.com

Les hauteurs s'affichent différemment dans Chrome et Firefox

J'ai trouvé que si nous définissons un élément de niveau bloc avec height:auto ou height: 0~100% sans définir la hauteur du parent avec une valeur explicite, et son enfant de niveau bloc a une marge inférieure, il calculera la hauteur différemment dans Chrome, mais pas dans Firefox. Pour le cas qui a défini height: 1%:

http://codepen.io/anon/pen/BjgKMR

html {
  background: pink;
}

body {
  background: yellow;
}

div {
  height: 1%;
}

inner {
  margin-bottom: 30px;
  margin-top: 20px;
}
<div>
  <p class="inner">block level element</p>
</div>

La hauteur du bloc div sera calculée comme margin-bottom + content height of p element. Je ne comprends pas pourquoi le height: 1% doit être calculé en fonction de auto parce que les éléments parents (html et body tag) ne définissent pas explicitement sa hauteur, mais ont une hauteur différente car nous venons de définir directement la hauteur à auto?

Si nous le définissons directement sur height: auto, il définira clairement la hauteur comme la hauteur de son élément de niveau bloc enfant, qui ne comprend pas sa marge inférieure.

html {
  background: pink;
}

body {
  background: yellow;
}

div {
  height: auto;
}

inner {
  margin-bottom: 30px;
  margin-top: 20px;
}
<div><p class="inner">block level element</p></div>

J'ai lu la spécification CSS 2.1 et je pense que ma question pourrait être couverte par le sujet de la propriété height et de l'effondrement des marges, mais je ne comprends toujours pas pourquoi elle se comporte différemment dans Chrome ver. 47.0.2526, bien que Firefox la version 44.0.2 affichera la hauteur avec la même valeur.

Références répertoriées:
https://www.w3.org/TR/CSS2/visudet.html#the-height-property

  • 10,5: pourcentage

    ... Si la hauteur du bloc conteneur n'est pas spécifiée explicitement (c'est-à-dire qu'elle dépend de la hauteur du contenu) et que cet élément n'est pas positionné de manière absolue, la valeur est calculée sur `` auto ''. ...

  • 10.6.3: Éléments non remplacés de niveau bloc dans un flux normal lorsque overflow calcule en visible.

    ... si 'height' est 'auto', la hauteur dépend si l'élément a des enfants au niveau du bloc et s'il a un remplissage ou des bordures:

    La hauteur de l'élément est la distance entre son bord de contenu supérieur et le premier applicable des éléments suivants:

    1. le bord inférieur de la dernière zone de ligne, si la zone établit un contexte de mise en forme en ligne avec une ou plusieurs lignes
    2. le bord inférieur de la marge inférieure (éventuellement réduite) de son dernier enfant entrant, si la marge inférieure de l'enfant ne s'effondre pas avec la marge inférieure de l'élément
    3. la bordure inférieure Bord du dernier enfant entrant dont la marge supérieure ne s'effondre pas avec la marge inférieure de l'élément
    4. zéro, sinon

https://www.w3.org/TR/2011/REC-CSS2-20110607/box.html#collapsing-margins

  • 8.3.1 effondrement des marges.

    La marge supérieure d'un élément de bloc entrant s'effondre avec la marge supérieure de son premier enfant au niveau du bloc entrant si l'élément n'a pas de bordure supérieure, pas de rembourrage supérieur et que l'enfant n'a aucun dégagement.

    La marge inférieure d'une boîte de bloc d'entrée avec une `` hauteur '' de `` auto '' et une `` hauteur minimale '' de zéro s'effondre avec la dernière marge inférieure de l'enfant au niveau du bloc d'entrée si la boîte n'a pas de rembourrage inférieur et aucune bordure inférieure et la marge inférieure de l'enfant ne s'effondre pas avec une marge supérieure qui a un dégagement.

    ... Si les marges supérieure et inférieure d'une boîte sont adjacentes, il est possible que les marges se réduisent à travers elle. Dans ce cas, la position de l'élément dépend de sa relation avec les autres éléments dont les marges sont réduites.

    • Si les marges de l'élément sont réduites avec la marge supérieure de son parent, le bord supérieur de la boîte est défini comme étant identique à celui du parent.
    • Sinon, soit le parent de l'élément ne participe pas à l'effondrement de la marge, soit seule la marge inférieure du parent est impliquée. La position de la bordure supérieure de l'élément Edge est la même qu'elle aurait été si l'élément avait une bordure inférieure non nulle.
18
James Yang

Vous avez donc d'abord les normes W3C, qui sont un ensemble de lignes directrices pour les fabricants de navigateurs.

Et puis vous avez les fabricants de navigateurs, qui sont libres de faire ce qu'ils veulent (comme en témoigne un historique des écarts d'Internet Explorer).

En particulier, avec les hauteurs de pourcentage CSS, il existe des différences claires de comportement entre les navigateurs.

Vous avez publié un exemple. En voici une autre:

Hauteurs de pourcentage dans Flexbox: Chrome/Safari vs Firefox/IE

Lorsque vous travaillez avec flexbox, Chrome et Safari résolvent les hauteurs de pourcentage sur les éléments flex en fonction de la valeur de la propriété height du parent. Firefox et IE11/Edge priorisent la hauteur de flex du parent.

Il semble que les navigateurs Webkit adhèrent à une interprétation plus traditionnelle de la spécification:

CSS height propriété

pourcentage
Spécifie un pourcentage de hauteur. Le pourcentage est calculé par rapport à la hauteur du bloc contenant la boîte générée. Si la hauteur du bloc conteneur n'est pas spécifiée explicitement et que cet élément n'est pas positionné de manière absolue, la valeur est calculée sur "auto".

auto
La hauteur dépend des valeurs des autres propriétés.

En d'autres termes, pour que le pourcentage de hauteur fonctionne sur un enfant entrant, le parent doit avoir une hauteur définie.

C'est l'interprétation traditionnelle de la spécification: le terme "hauteur" signifie la valeur de la propriété height. Selon moi, ce langage est vague et ouvert à l'interprétation, mais l'exigence de propriété height est devenue l'implémentation prédominante. Je n'ai jamais vu min-height ou max-height travailler sur un parent lorsqu'il s'agit de valeurs en pourcentage.

Récemment, cependant, Firefox et IE ont élargi leur interprétation pour accepter également les hauteurs flexibles.

Exemples de Firefox et IE utilisant la hauteur flexible d'un parent comme référence pour le pourcentage de taille d'un enfant:

Savoir quels navigateurs sont conformes à la spécification est un peu difficile car, comme je l'ai mentionné précédemment, le langage de la spécification semble vague et ouvert à l'interprétation.

Avec la dernière mise à jour de cette partie de la définition en 1998 ( CSS2 ) et l'avènement de nouvelles formes de hauteur telles que la hauteur flexible, une mise à jour semble attendue depuis longtemps.

Je pense qu'il est juste de dire qu'en ce qui concerne les hauteurs en pourcentage, jusqu'à ce que la définition des spécifications soit mise à jour, vous pouvez vous attendre à des différences de rendu entre les navigateurs.


Solutions alternatives

Voici deux alternatives à considérer lorsque vous souhaitez qu'un élément enfant prenne toute la hauteur du parent.

  1. Appliquer display: flex au parent. Cela définit automatiquement align-items: stretch, qui indique à l'enfant d'étendre toute la hauteur disponible du parent.

  2. Appliquer position: relative sur le parent et position: absolute; height: 100%; width: 100% sur l'enfant. Avec un positionnement absolu, un pourcentage de hauteur fonctionnera sans hauteur spécifiée sur le parent.

24
Michael_B