web-dev-qa-db-ja.com

ChromeとFirefoxでは高さのレンダリングが異なります

親の高さを明示的に設定せずにheight:autoまたはheight: 0~100%でブロックレベルの要素を設定し、そのブロックレベルの子に下マージンがある場合、Chromeでは異なる方法で高さを計算しますが、 Firefoxで。 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>

divブロックの高さは、margin-bottom + content height of p elementとして計算されます。親要素(autoおよびhtmlタグが原因で、height: 1%bodyに関して計算される理由について混乱しています )高さを明示的に設定するのではなく、高さをautoに直接設定するだけなので、高さは異なりますか?

height: autoに直接設定すると、子ブロックレベル要素の高さとして明確に高さを設定します。これには、下マージンは含まれません。

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>

CSS 2.1仕様を読んで、質問がheightプロパティとmargin collapseトピックでカバーされるかもしれないと考えていますが、FirefoxでもChrome ver。47.0.2526で異なる動作をする理由を理解できませんver。44.0.2では、同じ値の高さが表示されます。

リストされた参照:
https://www.w3.org/TR/CSS2/visudet.html#the-height-property

  • 10.5:割合

    ...包含ブロックの高さが明示的に指定されていない場合(つまり、コンテンツの高さに依存する)、この要素が絶対位置にない場合、値は「自動」に計算されます。 ...

  • 10.6.3:overflowvisibleに計算されるときの通常フローのブロックレベルの非置換要素。

    ...「高さ」が「自動」の場合、高さは要素にブロックレベルの子があるかどうか、およびパディングまたはボーダーがあるかどうかによって異なります。

    要素の高さは、その最上部のコンテンツエッジから次の最初に適用可能なまでの距離です。

    1. ボックスが1つ以上の行でインライン書式設定コンテキストを確立する場合、最後の行ボックスの下端
    2. 子の下部マージンが要素の下部マージンで折りたたまれない場合、最後のインフロー子の下部(折りたたまれている可能性がある)マージンの下部エッジ
    3. 下の境界線上マージンが要素の下マージンで折りたたまない最後のインフロー子のエッジ
    4. それ以外の場合はゼロ

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

  • 8.3.1マージンの折りたたみ。

    要素に上境界線、上余白がなく、子にクリアランスがない場合、インフローブロック要素の上余白は、最初のインフローブロックレベルの子の上余白で折りたたまれます。

    'height'が 'auto'で 'min-height'がゼロのインフローブロックボックスの下マージンは、ボックスにボトムパディングがなく、かつ下部境界線と子の下部マージンは、クリアランスがある上部マージンで折りたたまれません。

    ...ボックスの上部と下部のマージンが隣接している場合、マージンが折り返される可能性があります。この場合、要素の位置は、マージンが折りたたまれている他の要素との関係に依存します。

    • 要素のマージンが親の上部マージンで折りたたまれている場合、ボックスの上部の境界線は親のエッジと同じになるように定義されます。
    • そうでない場合、要素の親がマージンの縮小に参加していないか、親の下マージンのみが関与しています。要素の上部境界線Edgeの位置は、要素にゼロ以外の下部境界線がある場合と同じです。
18
James Yang

最初に、ブラウザメーカー向けの一連のガイドラインであるW3C標準を用意します。

そして、ブラウザメーカーがいて、好きなことを何でもすることができます(Internet Explorerによる逸脱の歴史からもわかるように)。

特に、CSSのパーセンテージの高さでは、ブラウザー間で動作に明確な違いがあります。

1つの例を投稿しました。ここに別のものがあります:

Flexboxの高さの割合:Chrome/SafariとFirefox/IE

フレックスボックスを使用する場合、ChromeおよびSafariは、親のheightプロパティの値に基づいてフレックスアイテムの高さのパーセンテージを解決します。FirefoxおよびIE11/Edgeは、親のフレックス高さを優先します。

Webkitブラウザーは、より伝統的な仕様の解釈に従っているようです。

CSS height property

パーセンテージ
高さのパーセンテージを指定します。割合は、生成されたボックスの包含ブロックの高さに対して計算されます。包含ブロックの高さが明示的に指定されておらず、この要素が絶対に配置されていない場合、値は「自動」に計算されます。

auto
高さは他のプロパティの値に依存します。

つまり、高さのパーセンテージがインフローの子で機能するには、親に設定された高さが必要です。

これが仕様の伝統的な解釈です。「高さ」という用語はheightプロパティの値を意味します。私自身の見方では、この言語は曖昧で解釈の自由がありますが、heightプロパティの要件が主な実装になっています。見たことがない min-heightまたはmax-heightパーセント値を処理する場合、親で動作します。

ただし、最近、FirefoxとIEは、フレックスの高さも受け入れるように解釈を広げました。

FirefoxとIEの例は、親のフレックスの高さを子のパーセント高さの参照として使用する:

前に述べたように、仕様言語はあいまいで解釈しやすいため、どのブラウザが仕様に準拠しているかを知ることは少し難しいです。

定義のこの部分に対する最後の更新は1998年( CSS2 )であり、フレックスの高さなどの新しい形式の高さの出現により、更新は長く待たれているようです。

高さの割合に関しては、仕様の定義が更新されるまで、ブラウザー間のレンダリングの違いが予想されると言ってもいいと思います。


代替ソリューション

子要素に親の最大の高さを取得させる場合に検討する2つの選択肢を次に示します。

  1. 適用display: flex親へ。これにより、align-items: stretchは、親の利用可能な全高を拡張するように子に指示します。

  2. 適用position: relativeは親で、position: absolute; height: 100%; width: 100%子に。絶対配置では、親の高さを指定しなくてもパーセントの高さが機能します。

24
Michael_B