『レイアウト』と『UIパーツ』を意識してCSS設計をするとデザインの再利用がしやすくなります。
UIパーツに関するCSSには再利用性の観点からUIパーツの外側の余白(margin)を含めないのが原則です。
今回はリストアイテムを例に、UIパーツの余分なマージンを:last-child
で削除するテクニックについて紹介します。
目次
今回利用するサンプルのデザインについて
横並びの正方形のリストアイテム(青色の要素)と、長方形のアイテム(緑色の要素)を並べるケースについて考えます。
<div class="container">
<div class="pager container__pager">
<div class="pager__item"></div>
<div class="pager__item"></div>
<div class="pager__item"></div>
<div class="pager__item"></div>
</div><div class="button container__button"></div>
</div>
.pager {
display: inline-flex;
}
.container__pager {
margin-right: 30px;
}
.pager__item {
width: 60px;
height: 60px;
background-color: lightblue;
}
.pager__item:not(:last-child){
margin-right: 10px;
}
.button {
width: 200px;
height: 100px;
background-color: greenyellow;
display: inline-block;
vertical-align: top; /* 上揃えにする */
}
See the Pen
pagenation-button-container by Toshiharu Nishina (@nishina555)
on CodePen.
以降の説明では横並びの正方形のリストアイテム(青色の要素)をページネーション、長方形のアイテム(緑色の要素)をボタンと定義します。
改善前: UIパーツのCSSに外側の余白が含まれている場合
margin-right
でページネーションの各アイテムの間隔を調整するとします。
ページネーションの右横にさらにボタンを並べる場合、ページネーションの最後のアイテムのmargin-right
の影響でページネーションとボタンの間に余白ができます。
<div class="pager">
<div class="pager__item"></div>
<div class="pager__item"></div>
<div class="pager__item"></div>
<div class="pager__item"></div>
</div><div class="button"></div>
.pager {
display: inline-flex;
border: dotted; /* マージンをわかりやすくするために追加 */
}
.pager__item {
width: 60px;
height: 60px;
background-color: lightblue;
margin-right: 10px;
}
.button {
width: 200px;
height: 100px;
background-color: greenyellow;
display: inline-block;
vertical-align: top; /* 上揃えにする */
}
See the Pen
pagenation-button-before by Toshiharu Nishina (@nishina555)
on CodePen.
たとえば『ページネーションとボタンの間のマージンは30px』という仕様の場合、仮にmargin-right
が10pxであれば20px(30px-10px)のマージンを追加すれば仕様は満たせます。
しかし、UIパーツのマージンを考慮してレイアウトの余白を調整するのは健全なCSS設計とはいえません。
改善後: 『:last-child』をUIパーツの外側マージンを削除した場合
:last-child
は最後の兄弟要素を指定する疑似クラスです。
:last-child
でmarigin: 0
を指定することで、ページネーションの最後のアイテムのマージンのみ削除できます。具体例は以下の通りです。
<div class="pager">
<div class="pager__item"></div>
<div class="pager__item"></div>
<div class="pager__item"></div>
<div class="pager__item"></div>
</div><div class="button"></div>
.pager {
display: inline-flex;
border: dotted; /* マージンをわかりやすくするために追加 */
}
.pager__item {
width: 60px;
height: 60px;
background-color: lightblue;
margin-right: 10px;
}
/* このCSSを追加 */
.pager__item:last-child {
margin-right: 0px;
}
.button {
width: 200px;
height: 100px;
background-color: greenyellow;
display: inline-block;
vertical-align: top; /* 上揃えにする */
}
See the Pen
pagenation-button-after by Toshiharu Nishina (@nishina555)
on CodePen.
上記の結果を見て分かる通り、先ほど存在していたページネーションとボタンの間の余白がなくなったので、レイアウトの余白を考える際にUIパーツのマージンを考慮する必要がなくなりました。
なお、pager
クラスにpager__item
以外の子要素が存在するケースを考慮して、以下のように最後の要素を指定する記述方法もあります。
/* pagerクラスの直下にある最後の要素に適用される */
.pager > *:last-child {
margin-right: 0px;
}
参考: :not(:last-child)を利用するとよりシンプルに記述できる
『最後の要素のみマージンが不要』は『最後の要素以外はマージンが必要』と言い換えられます。
ですので、:last-child
と:not
を組み合わせることで以下のように書き換えられます。
.pager__item {
margin-right: 10px;
}
.pager__item:last-child {
margin-right: 0px;
}
.pager__item:not(:last-child) {
margin-right: 10px;
}
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!