聞いたら一生の宝,プログラミングの基礎の基礎

第9回 CSS設計の基礎を見直す

この記事を読むのに必要な時間:およそ 4 分

みなさんこんにちは。teratail開発チーム デザイナーの平井優です。

Webサービスの制作において,閲覧者にとって情報を視覚的に伝わりやすくするためにはページのスタイル調整が欠かせないと思います。そんな重要な役目を担っているのがCSS(Cascading Style Sheets)というスタイルシート言語です。CSSを利用すればHTMLで記述された文書を読みやすくするだけでなく,3D,アニメーションなどのリッチな表現も可能になります。

そんな便利なCSSなのですが,長期的に運用していると予想外の不具合や,ほんの少しの変更をするだけで見た目が大きく崩れてしまうといった問題がしばしば起こってしまいます。

[参考]teratailでの質問件数(2015/12時点)
CSS:761件
CSS3:327件

今回は,そういった不具合によって後で困らないために,「CSSの設計」の基本的な考え方をアンチパターンなど具体的な例を交えながら紹介していきます。

CSSを設計することの重要性

CSSはとてもシンプルかつ学習コストも低く,気軽に書くことができますよね。teratailでは,フロントエンドエンジニアやデザイナーでなくとも,ブラウザのデバッグツールを用いてCSSを編集しながら一時的なプロトタイプとして表示確認する光景なんかも珍しくありません。

しかし,そんな簡単に書くことができ自由度が高いものであるからこそ,大規模サイトの運用フェーズや関係者が多いプロジェクトでは以下のような問題が起こることがあります。

  • 予測していなかった箇所のスタイルが崩れる
  • 思った通りにスタイルが反映されず,新しい記述で上書きをしてCSSが煩雑になる
  • 期待する場所以外のスタイルが変わってしまい,過去のCSSを修正せざるを得ない
  • ファイルの肥大化により,どこを編集したらいいのか分かりづらい
  • 既存のスタイルを利用すれば更新は必要ないのに,重複したスタイルを定義してしまう
  • ...etc

いかがでしょうか,みなさまも目にしたことや経験したことがございますでしょうか。簡単な記述の追加だったとしても,上記のような理由により予想以上の時間がかかってしまうことがあります。そんな状況になってしまうことを未然に防ぐため,CSSの設計が重要です。

CSS設計を行う上で意識すること

後で困ることのない,効率的かつ正確な開発をしていくために意識しておくポイントを簡単に追っていきましょう。

予測しやすい
機能追加・見た目の変更・修正を行う際に「どのスタイルが変更されるのか」または「どのスタイルは変更されないのか」が理解できる状態。
保守しやすい
既存のCSSのリファクタリングをできるだけ行わずに,新しい見た目や機能を追加できる状態。
再利用をしやすい
汎用的なスタイルは,定義したCSSの形を変えずに,どのような場合でも複数箇所で使い回すことができる状態。
拡張しやすい
機能の追加・修正などの拡張をすることを前提として,他のどの開発者がアサインされたとしても低学習コストでソースコードを理解し,サイトの拡張ができる状態。

設計が破綻しやすいCSS

次に,前述のようなメンテナブルなCSSに対する以下のアンチパターンを用いて,設計の実例を紹介していきます。

  • HTMLの構成に依存している
  • スタイルの打ち消しを使用している
  • 詳細度によるスタイルの上書きを多用している

HTMLの構成に依存している

以下のようなナビゲーションリストを実装し,リンクの部分aタグに対してスタイルを定義しました。とりあえず,以下の記述で期待するスタイルは実現できます。

<ul class="navigation">
    <li><p><a>link1</a></p></li>
    <li><p><a>link2</a></p></li>
</ul>
.navigation li p a {...}

数日後,以下のようにpタグを削除するマークアップに変更する機会がありました。この変更により,aタグに対してスタイルが適用されません。そのため,CSSの変更を行いました。

<ul class="navigation">
    <li><a>link1</a></li>
    <li><a>link2</a></li>
</ul>
.navigation li a {...}

上記のようなことを繰り返していては,ナビゲーションリストの構造の変更のたびにCSSを変更しなければなりません。

以下のような実装であれば,このケースに対応できます。

<ul class="navigation">
    <li>
        <p><a class="navigation-link">link1</a></p>
        <a class="navigation-link">link2</a>
    </li>
</ul>
.navigation-link {...}

極端な例でしたが,ユニークなセレクタに対してスタイルを定義することでHTMLの構造と見た目が分離され,たとえば以下のように全く違う構造になったとしても対応ができます。

<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行分削減されました。この範囲だけ見ると小さいものではありますが,「スタイルの打ち消し」がCSSの肥大化の大きな原因として挙げられる場合が多いです。

著者プロフィール

平井優(ひらいゆう)

レバレジーズ株式会社 teratail開発デザイナー。

UIデザイン・情報デザインを中心に,サービス企画・フロントエンドの開発・Webに限らずポスターやステッカーなどの制作も担当。趣味はものづくりと音楽活動。特技は妄想。常々,二次元へ行きたいと本気で願っている。

コメント

コメントの記入