web-dev-qa-db-ja.com

CSSのマージン/パディングの割合が常に幅に対して計算されるのはなぜですか?

CSSボックスモデルの仕様 を見ると、次のことがわかります。

[マージン]パーセンテージは、生成されたボックスの包含ブロックのwidthに関して計算されます。 これは「margin-top」および「margin-bottom」にも当てはまることに注意してください。包含ブロックの幅がこの要素に依存する場合、結果のレイアウトはCSS 2.1では未定義です。 (エンファシス鉱山)

これは確かに真実です。しかしwhy?このように設計することを誰に強制するのでしょうか?あなたが望むシナリオを考えるのは簡単です。特定のことは常にページの上部から25%低くする必要がありますが、垂直パディングを親の水平サイズに相対的にしたい理由を見つけるのは困難です。

ここに私が言及している現象の例を示します。

<div style="border: 1px solid red; margin: 0; padding: 0; width: 200px; height: 800px;">
  This div is 200x800.
  <div style="border: 1px solid blue; margin: 10% 0 0 10%;">
    This div has top-margin of 10% and left-margin of 10% with respect to its parent.
  </div>
</div>

http://jsfiddle.net/8JDYD/

125
mqp

論理的な意味があるので、コメントを回答に転送します。ただし、これは根拠のない推測であることに注意してください。仕様がこのように書かれている理由の実際の理由は、まだ技術的には不明です。

要素の高さは、子の高さによって定義されます。要素にpadding-top:10%(親の高さに対して)がある場合、それは親の高さに影響します。子の高さは親の高さに依存し、親の高さは子の高さに依存するため、高さが不正確になるか、無限ループになります。確かに、これはオフセットparent === parentの場合にのみ影響しますが、それでも変わりません。これは奇妙なケースであり、解決が困難です。

更新:最後の数文は完全に正確ではない場合があります。リーフ要素(子のない子)の高さは、その上のすべての要素の高さに影響するため、多くの異なる状況に影響します。

58
Ryan Kinal

"n%"マージン(およびパディング)がmargin-top/margin-right/margin-bottom/margin-leftの同じであるためには、4つすべてが同じベースに相対的である必要があります。 top/bottomがleft/rightと異なるベースを使用している場合、「n%」マージン(およびパディング)は、4辺すべてで同じことを意味しません。

(また、widthに対して上/下マージンがあると、変なCSSハックが有効になります。これにより、ボックスが再スケーリングされても、不変のアスペクト比を持つボックスを指定できます。)

28
Chuck Kollars

この JSFiddle (Chrome 46.0.2490.86)で遊んで、 this post (中国語で書かれています)。


無限計算推測に対する主な理由は、widthを使用すると同じ無限計算問題に直面することです。

これを見てください JSFiddleparentディスプレイはinline-blockで、マージン/パディングを定義するのに適しています。 childにはマージン値20%があります。 無限計算の推測に従うと:

  1. childの幅はparentに依存します
  2. parentの幅はchildに依存します

しかし、その結果、Chromeはどこかで計算を停止し、結果として:

enter image description here

JSFiddleで「結果」パネルを水平方向に拡張しようとしても、それらの幅は変わらないことがわかります。 childのコンテンツは2行(たとえば、1行ではない)にラップされていることに注意してください。 Chromeはどこかにハードコードしているだけだと思います。 childコンテンツを編集してさらに( JSFiddle )にすると、水平方向に余分なスペースがある限り、Chromeはコンテンツ2行。

したがって、次のことがわかります:無限計算を防ぐ方法があります


私は、この設計は同じ尺度に基づいて4つのマージン/パディング値を保持するだけであるという推測に同意します。

この投稿 (中国語で書かれています)はまた別の理由を提案しています:それは読み/組版の方向性のためです。幅を固定し、高さを無限に(仮想的に)上から下に読みます。

4
Joy

私はOPがwhyを要求していることを理解していますCSS仕様は上/下マージンの割合を幅の%として定義します、しかし、私はそれがまた潜在的な解決策を投稿するのに役立つかもしれないと思った。

最近のほとんどのブラウザは、ビューポートの幅とビューポートの高さに対してマージン番号を指定できるvwとvhをサポートしています。

スクロールバーがない場合、100vw/100vhは幅100%/高さ100%に等しくなります。スクロールバーがある場合、ビューポート番号はこれを考慮しません(%番号は考慮します)。ありがたいことに、ほとんどすべてのブラウザーは17px( こちらを参照 )のスクロールバーサイズを使用しているため、css calc関数を使用してこれを説明できます。スクロールバーが表示されるかどうかわからない場合、このソリューションは機能しません。

たとえば、水平スクロールバーがないと仮定すると、高さの50%の上マージンは、「margin-top:50vh;」と定義できます。水平スクロールバーでは、これは「margin-top:calc(0.5 *(100vh-17px));」と定義できます。 (calcのマイナス演算子とプラス演算子は、両側にスペースが必要であることを忘れないでください!)。

3
VKK