みなさんこんにちは。teratail開発チーム デザイナーの平井優です。
Webサービスの制作において,
そんな便利なCSSなのですが,
今回は,
CSSを設計することの重要性
CSSはとてもシンプルかつ学習コストも低く,
しかし,
- 予測していなかった箇所のスタイルが崩れる
- 思った通りにスタイルが反映されず,
新しい記述で上書きをしてCSSが煩雑になる - 期待する場所以外のスタイルが変わってしまい,
過去のCSSを修正せざるを得ない - ファイルの肥大化により,
どこを編集したらいいのか分かりづらい - 既存のスタイルを利用すれば更新は必要ないのに,
重複したスタイルを定義してしまう - ...
etc
いかがでしょうか,
CSS設計を行う上で意識すること
後で困ることのない,
- 予測しやすい
- 機能追加・
見た目の変更・ 修正を行う際に 「どのスタイルが変更されるのか」 または 「どのスタイルは変更されないのか」 が理解できる状態。 - 保守しやすい
- 既存のCSSのリファクタリングをできるだけ行わずに,
新しい見た目や機能を追加できる状態。 - 再利用をしやすい
- 汎用的なスタイルは,
定義したCSSの形を変えずに, どのような場合でも複数箇所で使い回すことができる状態。 - 拡張しやすい
- 機能の追加・
修正などの拡張をすることを前提として, 他のどの開発者がアサインされたとしても低学習コストでソースコードを理解し, サイトの拡張ができる状態。
設計が破綻しやすいCSS
次に,
- HTMLの構成に依存している
- スタイルの打ち消しを使用している
- 詳細度によるスタイルの上書きを多用している
HTMLの構成に依存している
以下のようなナビゲーションリストを実装し,a
タグに対してスタイルを定義しました。とりあえず,
<ul class="navigation">
<li><a>link1</a></li>
<li><a>link2</a></li>
</ul>
.navigation li a {...}
数日後,p
タグを追加するマークアップに変更する機会がありました。この変更により,a
タグに対してスタイルが適用されません。そのため,
<ul class="navigation">
<li>
<p><a>link1-a</a></p>
<p><a>link1-b</a></p>
</li>
<li>
<p><a>link2-a</a></p>
<p><a>link2-b</a></p>
</li>
</ul>
.navigation li p a {...}
上記のようなことを繰り返していては,
以下のような実装であれば,
<ul class="navigation">
<li>
<p><a class="navigation-link">link1-a</a></p>
<p><a class="navigation-link">link1-b</a></p>
</li>
<li>
<p><a class="navigation-link">link2-a</a></p>
<p><a class="navigation-link">link2-b</a></p>
</li>
</ul>
.navigation-link {...}
極端な例でしたが,
<div class="navigation">
<a class="navigation-link">link1</a>
<a class="navigation-link">link2</a>
</div>
スタイルの打ち消しを使用している
以下のような見出しの実装があったとします。上下の余白や下線を適用させたくない場合を考えてsimple
というクラスで,margin: 0;border: none;
という打ち消しの指定をしています。
<h2 class="heading simple">シンプルな見出し</h2>
...
<h2 class="heading">デコレーション見出し</h2>
...
.heading {
font-size: 40px;
font-weight: bold;
margin-top: 10px;
margin-bottom: 10px;
border-bottom: 2px solid black;
}
.simple {
margin: 0;
border: none;
}
こういったケースでは,
<h2 class="heading">シンプルな見出し</h2>
...
<h2 class="heading decoration">デコレーション見出し</h2>
...
.heading {
font-size: 40px;
font-weight: bold;
}
.decoration {
margin-top: 10px;
margin-bottom: 10px;
border-bottom: 2px solid black;
}
CSSの記述が2行分削減されました。この範囲だけ見ると小さいものではありますが,