CSS設計とは?主要な設計方法を紹介

見やすいCSSのコード、保守性の高いコードというのは書く前の段階でどのようにコーディングしていくかを設計する必要があります。

CSSの設計にはすでにいくつか代表的な設計ルールもあります。
今回は代表的なCSS設計を紹介していきます。

OOCSS

OOCSSはObject Oriented CSSの略称でオブジェクト指向を取り入れたCSS設計となっています。
多くのCSS設計のアイディアに取り入れられているCSS設計の基礎となるものです。

まず、 OOCSSの原則以下の2つがあります。

  • 構造と見た目の分離
  • コンテナーとコンテンツを分解

それぞれについて見ていきます。

構造と見た目の分離

構造と見た目の分離というのは、パーツの基本構造とルール、機能、デザインを分離するということです。
例えば、以下のようなアラートを表示する装飾したいとします。

block-content

何も考えずにコーディングすると以下のようになるかもしれません。

<div class="alert-primary">Primary</div>
<div class="alert-danger">Danger</div>
<div class="alert-success">Success</div>
<style>
    .alert-primary {
        width: 100%;
        padding: 5px 0;
        text-align: center;
        font-weight: bold;
        background: lightskyblue;
        color: deepskyblue;
        margin: 5px;
    }

    .alert-danger {
        width: 100%;
        padding: 5px 0;
        text-align: center;
        font-weight: bold;
        background: lightcoral;
        color: red;
        margin: 5px;
    }

    .alert-success {
        width: 100%;
        padding: 5px 0;
        text-align: center;
        font-weight: bold;
        background: lightgreen;
        color: darkgreen;
        margin: 5px;
    }
</style>

この装飾において重要なのは『パーツの色以外の装飾は一緒である』ということです。
基本構造というのはこのパーツの中で共通部分のことを指しており、OOCSSではこの共通部分は分離するべきだと述べています。
基本構造を分離すると以下のようになります。

<div class="alert alert-primary">Primary</div>
<div class="alert alert-danger">Danger</div>
<div class="alert alert-success">Success</div>
<style>
    .alert {
        width: 100%;
        padding: 5px 0;
        text-align: center;
        font-weight: bold;
        margin: 5px;
    }

    .alert-primary {
        background: lightskyblue;
        color: deepskyblue;
    }

    .alert-danger {
        background: lightcoral;
        color: red;
    }

    .alert-success {
        background: lightgreen;
        color: darkgreen;
    }
</style>

上記の例では共通の装飾であった部分を alert クラスでひとまとめにし色の部分だけ個別のクラスで設定するという設計にしています。
このように設計しておくことで、元のコードよりも簡略化できベース部分の装飾を変更したい時も alertクラスの部分を修正するだけで全ての パーツに適用出来るので出来るので保守がしやすいコードになります。

コンテナーとコンテンツの分解

『コンテナーとコンテンツを分離』は言い換えると、場所に依存しないセレクタを設定するということです。
例えば以下のコードがあったとします。

#header .icon {
    display: inline-block;
    width: 200px;
}

上記のように装飾した時に、フッターやサイドバーにもアイコンを設置したいということになるかもしれません。
上記のようにコーディングしていた場合は、以下のようになるかと思います。

#header .icon {
    display: inline-block;
    width: 200px;
}
#footer .icon {
    display: inline-block;
    width: 200px;
}
#side .icon {
    display: inline-block;
    width: 80px;
}

このコードはheader部分とfooter部分に同じ装飾が為されておりかなり無駄が多いコードになってしまっています。
上記を修正するとなると以下のようになるのではないでしょうか・

.icon {
    display: inline-block;
    width: 200px;
}
.small-icon {
    width: 80px;
}

上記のコードではidセレクタとの依存関係をなくし、大きさが異なる場合はsmall-icon クラスを付与するようにして調整するようにしています。
コンテナーとコンテンツの分離というのはこのように、装飾させるコンテンツをidセレクタなどのコンテナに依存させないということです。

修正前のコードではアイコンを別部分に設置したい場合はCSSを修正する必要がありますが、修正後のコードであればCSSを修正する必要なく必要なくHTMLタグにクラスを記載すれば追加できます。

SMACSS

OOCSSと並んで代表的なCSS設計が『SMACSS(スマックス)』です。
SMACSSはパターンを抽出しやすくするために5段階のカテゴリにパーツを分けます。

  • Base
  • Layout
  • Module
  • State
  • Theme

それぞれ見ていきます。

Base

Baseはブラウザやプロジェクトにおける各要素のデフォルトのスタイルを定義します。
HTMLタグごとの文字サイズや色、全体の背景色、フォントファミリーの定義はBase内で定義します。

html {
    font-family: sans-serif;
}
body {
    background: black;
}
h1, h2, h3, h4, h5, h6, p {
    color: white;
}

Layout

Layoutカテゴリーで定義するのは慣習的に言えばIDを用いて定義されるような構成の大枠部分になります。
headerやfooter、サイドバーなどがLayoutカテゴリーにあたります。

#header {
    background: yellow;
    color: black;
}
#footer {
    background: darkgray;
}

headerやfooterはページ内には1つしかないようにLayoutカテゴリーに属するものは重複しないことが前提になります。

Module

ページを構成するほぼ全てのパーツがここに属しています。ボタンや見出し、リスト、テーブルテーブルなどアラートメッセージなど再利用されるパーツはModuleのカテゴリーに入ります。

State

Stateは状態によって、装飾を変えたい時に定義するカテゴリーです。

.is-hidden {
    opacity: 0;
}
.active {
    opacity: 1.0;
}

SMACSSのStateのポイントとしては接頭語にis- というプレフィックスをつけるという点です。
指定したクラスがどのクラスかを判別するためにStateはis- というプレフィックスを付けて判別が出来るようにしています。

Theme

Themeはテーマを切り替えたりするような機能が備わっているページだった場合に考慮するカテゴリになります。
Stateのようなパーツ毎の状態ではなくサイト全体の色合いが変更されるなどの影響があるものはThemeにあたります。

<body class="theme-dark"></body>
<style>
    body {
        background: white;
    }
    .theme-dark {
        background: darkblue;
    }
    .theme-dark #header,
    .theme-dark #footer {
        background: white;
    }
</style>

上記ではtheme-darkによってヘッダーやフッターのスタイルの装飾が変化するコードとなっています。
このように全体のレイアウトが変わるように装飾の場合は Themeカテゴリーに属し、接頭辞に『theme-』をつける命名規則があります。

BEM

BEMはBlock, Element, Modifier の略でページを構成する要素をこの3つに分類して考えます。

Block

Blockは以下の例でいうと、 .alert の部分にあたります。

<div class="alert alert_primary">
    <h3 class="alert__title">Primary</h3>
</div>
<style>
    .alert {
        width: 100%;
        padding: 5px 0;
        text-align: center;
        font-weight: bold;
        margin: 5px;
    }

    ..alert__title {
        font-weight: bold;
        font-size: 24px;
    }

    .alert_primary {
        background: lightskyblue;
        color: deepskyblue;
    }
</style>

Element

Elementは以下の例でいうと、.alert__titleの部分になります。

<div class="alert alert_primary">
    <h3 class="alert__title">Primary</h3>
</div>
<style>
    .alert {
        width: 100%;
        padding: 5px 0;
        text-align: center;
        font-weight: bold;
        margin: 5px;
    }

    .alert__title {
        font-weight: bold;
        font-size: 24px;
    }

    .alert_primary {
        background: lightskyblue;
        color: deepskyblue;
    }
</style>

Elementの場合は命名規則があり、Block名の後にアンダースコア2つで名前を定義します。

Modifier

ModifierはBlockまたはElementのバリエーションの違いを示す部分です。
以下の例では、.alert_primary の部分です。

<div class="alert alert_primary">
    <h3 class="alert__title">Primary</h3>
</div>
<style>
    .alert {
        width: 100%;
        padding: 5px 0;
        text-align: center;
        font-weight: bold;
        margin: 5px;
    }

    .alert__title {
        font-weight: bold;
        font-size: 24px;
    }

    .alert_primary {
        background: lightskyblue;
        color: deepskyblue;
    }
</style>

Modifierの命名規則は、アンダースコア一つとなっています。
BEMではアンダースコアの数によって3つのブロックを明確に分けるようになっており、どのパーツの部分でどの要素に対しての装飾なのかが名前から判断できるのが大きな特徴です。

紹介したCSSの設計パターンで共通しているのは、共通している部分はパーツをオブジェクト化し、オブジェクトされたものをグルーピングしているという点です。
グルーピングの方法や命名規則に違いはありますが、基本的な考え方は一緒なのでCSSを設計する点で役立てて頂ければ幸いです。

フロントエンドを学習するならSkilled(スキルド)

スキルドではフロントエンド専門の実践特化型のプログラミング学習サービスです。

コーディングからフロントエンジニアまでの学習をカバーしており、コーディングしながら実践的に学習することで知識ではなく『スキル』が身につけられるサービスとなっております。

現在無料体験キャンペーンを行っていますので、気になる方はぜひ無料体験を利用してみてください。