クラスセレクターを使うことで詳細度をほどよく高める

概要

Web システム屋さんは、覚えなければいけないことがたくさんある。

バックエンドも大事だが、フロントエンドも大事なのだ ()
コア機能の実装に注力して開発していると、どうしてもスタイル (CSS) 周りは後回しになりがちだが、今後も機能追加や改修をしていくためは、やはり最低限の設計と基礎知識は必要である。

そんなことを実感したときがあったので、今回も恥を晒しつつ振り返ってみる。

まえおき

コード例はサンプル向けにアレンジしたもののため、違和感はご愛嬌。

やりたかったこと

アコーディオンのような折りたたみボックスの summary 部分を、高さ 50px で固定したかった。
例えば、以下のような HTML である。

uranai.html

<details>
  <summary>今日の運勢</summary>
  猫みたいにまったりしてると運命のネズミが近づいてくるかも!でも、急に跳ねる準備も忘れずに!
</details>

高さ 50px で固定するため、以下のような CSS を作成した。

style.css

summary {
  height: 50px;
}

このコードの問題点

上記のコードは、以下の点でイマイチである。


  • 要素型セレクターを使っているため、広範囲に影響を与える可能性がある
  • 今は問題なくても、今後 summary 要素が増えた場合はそれらも影響を受けるため、保守しにくくなる

なぜこうなった?

  • CSS のことをよくわかっていなかった
    • カスケーディングの基本的な仕組み (セレクター、重要度、詳細度) を理解していなった
  • とりあえず今は意図するスタイルが適用できればヨシと思った

どうするとよさそうか?

  • 影響範囲の大きい要素型セレクターは使用しない
  • クラスセレクターを使うことで、影響範囲をほどよく狭くする
    • 「ほどよく」というのが重要なため、ID セレクターはなるべく使用しない
    • ID セレクターを使うと詳細度が高すぎてスタイルの上書きがしにくくなる

クラスセレクターを使うと以下のようになる。

style.css

.summary {
  height: 50px;
}

これなら、今後 summary 要素が増えたとしても影響を与えることはない。

よりよい設計にするは?

.summary でクラスセレクターを使うようにした分、影響範囲は狭くなったが、保守しやすい設計にはなっていない。
たとえば、別の summary 要素を追加し、そこには異なるスタイルを適用したい場合、まずクラスの命名で困るだろう。

CSS にも様々な設計手法があるが、個人的には BEM (ベム) から初めてみるのがよさそうに思う。
利用者が多く、CSS 関連の書籍でもよく紹介されているので始めやすい。


BEM に則るとこんな感じになるだろう。

uranai.html

<details>
  <summary class="summary summary_height_low">今日の運勢</summary>
  猫みたいにまったりしてると運命のネズミが近づいてくるかも!でも、急に跳ねる準備も忘れずに!
</details>
style.css

.summary {
  ...
}
.summary_height_low {
  height: 50px;
}

BEM の場合、Modifier は単独では存在できないルールのため、Block か Element のクラスがある状態で、2つ目以降のクラスとして Modifier を定義する必要がある。
そのため、.summary という Block のクラスを設け、.summary の見た目を定義するための Modifier のクラスとして .summary_height_low クラスを定義した。

が、今回のように「高さを50pxにしたいだけ」の場合、.summary の中身をどうすればよいのかはちょっとわかっていない (そもそもこのような状況はレアケースかもしれない)。

実際のプロジェクトで、「HTML 側ではクラス (Block 相当のクラス) を指定するが、CSS には当該クラスは定義されていない」 というのを見たことがあるので、上記の場合もこのパターンに当てはまるかもしれない。


ちなみに、以前まで Modifier は -- (ダブルダッシュ) を使うルールだったと思うが、今は _ が基本になった? ように見える。
(ダブルダッシュでの記法が Alternative naming schemes として記載されている

BEM MEthodology > Alternative naming schemes > Two Dashes style


BEM を使うと、以下のように別の summary 要素に異なるスタイルを適用したい場合にも対応しやすいだろう。

uranai.html

<details>
  <summary class="summary summary_height_low">今日の運勢</summary>
  猫みたいにまったりしてると運命のネズミが近づいてくるかも!でも、急に跳ねる準備も忘れずに!
</details>

<details>
  <!-- 明日の運勢にはライトピンクの背景色を付けたい -->
  <summary class="summary summary_height_low summary_bg-color_lightpink">明日の運勢</summary>
  猫のように気まぐれに動いてみて!予期しない場所で「お宝」を見つけるかも。
</details>
style.css

.summary_height_low {
  height: 50px;
}
.summary_bg-color_lightpink {
  background-color: lightpink;
}

ただ、クラス名は長くなるので、そこに関しては可読性が落ちる。
この問題を解決するために No Namespace style がある認識だが、このスタイルを使うと、Modifier がどの Block / Element に属しているのかがわからなくなるので、それはそれで可読性が落ちる。
こうやって CSS 沼にハマっていくのだろう。

名前が長くなる問題はあるとしても、命名ルールがあり詳細度を均一に保てるので、よりよい設計にはなると思う。

おわり

バックエンドだけやっていてもダメなんだ (語彙
そうに思うようになって、CSS を学ぶとやってくるのが CSS 沼。

Web システム屋さんは、覚えなければいけないことがたくさんあるのだ。

参考