はじめに
僕はバックエンドが主戦場で、PHPのテンプレートを修正することもあるけど、普段、フロントは必要に応じて触るくらい。
たまに、JavaScriptに加えて、HTMLやCSSをガッツリ触る場合もある。
そうなると、やはり最低限の知識は必要だなって思うのです。
最近になって知ったのが、CSSには代表的な4つの設計手法があるということ。
(逆に言うと最近まで知らなかった、ヤバイ!)
今回は、CSS設計って何?設計なんて必要なの?というバックエンド寄りの自分が、CSS設計の世界を覗いてみた記録として、OOCSS・SMACSS・BEM・PRECSSという4つの設計手法を紹介してみます。
なぜCSSに“設計”が必要なのか?
CSSは「書けばすぐ反映される」便利な技術ですが、以下のような問題に悩まされたことはありませんか?
- クラス名が衝突して、意図しないスタイルが適用される
- どのCSSがどのHTMLに対応しているのか分からない
- 削除や変更が怖くて触れない
- 同じスタイルがあちこちにコピペされている
これらは、CSSの汚染によって起きる問題です。
CSSは基本的にグローバルスコープで動作するため、JavaScriptのようにスコープを分けて管理する仕組みがありません。
そのため、コーディングする人がクラス名の衝突などに注意する必要があります。
※現在では、例えばTailwindを利用すると命名の負担は減りますが「設計」自体が不要になるわけではないと思います。
様々な設計手法に触れておくのも意味があると思いました。
さて、CSSでも設計が重要だと認識したところで、代表的な設計手法を紹介していきます!
1. OOCSS(Object-Oriented CSS)
読みは「オーオーシーエスエス」。
OOCSSは、CSSを再利用可能な「オブジェクト」として捉える設計手法です。
「構造」と「見た目」を分離します。
<例>
構造.boxと見た目 .alert-warning .alert-success を分ける。
HTMLの例
<div class="box alert-warning">
パスワードの有効期限が近づいています。
</div>
<div class="box alert-success">
プロフィールが正常に更新されました。
</div>
CSSの例
/* 構造:共通のボックス構造 */
.box {
padding: 1em;
border-radius: 4px;
font-size: 1rem;
margin-bottom: 1em;
}
/* 見た目:バリエーションごとの装飾 */
.alert-warning {
background-color: #fff3cd;
color: #856404;
border: 1px solid #ffeeba;
}
.alert-success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
<メリット>
・再利用性が高まる
・スタイルの責務が明確になる
ただ、僕みたいに浅い理解だと使いこなすのは少し難しそう…
<バックエンド的な浅い解説>
僕は、OOCSSでは、CSSのクラスは「再利用可能なスタイルのまとまり」
言い換えると、CSSでクラス定義して、HTMLはオブジェクトやインスタンスみたいに認識している。
HTMLのタグにCSSのクラスを指定すれば、UI部品を生成できるイメージ。
(あくまで僕のイメージ。)
ただし、構造と見た目の責務分離が主眼なので、そのあたりは忘れちゃいけないですね。
2. SMACSS(Scalable and Modular Architecture for CSS)
読みは「スマックス」。
CSSを下記の5つのカテゴリに分類して管理します。
Base / Layout / Module / State / Theme
※なお、SMACSSは「ガイドライン」であり、厳密な命名規則はBEMほど強くないです。
プロジェクトごとにカスタマイズして利用するということも考えられます。
<例>
Base(ベース)ルールの例
body { font-family: sans-serif; }
a { color: blue; text-decoration: none; }
Layout(レイアウト)ルールの例
.layout-header { background: #333; }
.layout-main { display: flex; }
Module(モジュール)ルールの例
.card { border: 1px solid #ccc; }
.card-title { font-size: 1.2em; }
State(ステート)ルールの例
.is-active { border-color: blue; }
.is-hidden { display: none; }
Theme(テーマ)ルールの例
.theme-dark .card { background: #222; color: #eee; }
<メリット>
・大規模開発でもスケーラブルに保てる
・チームでルールを共有しやすい
<バックエンド的な浅い解説>
概要だけ理解するなら、レイヤー分けするような設計手法で、わかりやすいですよね。
3. BEM(Block Element Modifier)
たぶん「ベム」と読む。「ベン」かもしれない。
これはまず、例を見てもらいましょう。
例:.card__title--highlight
このようにアンダースコアやハイフンを2つにするところが特徴的です。
アンダースコア2つは、ブロックと要素の区切りを示す。
ハイフン2つは、要素やブロックの修飾を示す。
このようなことをする目的は、クラス名に意味を持たせてスコープを明確化することです。
つまり、どのブロックに属する要素なのか、どんな状態なのかがクラス名から一目でわかるようになります。
たとえば、以下のようなコードを見てみましょう。
<div class="card">
<h2 class="card__title card__title--highlight">注目記事</h2>
<p class="card__text">これはBEMの例です。</p>
</div>
この例では、
・card がブロック
・card__title がその中の要素(タイトル)
・card__title--highlight がその要素の修飾(強調している状態)
このように、クラス名だけで構造と役割が明確になるため、CSSの可読性・保守性が大きく向上します。
<メリット>
・命名だけで構造が分かる
・スタイルの衝突を防げる
<バックエンド的な浅い解説>
擬似的にだけど、プログラミング言語のスコープっぽいことができます!
4. PRECSS(Sassベースの設計補助ライブラリ)
※注意:PRECSSはSassの設計補助ライブラリであり、かつ現在は非メンテナンス状態です。
実務で採用することはまずないと思いますが、その思想と背景は知っておきましょう。
読みは「プレックス」または「プリセス」。
PRECSSという名前は「prefixed CSS」の略です。
(接頭辞付きCSSということですね)
Sassを使ってOOCSSやBEMの思想を補強。
接頭辞やネストで構造化しやすくする(Sassだからネスト可能)
※Sassとは?
Sass(Syntactically Awesome Stylesheets)は、CSSをより効率的に、再利用しやすく、保守しやすくするためのスタイルシート拡張言語です。
CSSの上位互換のような存在で、変数・入れ子・関数・継承など、プログラミング的な機能をCSSに追加できます。
<例>
接頭辞はあらかじめ定義されていて、bl_は「再利用可能なUI部品(ブロック)」を表します。
(例えば、el_はElement(構成要素)、is_はState(状態)を表す)
.bl_card {
border: 1px solid #ccc;
padding: 16px;
.bl_card_ttl {
font-size: 1.2em;
margin-bottom: 8px;
}
.bl_card_txt {
font-size: 1em;
&.is_highlight {
background-color: #ff0;
}
}
}
<メリット>
・設計思想をコードに落としやすい
・Sassの機能で保守性が向上
<バックエンド的な浅い解説>
これ、そもそもCSSではなくSassを使うので、設計手法の前に、そもそも言語が違う。
CSSが重要な要素になりそうと認識した場合は、例えば、CSSの進化状況を確認したり、Tailwindの利用を検討したり、そういったことが必要なのかなと思いました。
まとめ
CSSは見た目の技術と思われがちですが、設計の考え方があることで、保守性・再利用性・責務分離が実現できます。
バックエンドエンジニアにとっても、CSS設計は「設計者としての視点」を活かせる分野です。
最近は、TailwindやCSS Modulesなどを利用することも多いと思います。
その際、今回のような設計の観点を押さえておけば、鬼に金棒ではないでしょうか。