CSS は構造化が難しくスタイルを宣言していくだけで目的が達成できてしまいます。上書きの繰り返しによって肥大化しないための設計ヒントをまとめます。
詳細度の高騰が発生した CSS は破綻しやすい
CSS の詳細度はルーティングテーブルのロンゲストマッチのようなものです。一致度の高いとされるセレクタで指定したスタイルが優先的に適用されます。同じ詳細度の場合は後から指定したスタイルで上書かれて適用されます。
↑高い
!important (避けるべき)
HTML の style 属性でのインライン記述 (避けるべき)
ID セレクタ (避けることを推奨(後述))
クラスセレクタ (推奨)
要素セレクタ ('p' 等。HTML 構造への依存は避けます(後述)。リセット用途で使用)
ユニバーサルセレクタ '*' (リセット用途で使用。パフォーマンスの問題などからあまり推奨されない)
↓低い
important は基本的には使用しないようにします。CSS 内で詳細度が高騰してくるとスタイルを適用するための応急処置として以下のようなコードを書かざるを得なくなってきます。
p {
font-size: 6px !important;
}
可能なかぎり詳細度の高騰は避けましょう。例えば以下のようにします。
.mylist li a {
}
↓
.mylist a {
}
絶対値を多用した CSS は破綻しやすい
相対値を使用すると独立パラメータ変数の個数を削減できます。以下の line-height の例では子要素に属性値が伝搬するためコード量も削減できています。
<div class="myouter">
<p class="myinner">文章</p>
<p>文章</p>
</div>
悪い例
<style>
.myouter {
font-size: 12px;
line-height: 24px;
}
.myinner {
font-size: 24px;
line-height: 48px;
}
</style>
良い例
<style>
.myouter {
font-size: 12px;
line-height: 2.0;
}
.myinner {
font-size: 24px;
}
</style>
HTML の構造に依存した CSS は破綻しやすい
要素セレクタや ID セレクタは HTML の特定の場所に依存しがちです。クラスで部品化しましょう。ただし汎用部品化には時間がかかります。結局使用しない部品の可能性もあるため何度か出現してから抽出してコンポーネント化するようにします。
要素セレクタは避ける
悪い例
h1 が h2 に変更されると困ります。
<div id="container">
<h1>見出し</h1>
<p>文章</p>
</div>
<style>
div h1 {
font-size: 24px;
}
</style>
良い例
要素セレクタではなくクラスでセレクトしましょう。h1.myheadline ではなく、要素セレクタを使用せずに省略して .myheadline とします)。
<div id="container">
<h1 class="myheadline">見出し</h1>
<p>文章</p>
</div>
<style>
.myheadline {
font-size: 24px;
}
</style>
ID セレクタは避ける
悪い例
id container はページ内に一箇所しか存在できません。詳細度の高騰にもつながります。
<div id="container">
<h1>見出し</h1>
<p>文章</p>
</div>
<style>
#container h1 {
font-size: 24px;
}
</style>
良い例
<div id="container">
<h1 class="myheadline">見出し</h1>
<p>文章</p>
</div>
<style>
.myheadline {
font-size: 24px;
}
</style>
スタイルの取り消しがある CSS は破綻しやすい
クラスを用いた部品化ではスタイルの削除ではなく追加を心がけます。コード量を削減できます。以下の例ではスタイル三行を二行に削減できています。
悪い例
<div>
<h1 class="myheadline myheadline-no-underline">見出し</h1>
<h1 class="myheadline">下線あり見出し</h1>
</div>
<style>
.myheadline {
font-size: 24px;
border-bottom: 2px solid #000;
}
.myheadline-no-underline {
border-bottom: none;
}
</style>
良い例
ルールを追加するように設計すると行数が削減できます。
<div>
<h1 class="myheadline">見出し</h1>
<h1 class="myheadline myheadline-underline">下線あり見出し</h1>
</div>
<style>
.myheadline {
font-size: 24px;
}
.myheadline-underline {
border-bottom: 2px solid #000;
}
</style>
シングルクラスとマルチクラス
Sass の @extend を使用するとシングルクラスで書けてしまいます。しかしながらクラス数が増加していきます。以下の例における最後のクラスはマルチクラスにしておけば不要だったはずです。
.mybtn {
}
.mybtn-primary {
@extend .mybtn;
}
.mybtn-large {
@extend .mybtn;
}
.mybtn-primary-large {
@extend .mybtn;
@extend .mybtn-primary;
@extend .mybtn-large;
}
コンポーネントは複数の役割を担うのではなく一つのことだけを行うべきです。例えば「色やサイズなどの見た目」と「position, floatなどの配置」は別々のコンポーネントで管理されるべきです。過度に意識する必要はありませんが必要に応じてマルチクラスに分離していきましょう。一方、シングルクラスにはセマンティックなクラス名が実現できるというメリットがあり、状況によって使い分けられます。
コンポーネント化の実例 (CSS スプライト)
CSS スプライトは背景画像の座標を background-position で指定して width と height で切り出して表示する手法です。画像の HTTP リクエスト回数を減らせるという利点があります。これをコンポーネント化すると以下のようになります。
<div class="myicn myicn-1"></div>
<div class="myicn myicn-2"></div>
<style>
.myicn {
display: inline-block;
background-image: url(myicons.png);
}
.myicn-1 {
width: 300px;
height: 50px;
background-position: 0 0;
}
.myicn-2 {
width: 300px;
height: 50px;
background-position: 0 50px;
}
</style>
デザイナー兼フロントエンドエンジニア。UI/UX設計が得意です。
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。




