第6章 5節 親要素の始端と終端の余白を可変にする方法について練習問題を通して理解しよう

この節のはじめに

まず、親要素の始端と終端の余白というのはどこのことを指しているかについて説明します。

第3章 13節 mod-container-0001を作ろう」で作成したmod-container-0001のpaddingとmarginは以下のようになっています。

1
2
3
4
5
6
7
8
9
10
11
12
13
.mod-container-0001 {
padding: 1px 16px;
background-color: #ffffff;
// .mod-container-0001のpadding-topを補完する初期値
> :first-child {
margin-top: 15px;
}
// .mod-container-0001のpadding-bottomを補完する初期値
> :last-child {
margin-bottom: 39px;
}
〜略〜
}

このとき、mod-container-0001の始端の余白というのは「mod-container-0001のpadding-topとfirst-childのmargin-topを足した値」のことを指しており、mod-container-0001の終端の余白というのは「mod-container-0001のpadding-bottomとlast-childのmargin-bottomを足した値」のことを指しています。
つまり始端の余白の初期値は16pxで、終端の余白の初期値は40pxです。

mod-container-0001のpadding-topとpadding-bottomを1pxで設定しておいたことで、mod-container-0001の中に最初に設置される要素(first-child)が変化することによって始端の余白を初期値(16px)より小さくしたい場合や、最後に設置される要素(last-child)が変化することによって終端の余白を初期値(40px)より小さくしたい場合にも柔軟に対応できます。

この節では、「第3章 14節 mod-container-0001のコードからポイントを読み取ろう」で解説した、「first-childの前やlast-childの後の余白が変化する箇所は擬似クラスセレクタで親要素のpaddingを制御する」という方法について、mod-container-0001のfirst-childやlast-childが変化する具体例をもとに理解を深めていきましょう。

練習問題の基礎となるHTML

前の節で作成したmargin-tutorial.htmlの、以下の箇所を基礎として、少し変更しながら説明していきます。

1
2
3
4
5
6
7
8
9
10
11
<section class="mod-container-0001">
<div class="mod-margin-tutorial-0002">
mod-margin-tutorial-0002
</div>
<div class="mod-margin-tutorial-0003">
mod-margin-tutorial-0003
</div>
<div class="mod-margin-tutorial-0004">
mod-margin-tutorial-0004
</div>
</section>

練習問題の基礎となるSCSS

_mod-container-0001.scss

src/scss/modules/_mod-container-0001.scssはこの節では変更しませんが、ここにも載せておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
.mod-container-0001 {
padding: 1px 16px;
background-color: #ffffff;
// .mod-container-0001のpadding-topを補完する初期値
> :first-child {
margin-top: 15px;
}
// .mod-container-0001のpadding-bottomを補完する初期値
> :last-child {
margin-bottom: 39px;
}
〜略〜
}

_mod-margin-tutorial-0002.scss

前の節で以下の通り記述したsrc/scss/modules/_mod-margin-tutorial-0002.scssを基礎として、少し変更しながら説明していきます。

1
2
3
.mod-margin-tutorial-0002 {
background: #ffdddd;
}

_mod-margin-tutorial-0003.scss

前の節で以下の通り記述したsrc/scss/modules/_mod-margin-tutorial-0003.scssを基礎として、少し変更しながら説明していきます。

1
2
3
.mod-margin-tutorial-0003 {
background: #ddffdd;
}

_mod-margin-tutorial-0004.scss

前の節で以下の通り記述したsrc/scss/modules/_mod-margin-tutorial-0004.scssを基礎として、少し変更しながら説明していきます。

1
2
3
.mod-margin-tutorial-0004 {
background: #ddddff;
}

練習問題を始める前に

今回の基礎となるHTMLでは、以下の3つのモジュールをmod-container-0001が包括しています。

  • mod-margin-tutorial-0002
  • mod-margin-tutorial-0003
  • mod-margin-tutorial-0004

練習問題の説明をするにあたって、上記のモジュールをそれぞれ以下のように表現します。

  • mod-2
  • mod-3
  • mod-4

練習問題で想定する条件

この練習問題では、以下の条件を満たせるようなmarginをmod-2、mod-3、mod-4に設定していきましょう。

  • mod-container-0001の中には、mod-2、mod-3、mod-4が必ず表示され、同じ要素が同時に表示されないものとします。
  • mod-2、mod-3、mod-4の表示順はランダムで変化するものとします。
  • mod-container-0001の始端の余白は、一番上に表示されたモジュールの番号×10pxの式で算出した値を設定するものとします。例えばmod-2が一番上に表示された場合は、始端の余白は2×10=20pxとします。つまり、このときmod-container-0001のpadding-topとmod-2のmargin-topを合わせて20pxになるものとします。
  • mod-container-0001の終端の余白は、一番下に表示されたモジュールの番号×10pxの式で算出した値を設定するものとします。例えばmod-4が一番下に表示された場合は、終端の余白は4×10=40pxとします。つまり、このときmod-container-0001のpadding-bottomとmod-4のmargin-bottomを合わせて40pxになるものとします。

上記した条件を満たすSCSSを書いてみてください

余裕があれば、_mod-margin-tutorial-0002.scss、_mod-margin-tutorial-0003.scss、_mod-margin-tutorial-0004.scssを編集して、上記した条件を満たすSCSSをご自身で書いてみてください。

正しい答えの例はこの後に掲載します。

正しい答えの例

表示されるパターンを整理する

まずはパターンの整理をします。
余白のパターンさえ整理されれば、あとは簡単です。

一番上に表示される要素と、一番下に表示される要素だけがわかれば良いので、余白の設定をするうえで必要なパターンは以下の通りです。

一番上に表示される要素のパターン

  • mod-2が一番上に表示されるパターン
  • mod-3が一番上に表示されるパターン
  • mod-4が一番上に表示されるパターン

一番下に表示される要素のパターン

  • mod-2が一番下に表示されるパターン
  • mod-3が一番下に表示されるパターン
  • mod-4が一番下に表示されるパターン

全ての条件を満たせるSCSS

答えはとても簡単です。

一番上の要素はfirst-child、一番下の要素はlast-childなので、その通りにスタイルを設定していくだけです。

_mod-margin-tutorial-0002.scssは以下のようになりました。
> を使用して、.mod-container-0001の直接の子要素のときだけに限定していることに注意してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
.mod-margin-tutorial-0002 {
background: #ffdddd;

// .mod-container-0001の子のとき
.mod-container-0001 > & {
&:first-child {
margin-top: 19px;
}
&:last-child {
margin-bottom: 19px;
}
}
}

_mod-margin-tutorial-0003.scssは以下のようになりました。

1
2
3
4
5
6
7
8
9
10
11
12
13
.mod-margin-tutorial-0003 {
background: #ddffdd;

// .mod-container-0001の子のとき
.mod-container-0001 > & {
&:first-child {
margin-top: 29px;
}
&:last-child {
margin-bottom: 29px;
}
}
}

_mod-margin-tutorial-0004.scssは以下のようになりました。
mod-container-0001のlast-childには、もともとmargin-bottom: 39px;が設定されているため、このファイルには記述していません。

1
2
3
4
5
6
7
8
9
10
.mod-margin-tutorial-0004 {
background: #ddddff;

// .mod-container-0001の子のとき
.mod-container-0001 > & {
&:first-child {
margin-top: 39px;
}
}
}

このmarginの役割について

このmarginは親要素のpaddingを補完する役割を担っています。

marginの方向について

この練習問題では、margin-topとmargin-bottomを使用しました。
実際にほとんどの場合、first-childにmargin-topを設定し、last-childにmargin-bottomを設定することになると思いますが、要素間のmarginを設定する場合と同じく、要素の並ぶ方向に合わせてfirst-childやlast-childに設定するmarginの方向も変更する必要があります。

親要素の始端と終端の余白を可変にするいくつかの方法について

デザインにもよりますが、このとてもやさしいCSS設計に沿ってコーディングをした場合、特にl-contents-type-xxxxやmod-container-xxxxを色々なページで再利用していくと、その中に一番目に設置される要素または最後に設置される要素がページによって変更される場合はよくあり、それらの要素が変更されたことにより、親要素の始端や終端の余白の変更が必要となる場合もあります。

そのようなとき、例えばl-contents-type-0001の始端と終端の余白を変更する基本的な方法として、l-contents-type-0001のModifierクラスを新しく定義して付与したり、l-contents-type-0002を新しく定義してクラスを差し替えたりする方法があります。

それらの基本的な方法に比べて、この節で解説してきた方法は子要素のmarginを使って親要素のpaddingを補完するという点から見ていくと変則的な方法に見えます。しかし、少し視点を変えて、始端と終端の余白を変更する理由がどのようなものであったかという点から見ていくと「一番上に設置される要素が変更された」「一番下に設置される要素が変更された」ということをきっかけに余白を変更する必要が生じているため、first-childやlast-childのセレクタを使用して余白を変更することは自然なようにも見てとれます。

この方法を使用するとクラスの付け替えが不要であることから、プログラムによって動的に表示要素が変化するページはもちろんのこと、静的なページの作成においてもコードの管理をしやすくなることがありますので、ぜひ選択肢のひとつとして検討してみてください。

表示確認

public/html/margin-tutorial.html をブラウザで開いて確認してみてください。

この節のおわりに

この節では、隣接兄弟要素セレクタでは対応できない、親要素の始端と終端の余白を可変にする方法について、練習問題を通して学習しました。

mod-container-0001はこの練習問題で使用することも見越してpadding-topとpadding-bottomを1pxに設定していましたが、ほとんどの要素は初めから可変にしておく必要はありません。

この方法を使用するのは、first-childまたはlast-childが変化したときに親要素の余白を変化させたい場合に限ります。

モジュールを作成する時点において、first-childやlast-childが変化するかどうかわからない場合や、それらが変化するとしても余白を変化させない場合は、親要素のpaddingだけを使用して余白を設定しておき、可変にする必要に迫られてから対応するのが良いと思います。

過剰な実装にならないように、適宜使い分けてみてください。

続きはこちら

とてもやさしいCSS設計チュートリアルの目次へ戻る