SMACSSの探索:CSS用のスケーラブルでモジュラーなアーキテクチャ
公開: 2022-03-11大規模なプロジェクトや開発者のグループで作業していると、コードが乱雑で読みにくく、拡張しにくいことがよくあります。 これは、時間が経ち、私たちが戻ってきてもう一度見直すと特に当てはまります。私たちは、それを書いたときと同じ考え方に身を置くように努めなければなりません。
したがって、多くの人が行ったことは、CSSが読みやすくなるようにコードのスタイルを設定するのに役立つCSSアーキテクチャを作成したことです。 SMACSS (つまり、 CSS用のスケーラブルでモジュラーなアーキテクチャ)は、まさにそれを実現することを目的としています。 これは、私が採用したJonathanSnookのCSSアーキテクチャガイドラインの特定のセットです。
現在、SMACSSのアーキテクチャーアプローチは、BootstrapやFoundationなどのCSSフレームワークとは少し異なります。 代わりに、テンプレートやガイドのような一連のルールです。 それでは、CSSデザインパターンを詳しく調べて、それらを使用してコードをより良く、よりクリーンに、読みやすく、よりモジュール化する方法を見つけましょう。
すべてのSMACSSプロジェクト構造は、次の5つのカテゴリを使用します。
- ベース
- レイアウト
- モジュール
- 州
- テーマ
ベース
SMACSSでは、基本スタイルは、ページ上の任意の場所で要素がどのように表示されるかを定義します。 これらはデフォルトです。 リセットスタイルシートを使用している場合、これにより、内部のハードコードされた基本CSSデフォルトの違いにもかかわらず、結果のスタイルがブラウザー間で同じになることが保証されます。
基本スタイルでは、ベア要素セレクター、または疑似クラスを持つもののみを含める必要がありますが、クラスまたはIDセレクターは含めないでください。 (おそらく、サードパーティのプラグインの要素をスタイリングしていて、その特定の要素のデフォルトのスタイルをオーバーライドする必要がある場合にのみ、クラスまたはIDをその中に入れる十分な理由があるはずです。)
これは、ベースファイルユニットがどのように見えるかの例です。
html { margin: 0; font-family: sans-serif; } a { color: #000; } button { color: #ababab; border: 1px solid #f2f2f2; }
したがって、デフォルトのサイズ、余白、色、境界線、およびWebサイト全体で使用する予定のその他のデフォルト値を含める必要があります。 タイポグラフィとフォーム要素は、すべてのページに表示され、同じデザインとテーマの一部であるという感覚と外観を与える統一されたスタイルを持っている必要があります。
SMACSSであるかどうかにかかわらず、 !important
の使用をできるだけ避け、深いネストを使用しないことを強くお勧めしますが、これについてはこの投稿の後半で詳しく説明します。 また、CSSのリセットを使用する場合は、これを含める必要があります。 (私はSassを使用することを好むので、Sassをコピーしたり、各ページの<head>
要素とは別に参照したりするのではなく、ファイルの先頭に含めるだけです。)
レイアウト
レイアウトスタイルは、ページを主要なセクションに分割します。たとえば、ナビゲーションやアコーディオンなどのセクションではなく、実際にはトップレベルの分割です。
これらのレイアウトには、ボックス、カード、順序付けされていないリスト、ギャラリーなどの複数のCSSモジュールが含まれますが、モジュールについては次のセクションで詳しく説明します。 レイアウトに分割できるものを確認するために、Webページの例を考えてみましょう。
ここに、ヘッダー、メイン、およびフッターがあります。 これらのレイアウトには、上部のヘッダーにリンクとロゴ、メインにボックスと記事、フッターのリンクと著作権などのモジュールがあります。 レイアウトはページ上で繰り返されず、一意であるため、通常はIDセレクターを使用します。
また、レイアウトスタイルのルールの前に文字l
を付けて、モジュールスタイルと区別する必要があります。 通常、ここでは、境界線、配置、余白など、レイアウトに固有のスタイルを設定します。また、ページのその部分の背景は、レイアウト固有ではないように見えても、意味があります。
外観の例を次に示します。
#header { background: #fcfcfc; } #header .l-right { float: right; } #header .l-align-center { text-align: center; }
これらのヘルパーを配置に追加することもできます。これを使用して、適切なクラスを子に追加したり、テキストを配置したりするだけで、要素を簡単に配置できます。
別の例として、 20px
のマージンを持つ.l-margin
ように、レイアウトボックスでいくつかのデフォルトのマージンを使用できます。 次に、コンテナ、要素、カード、またはボックスのパディングが必要な場所に、 l-margin
クラスを追加するだけです。 しかし、再利用可能なものが必要です。
.l-full-width { width: 100%; }
このように内部的に結合されたものではありません:
.l-width-25 { width: 25px; }
SMACSSの命名規則について少しお話したいと思います。 CSSでの名前空間の概念を聞いたことがない場合は、基本的に、別の要素の先頭に名前を追加して、他の要素と区別できるようにします。 しかし、なぜこれが必要なのですか?
次のような問題が発生したことがあるかどうかはわかりません。 あなたはCSSを書いていて、何かにラベルを付けています。好きなスタイルを入れて、クラスを.label
と呼びます。 しかし、後で別の要素に到達し、それを.label
にしたいのですが、スタイルを変えます。 つまり、2つの異なるものが同じ名前を持っています—名前の競合です。
名前空間は、これを解決するのに役立ちます。 最終的に、これらは1つのレベルで同じものと呼ばれますが、名前空間が異なり、プレフィックスが異なるため、2つの異なるスタイルを表すことができます。
.box--label { color: blue; } .card--label { color: red; }
モジュール
前に述べたように、SMACSSモジュールはページ上で再利用可能な小さなコードであり、単一のレイアウトの一部です。 これらはCSSの一部であり、1つのページに多数あるため、別のフォルダーに保存します。 また、プロジェクトが成長するにつれて、フォルダー構造のベストプラクティスを使用して、つまりモジュール/ページごとに分割できます。
したがって、前の例では、それ自体がモジュールになる可能性のある記事がありました。 ここでCSSをどのように構成する必要がありますか? 子要素のtitle
とtext
を持つことができるクラス.article
が必要です。 したがって、同じモジュールに保持できるようにするには、子要素のプレフィックスを付ける必要があります。

.article { background: #f32; } .article--title { font-size: 16px; } .article--text { font-size: 12px; }
モジュールプレフィックスの後に2つのハイフンを使用していることに気付くかもしれません。 その理由は、モジュール名に2つの単語がある場合や、 big-article
のように独自のプレフィックスが付いている場合があるためです。 子要素がどの部分であるかを示すために、2つのハイフンが必要です。たとえば、 big-article-title
をbig-article--title
およびbig-article--text
と比較します。
また、特定のモジュールがページの大部分を占める場合は、モジュールをモジュール内にネストできます。
<div class="box"> <div class="box--label">This is box label</div> <ul class="box--list list"> <li class="list--li">Box list element</li> </ul> </div>
ここで、この簡単な例では、 box
がモジュールであり、 list
がその中の別のモジュールであることがわかります。 したがって、 list--li
はlist
モジュールの子であり、 box
の子ではありません。 ここでの重要な概念の1つは、CSSルールごとに最大2つのセレクターを使用することですが、ほとんどのシナリオでは、プレフィックスを持つセレクターは1つだけです。
このようにして、ルールの重複や、同じ名前の子要素に余分なセレクターを設定することを回避できるため、速度が向上します。 ただし、構造化が不十分なCSSプロジェクトの兆候である不要な!important
スタイルのルールの使用を回避するのにも役立ちます。
良い(単一のセレクターに注意してください):
.red--box { background: #fafcfe; } .red-box--list { color: #000; }
悪い(セレクター内の繰り返しと重複する参照メソッドに注意してください):
.red .box { background: #fafcfe; } .red .box .list { color: #000; } .box ul { color: #fafafa; }
州
SMACSSで状態が定義するのは、さまざまな動的な状況でモジュールがどのように見えるかを説明する方法です。 したがって、この部分は実際には対話性のためのものです。要素が非表示、展開、または変更されたと見なされる場合は、異なる動作が必要です。 たとえば、jQueryアコーディオンは、要素のコンテンツを表示できる場合と表示できない場合を定義するためのヘルプが必要になります。 特定の時間に要素のスタイルを定義するのに役立ちます。
状態はレイアウトと同じ要素に適用されるため、前のルールがある場合はそれをオーバーライドするルールを追加します。 状態ルールは、一連のルールの最後のルールであるため、優先されます。
レイアウトスタイルと同様に、ここではプレフィックスを使用する傾向があります。 これは、私たちがそれらを認識し、それらに優先順位を与えるのに役立ちます。 ここでは、 is-hidden
またはis-selected
のように、 is
プレフィックスを使用します。
<header> <ul class="nav"> <li class="nav--item is-selected">Contact</li> <li class="nav--item">About</li> </ul> </header>
.nav--item.is-selected { color: #fff; }
ここでは、 !important
を使用できます。これは、状態がレンダリング時ではなくJavaScriptの変更として使用されることが多いためです。 たとえば、ページの読み込み時に非表示になっている要素があります。 ボタンをクリックすると、それを表示します。 ただし、デフォルトのクラスは次のようになります。
.box .element { display: none; }
したがって、これを追加するだけの場合:
.is-shown { display: block; }
JavaScriptを使用して.is-shown
クラスを要素に追加した後でも、非表示のままになります。 これは、最初のルールが2レベルの深さであり、それをオーバーライドするためです。
したがって、代わりに次のように状態クラスを定義できます。
.is-shown { display: block !important; }
これが、ページの初期読み込みにのみ適用されるレイアウト修飾子と状態修飾子を区別する方法です。 これは、最小限のセレクターの利点を維持しながら機能するようになります。
テーマ
これは、原色、形状、境界線、影などのルールを含むために使用されるため、最も明白なはずです。 ほとんどの場合、これらはWebサイト全体で繰り返される要素です。 作成するたびに再定義する必要はありません。 代わりに、後でデフォルト要素に追加するだけの一意のクラスを定義します。
.button-large { width: 60px; height: 60px; }
<button class="button-large">Like</button>
これらのSMACSSテーマルールを基本ルールと混同しないでください。基本ルールはデフォルトの外観のみを対象とし、デフォルトのブラウザ設定にリセットするようなものになる傾向がありますが、テーマユニットは最終的な外観を与える一種のスタイリングです。この特定の配色に固有です。
テーマルールは、サイトに複数のスタイルがある場合、または異なる状態で使用されるテーマが2つある場合にも役立ちます。したがって、テーマ切り替えボタンなどを使用して、ページ上の一部のイベント中に簡単に変更または交換できます。 少なくとも、すべてのテーマスタイルを1つの場所に保持するため、簡単に変更して整理することができます。
CSS編成方法論
このCSSアーキテクチャのアイデアの重要な概念のいくつかを取り上げました。 この概念について詳しく知りたい場合は、SMACSSの公式Webサイトにアクセスして、さらに深く理解することができます。
はい、おそらくOOCSSやBEMなどのより高度な方法論を使用できます。 後者は、ほぼ完全なフロントエンドワークフローとそのテクノロジーをカバーしています。 BEMセレクターは、一部の人にとってはうまく機能する場合がありますが、長すぎて圧倒され、複雑すぎて使用できない場合もあります。 簡単に理解してワークフローに組み込むことができる、よりシンプルなものが必要な場合、およびあなたとあなたのチームの基本ルールを定義するものが必要な場合は、SMACSSが最適です。
新しいチームメンバーは、以前の開発者が何をしたかを理解するだけでなく、コーディングスタイルに違いがなく、すぐに作業を開始することも簡単になります。 SMACSSは単なるCSSアーキテクチャであり、缶に書かれていることを実行します。それ以上でもそれ以下でもありません。