初歩的な質問でごめんなさい。
html
1 2<div class="parent"> 3 <div class="child">demo</div> 4</div> 5 6<style type="text/css"> 7 .parent { 8 margin:30px 0; 9 overflow:hidden; 10 } 11 .child { 12 margin:10px 0; 13 } 14</style>
とした場合、なぜ親要素が子要素のmarginを相殺しないのかが分かりません。
どのような構造になっているのか教えていただければ幸いです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
CSSの仕様書のmarginの相殺の部分に以下のように記述してあります。
Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
marginが相殺されるパターンは、水平方向では起こらず、垂直(oriental)方向で行われます。
また、その他にも条件があり、親のmargin-(top|bottom)と子のmargin-(top|bottom)の間に何もないことが条件です。
なので、子要素にborderやpaddingなどがあると相殺は起きません。
また、理由はわかりませんが、新しいブロック書式コンテキストの場合も同様に相殺が起きないらしいです。
これはfloatがnone以外の浮動要素やoverflowがvisible以外の場合です。
ブロック書式コンテキストとブロックレベル要素がごちゃごちゃしてわかりにくいですが、以下に書いて有ることを自分なりに解釈してみました。
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
上記を解釈すると、まず、フロートや絶対配置などはブロックボックスではないし、さらにoverflow: visible以外のブロックは新しいブロック書式コンテキストを確立する。
また、ブロック書式コンテキストの中に入っているブロックレベル要素同士はmarginの縦方向の相殺をすると書いてあります。
overflow: visibleやfloatなどが指定されている要素はブロックレベル要素ではなく(厳密には違うけど語るには知識が足りませんすいません。。。)、ブロック書式コンテキストでhtml的に新しい文脈を作成するものなので相殺が起きないみたいな感じですかね?
なんか上手く説明できなくてスイマセン。。。
もし興味があるなら仕様書を読んでみるといいと思います!
投稿2017/09/04 13:03
総合スコア1869
0
ベストアンサー
はい、overflow
がvisible
以外の値の場合、その要素自体が1つの「ブロック整形コンテキスト」となる(その中と外は、レイアウト上いわば別世界になる)ため、子要素との相殺は起きません。
新しいブロック整形コンテキスト(たとえば、'visible'以外の'overflow'の浮動体や要素など)を設置する要素のマージンは、そのフロー内の子とともに相殺しない。
※制式採用されなかったCSS 2.2のものですが、この部分は2.1や3とそう変わりません。
投稿2017/09/04 13:00
編集2017/09/04 13:06総合スコア146018
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
※追記しました。見ていただけると幸いです。
同じく初心者ですが、簡単にテスト用のHTMLを書いてみました。
lang
1<!doctype html> 2<html> 3<head> 4<meta charset="utf-8"> 5<title>overflow</title> 6<style type="text/css"> 7#parent { 8 background-color: lightskyblue; 9 margin:50px 50px; 10 overflow: visible; 11 height : 250px; 12 width : 250px; 13 14 border: 5px solid red; 15} 16#child { 17 background-color: turquoise; 18 margin:100px 100px; 19 height : 500px; 20 width : 500px; 21 22 border: 5px solid red; 23} 24</style> 25<script> 26 27window.onload = function(){ 28 var button_elem = document.getElementById('button'); 29 30 button_elem.addEventListener("click",function(){ 31 var parentStyle = document.getElementById('parent').style; 32 if(parentStyle.overflow == 'hidden'){ 33 parentStyle.overflow = 'visible'; 34 button_elem.innerHTML = '現在 : visible'; 35 }else{ 36 parentStyle.overflow = 'hidden'; 37 button_elem.innerHTML = '現在 : hidden'; 38 } 39 },false); 40} 41</script> 42</head> 43<body> 44<div id="parent"> 45 <div id="child"> 46 demo 47 </div> 48 </div> 49</div> 50<br /> 51<button id="button">現在 : visible</button> 52</body> 53</html>
ボタンをクリックしてもらえばわかると思いますが、そもそもoverflowとmarginは関係ないように見えます。
参考になれば。
###追記
ごめんなさい私自信相殺についてわかってなかったみたいです。
maisumakun様やMasakazuFukami様の回答を読ませていただいてから調べました。
ただ私が間違ってしまったのは、(私の場合はですが)最初からoverflowが設定されていた時の挙動の方が自然に見えたからかもしれません。
その挙動というのは、overflowを設定すると、子要素のmarginがbodyに対してではなく、parentに対して行われるようになる、というものです。最初から全てこういう仕様(marginは常に直近の親要素に対して適用されるという仕様)の方がいいように私は感じましたが、
何か理由があるのだと思います。(多分その理由というのが他の回答者様のおっしゃる仕様関連のところにあるのでしょう。)
overflowがないと子要素のmarginはbodyに対するものになっていますね。
ある場合はparentに対するものになっていますから、構造的なもの、となるとこの挙動が解決案にはならないでしょうか?
また質問者様の質問を読んでいると、むしろ「相殺されるのはなぜですか?」みたいになるのかと思いました。
というのはもしoverflow:hidden;によってbodyに対してmarginがついたままで、parentのmarginがchildのmarginより大きく、さらに相殺されないならば、childの方はparentより上に行くことで、childの一部または全部がhiddenをvisibleにしないと見ることができない領域に行くであろうからです。
実際はparentからのmarginとなるので、子要素はあたかも相殺されたかのように下に行き、さらには自身のmarginによってさらに下に行きます。
その様子を見れるように改めてhtmlを書いてみました。言いたいことが伝われば幸いです。
lang
1<!doctype html> 2<html> 3<head> 4<meta charset="utf-8"> 5<title>sousai</title> 6<style> 7.parent { 8 background-color: red; 9 margin-top: 100px; 10} 11 12.child { 13 background-color: yellow; 14 margin-top: 250px; 15 margin-left: 10px; 16} 17</style> 18<script> 19var disp1; 20var parent; 21var parentStyle; 22var disp2; 23var button; 24 25window.onload = function(){ 26 disp1 = document.getElementById("disp1"); 27 parent = document.getElementsByClassName("parent")[0]; 28 disp2 = document.getElementById("disp2"); 29 button = document.getElementById("button"); 30 31 32 button.addEventListener("click",function(){ 33 parentStyle = parent.style; 34 if(parentStyle.overflow=="hidden"){ 35 parentStyle.overflow = ""; 36 disp1.innerHTML = "childのmargin-top: 250px;が適用"; 37 disp2.innerHTML = ""; 38 button.innerHTML = "現在 : none"; 39 }else{ 40 parentStyle.overflow = "hidden"; 41 disp1.innerHTML = "parentのmargin-top: 100px;が適用"; 42 disp2.innerHTML = "childのmargin-top: 250px;が適用"; 43 button.innerHTML = "現在 : hidden"; 44 } 45 },false); 46} 47</script> 48</head> 49<body> 50<span id="disp1">childのmargin-top: 250px;が適用</span> 51<div class="parent"> 52<span id="disp2"></span> 53<div class="child"> 54child 55</div> 56parent 57</div> 58<button id="button">現在 : none</button> 59</body> 60</html>
(長文、乱文、また初心者な回答、失礼しました。m(_ _)m)
投稿2017/09/04 13:37
編集2017/09/04 22:04総合スコア2045
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/09/05 00:47