CSS設計の方法まとめ
今回はCSS設計の方法についてまとめていきます。
歴史から振り返って解説していくので、かなりタメになる内容になっているかと思います。
ぜひ、この記事を参考にしてCSS設計に入門しましょう。
CSS開発の歴史
CSS登場当初は、そこまで複雑なサイトが存在しなかったので、特に設計などは必要ありませんでした。
けれど、徐々にリッチなデザインが求められるにつれて、CSSのファイルがカオスになったため、CSS設計論が登場してきました。
具体的には、BEMやOOCSSなどで、開発・保守をしやすくするための設計理論が提唱されました。
その後、それらを元にした、CSSフレームワークが登場してきます。(BootStrapなど)
さらに、表現力が乏しいという欠点もあったため、SassなどのCSSプロプロセッサーなども開発されました。
その後、Reactなどのコンポーネント指向のJavaScritpフレームワークが登場しきて、CSSはコンポーネントの中に閉じ込めるのが一般的となりました。
そのために開発されたのが、CSS In JSという技術となります。
このコンポーネント指向が生まれたことで、CSS設計は実質不要となりました。
なので、モダンなJSフレームワークを使っている現場にいる限りは、CSS設計を学習する必要はあまりないと言えます。
逆に、Web制作をする場合は、しっかりとCSS設計をしないと保守の段階で苦労することになってしまいます。
また、コンポーネント指向の開発をする際にも、CSS設計の考え方が役に立つことはあります。
なので今回は、CSS設計をする場合を想定して、CSS設計の基本的なことを解説していきます。
CSS設計の基礎
まず、CSS設計を考える際に知っておくべきことを解説していきます。
CSSの問題点
CSSの唯一の問題点は、全てがグローバルスコープであることです。
例えば、a.cssというファイルでスタイリングして、b.cssで同じ要素に対してスタイリングした場合は、エラーが出ずにそのままスタイリングが反映されてしまいます。
小規模なサイトだと、そこまで問題にはなりませんが、大規模サイトだと違ってきます。
大規模サイトの場合は、CSSをたくさんのファイルで管理することになるので、スタイルの衝突が起こってしまいます。
例えば、a.cssというファイルでtitleというクラス名についてスタイリングし、b.cssでもtitleに対しての記述がある場合は、スタイリングが衝突してしまい、cssの読み込みが遅い方が優先されて適用されてしまいます。
このように、意図しないスタイリングが適用されてしまう可能性があるのです。
なので、それを防ぐために、CSS設計が必要というわけです。
CSS設計の主な思想
CSS設計で意識すべきことは、主に次の2つです。
- 分ける
- 抽象化する
グローバルスコープが問題なのであれば、それぞれの要素に独自のクラス名をつければ解決します。
これが、スコープを分けるという考え方です。
けれど、そのような実装方法では、繰り返し同じようなスタイルを書くことになってしまいます。
要は、DRYの原則に反するわけです。
なので、よく使う要素は、抽象化して何度も使えるようにしておく必要があるのです。
ただ、この2つはトレードオフの関係になるので、塩梅がとても難しいです。
そのため、チームごとにきちんとルールを設けておく必要があります。
そして、その際に参考になるのが、CSS設計なのです。
リセットCSS
現状、ブラウザ間で要素に対するスタイリングが若干異なる場合があるので、リセットCSSを使うことが一般的となっています。
リセットCSSとは、ブラウザにデフォルトで指定されているスタイルを打ち消すためのCSSです。
これを使うことで、ブラウザ間の差異を無くすことができます。
リセットCSSには文字の大きさや間隔までも無くすハードリセットCSSと、ある程度のスタイリングは残すノーマライズCSSがあります。
これらはどれが優れているとかは特になく、デザインに拘りたい場合はハードリセットCSSを使うのが良いかと思います。
逆に、業務系のシステムなどで、デザインをそこまだ拘らないのであればノーマライズCSSを使うのが適当です。
良いCSS設計とは
最初にGoogleのエンジニアにより、CSSの良い設計というものが提唱されました。
具体的には、以下の要件を満たすのがCSSの良い設計ということになります。
- 予測できる
- 再利用できる
- 保守できる
- 拡張できる
これは一般のプログラミングとも共通する思想なので、理解がしやすいかと思います。
CSS設計の方法論は基本的にこれらを踏まえて作ってあるので、これを理解していると、具体的なCSS設計論も理解しやすいかと思います。
そして、これを実現するためには、次のことを意識する必要があります。
- 特性に応じてCSSを分類する
- コンテキストに依存させない、そのためHTMLとCSSを疎結合にする
- 影響範囲を意味なく広げない
- 詳細度を意味なく高くしない
- クラス名からスタイルを想像できるようにする
まだ、よく分からないところをもあるかと思いますが、具体的な例を見ていけば理解できるはずです。
具体的なCSS設計方法
では、具体的なCSSの設計方法を紹介していきます。
今回は、主に使われる設計方法を3つ紹介します。
OOCSS
OOCSSとは、Object Oriented CSS(オブジェクト指向のCSS)の略になります。
つまりは、オブジェクト指向のCSS設計論となります。
これの基本的な考え方は、次のとおりです。
- レゴのように組み合わせ可能なモジュールの集まりを作ろう
- そのモジュールを組み合わせてページを作ろう
要は、コンポーネント指向と同じような考え方です。
そして、これを実現するためには2つのことを意識すればOKです。
- ストラクチャーとスキンの分離
- コンテナとコンテンツの分離
それぞれ具体的に解説していきます。
ストラクチャーとスキンの分離
例えば、ボタンのスタイルを2つ定義したいとします。
この場合、全てのプロパティをそれぞれのクラスに持たせるのは、CSS設計の思想的に微妙です。
そのような書き方をしてしまうと、再利用性がなくなってしまうので。
なので再利用しやすいように、以下のように定義し直すことができます。
/* ストラクチャ */
.btn{
font-size: 16px;
width: 100px;
height: 50px;
}
/* スキン */
.red-btn{
background-color: red;
color: white;
}
.blue-btn{
background-color: blue;
color: black;
}
このように、基本的な構造に関してはストラクチャーで定義し、可変の部分をスキンで定義するわけです。
ストラクチャーとスキンの厳密な定義はないので、チーム内で都度話し合うのがベストでしょう。
文字や背景の色など、変えたい場合が多いと思う時はスキンに定義し、それ以外はストラクチャに定義すれば特に問題はないかと思います。
コンテナとコンテンツの分離
次に説明するのが、コンテナとコンテンツの分離です。
これは、「HTMLのコンテキストに依存しないセレクタを作ろう」ということです。
つまり、なるべくセレクタはシンプルに書き、階層構造に依存しないように書くのが最良とされています。
こうすることで、再利用性が増します。
OOCSSの考え方はこれだけなので、設計論としては少し弱く感じるかと思います。
ただ、これを意識するだけでもCSS設計が綺麗になると思うので、特に何も取り入れていないチームはここから始めるのが良いかと思います。
また、冒頭でも述べた通り、1周回ってコンポーネント指向というほぼ同じような概念が最近では使われています。
なので、この設計論は1つの真理だと言えるかもしれないです。
SMACSS
次に解説するのが、SMACSSです。
SMACSSは、Scalable and Modular Architecture for CSSの略になります。
この設計手法では、CSSを次の5つの役割に分類します。
- ベース
- レイアウト
- モジュール
- ステート
- テーマ
それぞれ具体的に解説していきます。
ベース
まず、ここではページのベースを作るように、HTMLのそれぞれの要素にスタイルを当てていきます。
こうすることで、ページ間の差異を減らすことができます。
ただ、ここは飽くまでベースなので、スタイルは最低限に留めるようにしましょう。
そうしないと、いちいちスタイルを書き換える手間が増えるので。
レイアウト
次が、レイアウトです。
これは、headerやfooterなどのレイアウトのエリア分けを行います。
レイアウトをスタイリングするときは、l-から始まるクラス名をセレクタにするのがベストプラクティスとされています。
ここはエリア分けが目的なので、要素の幅や、paddingやmarginなどの間隔などを定義していきます。
モジュール
次が、モジュールとなります。
ここからが具体的なスタイリングとなっていきます。
こちらは、OOCSSのモジュールと同じ概念だと思っていただければOKです。
なので、CSSの書き方も先ほどと同じように、ストラクチャとスキンを分離して書けば問題ないです。
ステート
次に解説するのが、ステートです。
これは、モジュールの状態を表します。
例えば、選択中やホバー時のスタイルを記述します。
なので、基本的にはインタラクティブな要素に対するスタイルとなります。
こちらは、状態を表すクラスを定義し、それをJSを用いて付け替えていくのが一般的となります。
クラス名は、"is-"から始まるものにしましょう。
例えば、アクティブな状態を表す"is-active"というクラスを作って、それを付け替えていくわけです。
テーマ
最後が、テーマとなります。
こちらは少しイメージしづらいかもしれませんが、wordpressを使ったことがある人には分かりやすいかと思います。
Wordpressのテーマごとに、テーマカラーなど設定できるかと思います。
それと同じ感じで、ユーザーがテーマを切り替えたら、ページ全体のスタイルが切り替わるように設定しておくわけです。
ただ、普通のサイトの場合テーマを変えるということはあまりないと思うので、サイトのテーマカラー的なものを作っておけばOKです。
こうすることで、サイトのテーマカラーを青から赤に変えたいと思った時にスムーズに変更することができます。
この時のクラスは、"t-"から始まるものにしましょう。
BEM
最後に紹介するのが、BEMとなります。
こちらはWeb制作業界ではよく使われている手法となります。
主に、大規模なサイトを作成する時に力を発揮します。
BEMは規則がたくさんあるので、実装するのは大変です。
ただ、大規模サイトの場合は、そこまで設計しないとCSSが破綻してしまいます。
なので、「BEMは実現が大変過ぎる」という認識は間違っており、「大規模サイトのCSSはかなり設計を作り込まなおと破綻する」という考えが正解です。
BEMは、Block, Element, Modifierの略となります。
BEMでは、クラスをこの3種類に分けて設計していきます。
大前提
まず、大前提として、BEMではクラス名1つのみのセレクタを使うのが推奨されています。
こうすることで、コンテキストに依存しなくなりますし、詳細度を考える手間なども省けます。
また、クラス名が複数単語になる場合は、ハイフンで区切ります。
Block
Blockは、「どのページでも使い回すことができるパーツ」という認識でOKです。
このBlockはどのページでも使い回せるようにする必要があるので、marginやpaddingなどに周りに影響を及ぼすスタイルはできません。
そのような値を設定したい場合は、後述するmixというものを使います。
また、BlockはBlockでネストさせることが可能です。
Element
Element、はBlockの中に存在するパーツだと思えばOKです。
なので、ElementはBlockの外で独立して使用することはできません。
クラス名は、「親Blockのクラス名__Elementを表す名前」となります。
このElementもネストさせることが可能ですが、「親要素のElement名__Elementを表す名前」と間違えて命名しないように気をつけましょう。
また、Block要素の中に必ずしもElement要素を入れる必要はないです。
ちなみにmarginやpaddingなどはここに記述することができます。
Modifier
Modifierでは、BlockやElementの見た目、状態、振る舞いを定義します。
OOCSSで例えると、スキンのような働きになります。
このような特徴から、もちろん独立して使うことはできません。
クラス名を付けるときは、「親Block(Element)のクラス名--Modifier名」となります。
具体的には、以下のようなことを定義します。
- 見た目 - どんなサイズか?どの色か?
- 状態 - BlockやElementがどのような状態か?
- 振る舞い - それがどのように配置されるか?
Mix
最後にMixという概念について軽く解説します。
簡単に言うと、BlockとModifierのクラスを両方適用させることです。
こうすることで、特定の要素に対してBlockとModifier両方の性質を併せ持って欲しいという状況を解決することができます。
BEMの説明は以上になります。
今回はかなり基本的なことしか説明してないので、詳しくは公式ドキュメントを読んでみるのがいいかと思います。
とは言え、BEMは複雑なので、実務で使わないと理解は難しいかと思います。
僕も使ったことないので、正直理解は浅いです。
そのため、最低限の基礎を理解してれば、とりあえずは問題ないかと思います。
まとめ
今回は、CSS設計についてまとめてきました。
本記事の内容を参考にすれば、より良いCSSが書けるようになるはずです。
ぜひ、参考にしてみてください。
宣伝
0からエンジニアになるためのノウハウをブログで発信しています。
また、YouTubeでの動画解説も始めました。
YouTubeのvideoIDが不正ですインスタの発信も細々とやっています。
興味がある方は、ぜひリンクをクリックして確認してみてください!
Discussion
ここの3行がすごいことになってます。
全て表記が違いますねw
修正しておきました🙇♂️