marginプロパティには、margin collapsing(マージンの相殺)というルールがあります。
マージンの相殺について、CSS【 margin 】4~マージンの相殺 (margin collapsing)(1)で、マージンの相殺が起きる場合について紹介しましたが、今回は、マージンの相殺が起きない場合について紹介したいと思います。
marginプロパティについては、以下のページもご参照下さい。
CSS【 margin 】1~マージンとショートハンド
CSS【 margin 】2~autoとwidthと上下と左右
CSS【 margin 】3~ネガティブマージン
CSS【 margin 】4~マージンの相殺 (margin collapsing)(1)
CSS【 margin 】5~マージンの相殺 (margin collapsing)(2)(本ページ)
なお、未経験からITエンジニアへの就職に興味がある方や未経験からプログラミングを効率よく学びたいと考えている方は、就職率98.3%で受講料無料のプログラミングスクールプログラマカレッジもおすすめです。
マージンの相殺が起きるには条件があります。
【マージンの相殺が起きる条件】
• ブロックレベルの要素であること
• margin と margin の間に何もないこと
• 上下のmargin同士が直接触れ合っていること
この条件に照らし合わせると、マージンの相殺が起きるか起きないかの判別ができますが、マージンが相殺されない代表的な以下のケースについて考えてみたいと思います。
【マージンが相殺されない主なケース】
• display:inline-blockを指定した兄弟要素同士の場合
• display:flex の中のFlexアイテムな兄弟要素同士の場合
• float を指定した要素同士の場合
• clear を指定した要素同士の場合
• 親要素がoverflow:visible以外のoverflowを指定した場合
• 親要素がposition:absoluteまたはposition:fixedを指定した場合
ブロックレベルの要素を横に並べる際に、display: inline-blockを指定すると便利ですが、display: inline-block を指定した兄弟要素同士では、マージンの相殺が起きません。
display:inline-block
display:inline-block
display:inline-block
display:inline-block
ソースは次の通りです。
<!-- CSSファイル -->
div#sample {border:solid 1px #CCC; width:18.5em;}
div#sample p {
display:inline-block;
text-align:center;
width:7em;
background:#AAA;
margin:1em;}
<!-- HTMLファイル -->
<div id="sample">
<p>display:inline-block</p>
<p>display:inline-block</p>
<p>display:inline-block</p>
<p>display:inline-block</p>
</div>
上下に接したp要素のマージンの相殺が起こると1emとなりますが、マージンが相殺されずに2emとなっています。
Flexboxを作るdisplay:flexを要素に指定すると、中の子要素は全てFlexアイテムと呼ばれ、兄弟要素同士のFlexアイテム間では、マージンの相殺は起きなくなります。
display:flex
display:flex
display:flex
display:flex
display:flex
display:flex
display:flex
display:flex
ソースは次の通りです。
<!-- CSSファイル -->
div#sample {border:solid 1px #CCC;}
div#f1, div#f2 {
display:flex;
flex-wrap: wrap;
background:#AAA;
margin:1em;}
div#f1 p, div#f2 p {
flex:1 0 200px;
text-align:center;
line-height:3em;
background:#31A9EE;
margin:1em;}
<!-- HTMLファイル -->
<div id="sample">
<div id="f1">
<p>display:flex</p>
<p>display:flex</p>
<p>display:flex</p>
<p>display:flex</p>
</div>
<div id="f2">
<p>display:flex</p>
<p>display:flex</p>
<p>display:flex</p>
<p>display:flex</p>
</div>
</div>
Flexアイテム同士の上下のマージンが相殺されると1emですが、 相殺されずに2emになっています。
2つのFlexbox を縦に並べていますが、親要素同士は上下のマージンが相殺されています。
floatが指定されている兄弟要素同士では、マージンの相殺は起きません。
また、親要素にfloatが指定されている場合は、親子間でマージンの相殺は起きません。
float:left
float:left
float:left
float:left
ソースは次の通りです。
<!-- CSSファイル -->
div#sample {border:solid 1px #CCC; width:14em; height:21em;}
div#sample p, div#sample ul {
float:left;
text-align:center;
line-height:3em;
width:5em;
background:#AAA;
margin:1em;}
div#sample ul { width:12em;}
div#sample ul li {margin:1em; background:#31A9EE;list-style:none;}
<!-- HTMLファイル -->
<div id="sample">
<p>float:left</p>
<p>float:left</p>
<p>float:left</p>
<p>float:left</p>
<ul>
<li>List</li>
<li>List</li>
</ul>
</div>
p要素及びul要素に float:left を指定しています。
すると、縦に並んだ p要素同士ノマージン、p要素とul要素との間のマージンは、いずれも相殺されずに2emです。
また、ul要素は、子要素のli要素とのマージンの相殺が起きず、最初のli要素の上マージンも、最後のli要素の下マージンも1emです。
上の例で、ul要素にfloat:noneと指定した部分をclear:leftと指定します。
clearプロパティを指定すると、マージンの相殺は起きなくなります。
clear
clear
ソースは次の通りです。
<!-- CSSファイル -->
div#sample {border:solid 1px #CCC; width:14em; height:16em;}
div#sample p, div#sample ul {
float:left;
text-align:center;
line-height:3em;
width:5em;
background:#AAA;
margin:1em;}
div#sample ul {
width:12em;
clear:left;
background:#AAA;}
div#sample ul li {margin:1em; background:#31A9EE; list-style:none;}
<!-- HTMLファイル -->
<div id="sample">
<p>float:left</p>
<p>float:left</p>
<p>float:left</p>
<p>float:left</p>
<ul>
<li>List</li>
<li>List</li>
</ul>
</div>
ul要素の上マージンは1emです。
p要素と ul要素との間は 2em になって、兄弟要素同士でマージンの相殺は起きていません。
clearプロパティを指定したul要素は、子要素liとのマージン相殺も起きていません。
親要素が、overflowプロパティでhidden、auto、scrollのいずれかを指定した場合(overflow:visible 以外を指定した場合)は、親要素と子要素との間で、マージンの相殺は起きません。
ちなみに、visible は overflowプロパティのデフォルト値です。
ソースは次の通りです。
<!-- CSSファイル -->
div#sample {border:solid 1px #CCC; font-weight:bold; padding:0; margin:0;}
div#sample ul {
overflow:hidden;
padding:0;
margin:1em;
background:rgba(102, 153, 255, 0.5);}
div#sample ul li {
margin:1em;
padding:1em;
list-style:none;
background:rgba(102, 153, 255, 0.5);
border-radius:5px;
color:#FFF;
line-height:1em;}
<!-- HTMLファイル -->
<div id="sample">
<ul>
<li>overflow:visible 以外(hidden、auto、scroll)</li>
<li>overflow:visible 以外(hidden、auto、scroll)</li>
</ul>
</div>
親要素のul要素に、overflow: hiddenを指定しています。
親要素がposition:absolute または position:fixed の場合は、親要素と子要素との間でマージンの相殺は起きません。
ソースは次の通りです。
<!-- CSSファイル -->
div#sample {border:solid 1px #CCC; font-weight:bold; padding:0; margin:0;
position:relative;
height:11em;}
div#sample ul {
position:absolute;
top:0;
left:0;
right:0;
padding:0;
margin:1em;
background:rgba(102, 153, 255, 0.5);}
div#sample ul li {
margin:1em;
padding:1em;
list-style:none;
background:rgba(102, 153, 255, 0.5);
border-radius:5px;
color:#FFF;
line-height:1em;}
<!-- HTMLファイル -->
<div id="sample">
<ul>
<li>position:absolute または position:fixed</li>
<li>position:absolute または position:fixed</li>
</ul>
</div>
ul要素に position: absolute を指定し、その親要素のdiv要素に対して、絶対位置にしました。
すると、ul要素と子要素のli要素との間で、マージンの相殺は起きていないのがわかります。
INTERNOUS,inc. All rights reserved.