2つのdivを作成しようとしています。内側のdivは外側のdivより大きく、外側のdivはoverflow:scroll
を持ち、内側のdivはmargin:25px
を持ちます。だから私はこれをします:
#outer {
width: 200px;
height: 100px;
overflow: scroll;
}
#inner {
width: 400px;
height: 200px;
margin: 25px;
}
...
<div id="outer">
<div id="inner">
</div>
</div>
内側のdivのマージンが予想どおり25pxである代わりに、3つの側面に25pxのマージンがありますが、右側にはありません。これは私の意見では非常に直感に反しています。
内側のdiv + 50pxを含めるのに十分な幅のある中央のdivを追加すると、正しく見えるようになりますが、これは面倒な回避策のようです。
JSFiddleの私の例を参照してください: http://jsfiddle.net/d3Nhu/16/
これは、すべての主要なブラウザで同じように発生します。この動作に正当な理由はありますか? CSS仕様によると、これは正しい動作ですか?
注:この例で期待するとおり、overflow:auto
の代わりにoverflow:scroll
を使用しても違いはありません。
[〜#〜] edit [〜#〜]:私は見ていませんこの動作の回避策について。 (私はすでにそれを見つけました。)特に CSS仕様 に記載されている場合、この動作の理由に関する洞察を探していますどこでも。
マージンは、ラッパーを外側に拡張するのではなく、ラッパーから要素を移動するためのものです。
この動作は、ドキュメント内の任意の場所で水平width
に加えてmargin
を指定することと一致しています。それを分解するために、overflow
プロパティのないラッパーを特定し、margin
がラッパー要素を展開しない次のスニペットを検討してください。
body {
padding: 20px;
}
.outer {
width: 400px;
border: 1px solid black;
}
.inner {
width: 400px;
height: 40px;
margin: 0 20px;
background: grey;
}
<div class="outer">
<div class="inner">
</div>
</div>
ご覧のとおり、margin
によってラッパーのサイズが拡張されず、要素がオーバーフローし続けただけです。この動作は、CSS 2.1仕様に記載されているビジュアルフォーマットモデルの詳細に記載されています。
次の制約は、他のプロパティの使用された値の間で保持する必要があります。
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' =包含ブロックの幅
[...]
上記のすべてに「自動」以外の計算値がある場合、値は「過剰制約」されていると呼ばれ、使用される値の1つがその計算値と異なる必要があります。包含ブロックの 'direction'プロパティの値が 'ltr'の場合、指定された 'margin-right'の値は無視され、等式がtrueになるように値が計算されます。 'direction'の値が 'rtl'の場合、これは代わりに 'margin-left'に発生します。
この抜粋は非常に密集しているので、簡単に言えば、border
とpadding
の幅は無視してみましょう。どちらも0
なので、width
、margin-left
、およびmargin-right
。
これで、固定のwidth
とmargin-left
およびmargin-right
の値が得られたため、値は「過剰制約」されています。この例では、方向がデフォルトでltr
であるため、margin-right
は強制的に補正されます。
方向の影響を確認するために、ラッパー要素にdir="rtl"
属性を追加してみましょう。
body {
padding: 20px;
}
.outer {
width: 400px;
border: 1px solid black;
}
.inner {
width: 400px;
height: 40px;
margin: 0 20px;
background: grey;
}
<div class="outer" dir="rtl">
<div class="inner">
</div>
</div>
これで、要素は左側にオーバーフローしています。このdir="rtl"
属性がoverflow: scroll
の例に同じ影響を与えるかどうかを見てみましょう。
#outer {
border: 1px solid #00F;
width: 200px;
height: 100px;
overflow: scroll;
}
#inner {
border: 1px solid #F0F;
margin: 25px;
width: 400px;
height: 200px;
}
<div id="outer" dir="rtl">
<div id="inner">
</div>
</div>
はい、そうです。マージンが右側ではなく左側に欠けている。
overflow: scroll
にマージンが含まれていないのですか?主に仕様がそうすべきではないと言っているからです。 overflow
プロパティのCSS 2仕様を見てみましょう。
オーバーフローが発生するたびに、 'overflow'プロパティは、ボックスがパディングエッジに切り取られるかどうかを指定し、切り取られる場合は、切り取られたコンテンツにアクセスするためにスクロールメカニズムが提供されるかどうかを指定します。
「切り取られたコンテンツ」が具体的にどのように表示されているかをご覧ください。 「コンテンツ」の説明については、CSS 2仕様の次の図を参照してください。
ご覧のとおり、margin
はcontent
とは別のものです。ただし、この時点では、パディングとボーダーがスクロール領域に含まれていることに注意する必要があります。そのため、仕様に「コンテンツ」と記載されている場合、ボーダーボックスを参照している、または少なくとも、それが解釈されたようです。 。
display: inline-block
が機能する理由基本的に、マージンはinline-block
要素で異なる動作をします。マージンはブロックレベルではなくコンテンツレベルであり、「過剰制約」の概念がないためです。
追加 display:inline-block;
〜#inner
div
これを見てください フィドル
したがって、ここでの回答は実際には問題を解決しません! (機能しない理由については非常に詳細ですが)
解決策が必要でした。これは将来の読者のためのものです。 display:flex;
と疑似:: after要素の組み合わせを使用して、divの存在を偽って必要なマージンを提供します。
.wrapper {
display: flex;
width: 400px;
height: 100%;
padding: 40px;
background: lightGrey;
}
.lists_container {
display: flex;
flex-direction: row;
justify-content: flex-start;
overflow: auto;
position: relative;
background: grey;
padding: 40px;
margin: 40px;
width: 100%;
}
.card {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
min-width: 250px;
max-width: 500px;
height: 100px;
margin: 50px 0;
padding: 20px;
background: orange;
margin-right: 30px;
}
.card.last::after {
content: '';
position: absolute;
right: -100px;
width: 40px;
height: 100%;
background: red;
}
<div class="wrapper">
<div class="lists_container">
<div class="card">
</div>
<div class="card">
</div>
<div class="card last">
</div>
</div>
</div>