入れ子要素のmargin/paddingを簡潔に調整したい
CSSでpaddingを付けた親要素の中に子要素を等間隔で並べたい場合、親要素の上下paddingと先頭・末尾の子要素のmarginがダブってしまうため、これまでは以下のような手法を使っていました。
- 子要素のmarginをリセットし、上下間隔は隣接セレクタなどで指定する
- 子要素のmargin分を親要素の上下padding値からあらかじめ引いておく
- 先頭・末尾の子要素を疑似クラスなどで特定し、上下marginを上書きする(サンプル)
example01.html
<blockquote class="example01" cite="http://www.aozora.gr.jp/cards/000148/files/789_14547.html">
<p>吾輩は猫である。名前はまだ無い。</p>
<p>どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。~</p>
</blockquote>
example01.css
.example01 {
border: solid 1px #ccc;
padding: 2em;
background: #eee;
color: #333;
}
.example01 > :first-child {
margin-top: 0;
}
.example01 > :last-child {
margin-bottom: 0;
}
.example01 p {
margin: 1em 0;
padding: .5em;
border: solid 1px #ccc;
}
疑似要素で作る内側marginの試案
CSSの疑似要素を使うと要素内側の前後に仮想的な要素を配置できるため、親要素の内側上下にmarginを取るパターンを作ってみました。paddingを使った場合とは異なり子要素のmarginと相殺が働くため、先頭・末尾に一定の余白を自然に取ることができます。
(参考: CSS: marginの正しい理解 (CSSのmarginが難しい)|Web Design KOJIKA17)
example02.html
<blockquote class="example02" cite="http://www.aozora.gr.jp/cards/000148/files/789_14547.html">
<p>吾輩は猫である。名前はまだ無い。</p>
<p>どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。~</p>
</blockquote>
example02.css
.example02 {
border: solid 1px #ccc;
padding: 0 2em;
background: #eee;
color: #333;
}
.example02::before,
.example02::after {
content: "";
display: block;
margin-top: 2em;
}
.example02 p {
margin: 1em 0;
padding: .5em;
border: solid 1px #ccc;
}
Sassを使ったMixin化
上記のパターンをSass(SCSS)でMixin化した場合のサンプルです。
example03.html
<blockquote class="example03" cite="http://www.aozora.gr.jp/cards/000148/files/789_14547.html">
<p>吾輩は猫である。名前はまだ無い。</p>
<p>どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。~</p>
</blockquote>
example03.scss
@mixin margin-inner-top($length: none) {
&::before {
@if $length == none {
display: none;
} @else {
content: "";
display: block;
margin-top: $length;
}
}
}
@mixin margin-inner-bottom($length: none) {
&::after {
@if $length == none {
display: none;
} @else {
content: "";
display: block;
margin-top: $length;
}
}
}
@mixin margin-inner-row($top: none, $bottom: null) {
@include margin-inner-top($top);
@include margin-inner-bottom(if($bottom != null, $bottom, $top));
}
.example03 {
@include margin-inner-row(2em);
border: solid 1px #ccc;
padding: 0 2em;
background: #eee;
color: #333;
p {
margin: 1em 0;
padding: .5em;
border: solid 1px #ccc;
}
}