CSS の整理

大きなスタイルシートや巨大なプロジェクトで作業をはじめると、巨大な CSS ファイルを維持するのが難しいことがわかります。この記事では、CSS を書いていくのと保守していくのをやりやすくするためのベストプラクティスと、保守性を向上させるための解決策の一部を紹介します。

前提条件: 基本的なソフトウェアがインストールされていること、 ファイルの扱い、 HTML の基本(HTML 入門)および CSS に関するアイデア(CSS の第一歩)に関する基本的な知識を得ていること。
目的: スタイルシートを整理するためのヒントとベストプラクティスを学び、 CSS の整理およびチーム作業を手助けするいくつかの命名規則とツールについて調べる。

CSS を整理するためのヒント

スタイルシートを整理して整頓するための一般的な提案を示します。

プロジェクトのコーディング規約があるか?

既存のプロジェクトでチームと作業している場合、最初に確認することは、プロジェクトに CSS の既存のコーディング規約があるかどうかです。チームコーディング規約は常に自分の個人的な好みより優先する必要があります。多くの場合、何かを行うのに何が正しくて何が間違っているということはありませんが、一貫性が重要です。

例えば、MDN コードの例の CSS ガイドラインを見てみましょう。

一貫性を保つ

プロジェクトのルールを設定したり、単独で作業している場合、最も重要なことは、一貫性を保つことです。一貫性は、クラスに同じ命名規則を使用する、色を説明する1つの方法を選択する、一貫したフォーマットを維持するなど、あらゆる方法で適用できます(例えば、タブまたはスペースのどちらを使用してコードをインデントしますか。スペースの場合、いくつのスペース?)

常に従う一連のルールがあると、CSS を作成するときに必要な精神的なオーバーヘッドの量が減ります。

CSS を読みやすくする

CSS をフォーマットする方法には、いくつかの方法を見かけるでしょう。開発者によっては、次のようにすべてのルールを 1 行に配置しています。

css
.box {background-color: #567895; }
h2 {background-color: black; color: white; }

また、すべてを新しい行に分割したがる開発者もいます。

css
.box {
  background-color: #567895;
}

h2 {
  background-color: black;
  color: white;
}

CSS ではどちらを使用してもかまいません。個人的には、各プロパティと値の組を新しい行に置く方が読みやすいと思います。

CSS にコメントを書いておく

CSS にコメントを追加することは、将来の開発者がその CSS ファイルを使って作業する際に役立つだけでなく、休暇の後にプロジェクトに戻ってきたときに自分でも役立ちます。

css
/* これは CSS のコメントです。
複数行に分割できます。 */

ヒントとしては、スタイルシートの論理的な部分にコメントブロックを追加して、ざっと見たときにさまざまな部分をすばやく見つけられるようにしたり、 CSS のその部分にジャンプするために検索するものを提供したりすることもできます。コードに表示されない文字列を使用すると、検索することで部分から部分へジャンプすることができます。以下の例では || を使用しています。

css
/* || 全般的なスタイル */

/* … */

/* || 書体 */

/* … */

/* || ヘッダーとメインナビゲーション */

/* … */

CSS に書かれていることの多くは自明なことなので、いちいちコメントする必要はありません。コメントすべきなのは、理由があって特定の判断をした部分です。

古いブラウザーとの互換性のために、特定の方法で CSS プロパティを使用する場合などがあります。

css
.box {
  background-color: red; /* グラデーションに対応していない古いブラウザーでの代替手段 */
  background-image: linear-gradient(to right, #ff0000, #aa0000);
}

何かを達成するためにチュートリアルに従ったのでしょうが、その CSS があまり自明でなく、認識しやすいものではない場合もあると思います。その場合は、チュートリアルの URL をコメントに追加しましょう。 1 年後くらいにこのプロジェクトに戻ってきたときに、「そういえば、あのことについての素晴らしいチュートリアルがあったな」とぼんやりと思い出すことができるのですが、それがどこのものかは思い出せないものです。

スタイルシートを合理的に分割する

スタイルシートで最初で、すべての一般的なスタイルを設定することをお勧めします。これは、その要素で特別なことをしない限り、通常適用されるすべてのスタイルを意味します。通常、次のルールを設定します。

  • body
  • p
  • h1, h2, h3, h4, h5
  • ulol
  • table 関係のプロパティ
  • リンク

スタイルシートのこの部分では、サイト上の型に対する既定のスタイルを提供したり、データ表やリストに対する既定のスタイルを設定したりしています。

css
/* || 一般的なスタイル */

body {
  /* … */
}

h1,
h2,
h3,
h4 {
  /* … */
}

ul {
  /* … */
}

blockquote {
  /* … */
}

この部分の後で、いくつかのユーティリティクラスを定義することができます。例えば、フレックスアイテムとして表示するリストや他の方法で表示するリストの既定リストスタイルを削除するクラスなどです。多くの異なる要素に適用することが分かっているいくつかのスタイル指定がある場合、この部分に記述することができます。

css
/* || ユーティリティ */

.nobullets {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* … */

次に、サイト全体で使用されるものをすべて追加します。例えば、基本的なページレイアウト、ヘッダー、ナビゲーションのスタイリングなどです。

css
/* || サイト全体 */

.main-nav {
  /* … */
}

.logo {
  /* … */
}

最後に、特定のものを使用するための CSS を、それらが使用されるコンテキスト、ページ、あるいはコンポーネントごとに分けて記載します。

css
/* || 店のページ */

.product-listing {
  /* … */
}

.product-box {
  /* … */
}

このように物事を順番に並べることで、少なくともスタイルシートのどの部分に変更したいものがあるのかを知ることができます。

過剰なセレクターを避ける

とても特殊なセレクターを作成した場合、別の要素に同じルールを適用するために CSS の塊を複製する必要があることに気づくことがよくあります。例えば、以下のようなセレクターがあったとします。これは、 <p> のうちクラスが box であるものを、 <article> のうちクラスが main であるものの中にあるルールに適用するものです。

css
article.main p.box {
  border: 1px solid #ccc;
}

同じルールを main 以外の要素、あるいは <p> 以外の要素に適用したい場合は、これらのルールに別のセレクターを追加するか、まったく新しいルールセットを作成しなければなりません。その代わりに、 .box セレクターを使用すると、 box クラスを持つすべての要素にルールを適用することができます。

css
.box {
  border: 1px solid #ccc;
}

より具体的にすることが理にかなっている場合もありますが、これは通常の習慣ではなく、一般的に例外です。

スタイルシートが大きくなってきたら分割する

サイト内のある部分のスタイルがとても異なったものである場合、すべてのグローバルなルールを含む一つのスタイルシートと、その部分に必要なとても特殊なルールを含むいくつかの小さなスタイルシートに分割すると良いかもしれません。一つのページから複数のスタイルシートにリンクすることができますし、先にリンクされたスタイルシートのルールの後に、後にリンクされたスタイルシートのルールが来るという、通常のカスケードルールが適用されます。

例えば、サイトの一部にオンラインストアがあり、そのストアに必要な商品リストや フォームにのみ多数の CSS が使用されることがあります。そのようなものは別のスタイルシートで持ち、ストアのページからのみリンクさせるのが理にかなっています。

これにより、 CSS を整理しやすくなります。また、複数の人が CSS を扱う場合、 2 人が同時に同じスタイルシートで作業する必要があり、ソース管理上の競合が発生するという事態を少なくすることができます。

その他の役立つツール

CSS は、それ自身に組み込まれた組織化の方法が充実していないため、 CSS の一貫性のレベルは、書き手に大きく依存することになります。ウェブコミュニティは、大規模な CSS プロジェクトを管理するのに役立つさまざまなツールやアプローチを開発してきました。他の人と一緒に作業するときには、このような補助ツールに出会う可能性が高く、また一般的に役立つことが多いので、その一部を簡単にご紹介しています。

CSS の方法論

CSS を記述するための独自のルールを考え出す代わりに、コミュニティによってすでに設計され、多くのプロジェクトでテストされているアプローチのいずれかを採用するほうが得策かもしれません。これらの方法論は、基本的に CSS コーディングガイドであり、 CSS の記述や構成についてとても体系的なアプローチを取っています。一般に、これらの方法論は、プロジェクト独自のルールに従ってすべてのセレクターを記述し、最適化した場合よりも、 CSS をより冗長に表現する傾向があります。

しかし、このようなシステムを採用することで、多くの構造を手に入れることができます。これらのシステムの多くは広く使用されているため、他の開発者はゼロからあなた自身の個人的な手法を見つけ出すのではなく、使用しているアプローチを理解し、同じ方法で自分自身の CSS を記述できるようになる可能性が高くなります。

OOCSS

あなたが遭遇するであろうアプローチのほとんどは、 Nicole Sullivan の業績によって人気を博した Object Oriented CSS (OOCSS) の概念に起因しています。 OOCSS の基本的な考え方は、 CSS を再利用可能なオブジェクトに分割し、サイト上の必要な場所で使用できるようにすることです。 OOCSS の例として代表的なものに、メディアオブジェクトとして記述されているパターンがあります。これは、片面に固定サイズの画像や動画などの要素を配置し、もう片面には柔軟なコンテンツを配置したパターンです。コメントやリスティングなどのウェブサイトでよく見かけるパターンです。

もし、 OOCSS のアプローチを取らないのであれば、このパターンが使用される様々な場所に対してカスタム CSS を作成することになります。例えば、 2 つのクラスを作成し、 1 つは comment という名前で構成要素に対して多くのルールを設定し、もう 1 つは list-item という名前でいくつかの小さな違いを除いて comment クラスとほとんど同じルールを設定します。この 2 つのコンポーネントの違いは、 list-item には下の境界線があることと、 comment 内の画像に境界線があるのに対し、 list-item の画像にはないことです。

css
.comment {
  display: grid;
  grid-template-columns: 1fr 3fr;
}

.comment img {
  border: 1px solid grey;
}

.comment .content {
  font-size: 0.8rem;
}

.list-item {
  display: grid;
  grid-template-columns: 1fr 3fr;
  border-bottom: 1px solid grey;
}

.list-item .content {
  font-size: 0.8rem;
}

OOCSS では、media と呼ばれる 1 つのパターンを作成して、両方のパターンに共通の CSSをすべて持つようにします。一般的には media オブジェクトの形状を表す基底クラスです。そして、それらの小さな違いに対応するために追加のクラスを追加して、特定の方法でスタイリングを拡張します。

css
.media {
  display: grid;
  grid-template-columns: 1fr 3fr;
}

.media .content {
  font-size: 0.8rem;
}

.comment img {
  border: 1px solid grey;
}

.list-item {
  border-bottom: 1px solid grey;
}

HTMLでは、コメントに mediacomment クラスの両方を適用する必要があります。

html
<div class="media comment">
  <img src="" alt="" />
  <div class="content"></div>
</div>

リストアイテムは次のように medialist-item が適用されます。

html
<ul>
  <li class="media list-item">
    <img src="" alt="" />
    <div class="content"></div>
  </li>
</ul>

Nicole Sullivan がこのアプローチを記述し、普及させたことで、今日、厳密に OOCSS のアプローチに従っていない人でも、一般的にこの方法で CSS を再利用していることになります - 一般的に物事をアプローチする良い方法として私たちの理解に入ってきています。

BEM

BEM とは、 Block Element Modifier の略です。 BEM では、ブロックは、ボタン、メニュー、ロゴなどの独立した実体として扱われます。要素は、リスト項目やタイトルのようなもので、それが含まれているブロックと結びついています。修飾子は、ブロックや要素に付けられたフラグで、スタイルや動作を変更するものです。 BEM を使用したコードは、 CSS のクラスにダッシュとアンダースコアが多用されているため、見分けがつくと思います。例えば、 BEM の命名規則についてのページから、この HTML に適用されたクラスを見てみましょう。

html
<form class="form form--theme-xmas form--simple">
  <label class="label form__label" for="inputId"></label>
  <input class="form__input" type="text" id="inputId" />

  <input
    class="form__submit form__submit--disabled"
    type="submit"
    value="Submit" />
</form>

追加のクラスは、 OOCSS の例で使用されているクラスに似ていますが、 BEM の厳密な命名規則を使用しています。

BEM は大規模なウェブプロジェクトで広く使用されており、多くの人がこの方法で CSS を作成しています。チュートリアルでさえ、CSS がこのように構造化されている理由について触れずに、BEM 構文を使用する例に出くわす可能性があります。

システムの詳細については、CSS トリックの BEM 101 を参照してください。

その他の一般的なシステム

これらのシステムは多数使用されています。その他の一般的なアプローチには、 Jonathan Snook によって作成された SMACSS (CSS のスケーラブルでモジュール式のアーキテクチャ)、 Harry Roberts の ITCSS、および Yahoo! によって最初に作成された Atomic CSS (ACSS) があります。これらのアプローチのいずれかを使用するプロジェクトに遭遇した場合の利点は、同じスタイルでコーディングする方法を理解するのに役立つ多くの記事とガイドを検索して見つけることができることです。

このようなシステムを使用することの欠点は、特に小規模なプロジェクトの場合、過度に複雑に見える可能性があることです。

CSS のビルドシステム

CSS を整理するもう 1 つの方法は、フロントエンド開発者が利用できるツールをいくつか利用することです。これにより、 CSS を書くために、よりプログラム的なアプローチを取ることができます。プリプロセッサーポストプロセッサーと呼ばれるツールが多数あります。プリプロセッサーは未加工のファイルに対して実行してそれらをスタイルシートに変換し、ポストプロセッサーは完成したスタイルシートに何かを実行します。おそらく、読み込みを高速化するために最適化します。

これらのツールを使用するには、開発環境で前処理と後処理を行うスクリプトを実行できる必要があります。多くのコードエディターで実行することができます。または、コマンドラインツールをインストールして支援することもできます。

最も人気のあるプリプロセッサーは Sass です。これは Sass のチュートリアルではありませんので、 Sass でできることを簡単に説明します。これは Sass の他の機能を使っていなくても、整理する上で非常に便利です。 Sass についてもっと知りたいのであれば、Sass の基礎知識の記事から始めて、他のドキュメントに進んでください。

変数の定義

CSS にネイティブカスタムプロパティが追加されたため、この機能の重要性は低下していますが、 Sass を使用する理由の 1 つは、プロジェクトで使用されるすべての色とフォントを設定として定義し、その変数をプロジェクトで使用できるようにすることです。これは、間違った青の色合いを使用したことがわかった場合、 1 つの場所で変更するだけでよいということです。

$base-color 以下の最初の行のように呼び出される変数を作成した場合、その色が必要な場所であればどこでも、スタイルシートを介してその変数を使用できます。

scss
$base-color: #c6538c;

.alert {
  border: 1px solid $base-color;
}

CSS にコンパイルすると、最終的なスタイルシートには次の CSS が含まれます。

css
.alert {
  border: 1px solid #c6538c;
}

コンポーネントスタイルシートのコンパイル

CSS を整理する 1 つの方法は、スタイルシートを小さなスタイルシートに分解することであると上記で述べました。 Sass を使用すると、これを別のレベルに引き上げ、非常に小さなスタイルシートをたくさん持つことができます。コンポーネントごとに個別のスタイルシートを用意することもできます。 Sass のインクルード機能を使用することで、これらすべてを 1 つまたは少数のスタイルシートにまとめて、実際にウェブサイトにリンクすることができます。

例えば、パーシャルを使って、ディレクトリー内にいくつかのスタイルファイル、例えば foundation/_code.scssfoundation/_lists.scssfoundation/_footer.scssfoundation/_links.scss などを作成し、Sass の @use ロールを使って他のスタイルシートに読み込むことができます。

scss
// foundation/_index.scss
@use "code";
@use "lists";
@use "footer";
@use "links";

上記のように、パーシャルがすべてインデックスファイルに読み込まれている場合、ディレクトリー全体を一度に別のスタイルシートに読み込むことができます。

scss
// style.scss
@use "foundation";

メモ: Sass を試す簡単な方法は、CodePen を使用することです。これを有効にすると、 CodePen が Sass パーサーを実行してくれるので、通常の CSS を適用したウェブページを見ることができます。CSS チュートリアルでは、CodePen のデモでプレーンな CSS ではなく Sass を使用しているのを見つけることがありますので、少しでも知っておくと便利です。

ポストプロセッサー

もし、コメントや空白を大量に追加することでスタイルシートのサイズが大きくなることを気にしているのであれば、本番バージョンでは不要なものを取り除くことで CSS を最適化することが後処理のステップになります。これを実現するポストプロセッサーの例としては、cssnano があります。

まとめ

これは CSS 学習ガイドの最後の部分で、ここから CSS の探求を続けるための様々な方法があることがお分かりいただけると思います。

CSS のレイアウトの詳細については、「CSS レイアウトの学習」部分を参照してください。

また、これで MDN の CSS の資料の残りの部分を探索するためのスキルを身につけることができます。プロパティや値を調べたり、CSS 料理帳で使用するパターンを調べたり、CSS グリッドレイアウトなどの特定のガイドを読んだりすることができます。