ITCSSとBEMを使用して大規模なCSSのボトルネックを解決する方法
###はじめにフロントエンドコードベースプロジェクトでは、要件と場合によってはスコープが頻繁に変更される可能性があります。 要件が変更され、特定のページでスタイルシートを調整したり、セレクターのスタイルを拡張したりすると、そのような変更は、同様のスタイルを共有する他のビューに影響を与えることがよくあります。
これは、スタイルをオーバーライドしようとしている間、何時間もの特異性戦争につながる可能性があります。 これは、スタイルシートへの変更がプロジェクト全体に悪影響を及ぼさないようにプロジェクトが適切に構成されていないために発生します。 このチュートリアルでは、問題を回避するために、Block Element Modifier(BEM)CSSとInverted Triangle CSS(ITCSS)を組み合わせる方法を説明します。
CSSの操作中に直面する一般的な問題
言語としてのCSSには、開発者にとってCSSの管理を少し難しくするいくつかの問題があります。
- これは宣言型です。つまり、プロジェクトの状態を通知する制御フローがありません。
- すべてがグローバルスコープに存在し、スタイルの衝突を可能にします。
- 特定のセレクターに適用されるスタイルを決定する特異性の問題もあります。
これらの問題は、プロジェクトが成長し、同じコードベースで作業する開発者が増えると、さらに明らかになります。 適切な構造が設定されていないと、スタイルシートへの変更が予測できなくなる傾向があります。
これらの問題を回避するのに役立つ方法でCSSを適切に構造化するために、 Harry Roberts は「InvertedTriangleCSS(ITCSS)」を作成しました。 これは、CSSがより予測可能な方法で動作するようにCSSを構造化するのに役立つ方法論です。 これは、大規模なプロジェクトで作業する開発者がCSSをより適切に整理および管理できるように設計されています。
ハリーによれば、ITCSSは、開発者がCSSをグループ化して順序付けし、CSSをスケーラブル、簡潔、論理的、および管理しやすくするための原則とメトリックのコレクションです。 これは、CSSプロジェクトを階層化された逆三角形として視覚化する方法です。 この階層形状は、言語の設計によって定義されたメトリックによってCSSを並べ替えるモデルを表しており、人の考え方に基づいてCSSを記述した場合よりも、スケーラビリティと保守性が向上します。
ITCSSも柔軟性があり、プリプロセッサの有無にかかわらず使用できます。 これは、BEM、SMACSS、OOCSSなどの他のCSS手法と互換性があります。 このチュートリアルを進めるにつれ、BEMでITCSSを使用する方法を紹介します。
ITCSSの基本原則
CSSにIDがありません
IDはセレクターの特異性が高く、これによりスタイルのオーバーライドが困難になる可能性があります。 IDを上書きするには、IDを追加するか、!important
を使用します。これにより、スタイルシートで特異性戦争を開始できます。 CSSを保守しやすく、快適に操作できるように、スタイルのオーバーライドと拡張は難しくありません。
コンポーネントUIパターン
コンポーネントは、通常、ロジックとスタイルを備えた再利用可能なマークアップのコレクションです。 コンポーネントは自己完結型であり、React、Angular、Vue、Emberなどの最新のフロントエンドテクノロジーのビルディングブロックとして機能します。 ITCSSは、ページよりもコンポーネント化されたUIアーキテクチャを優先します。
クラスベースのアーキテクチャ
優れたCSSアーキテクチャは、再利用可能で柔軟性のあるアーキテクチャです。 ITCSSは、クラスを同じページで複数回使用でき、特定の要素に複数のクラスを配置できるため、クラスの使用を優先します。 クラスはまた、HTMLを読みやすくします。
ITCSSの主要な指標
ITCSSは、3つの主要なメトリックを使用してプロジェクトを注文します。
ジェネリックスタイルからエクスプリシットスタイルへ
一般的で高レベルで広範囲にわたるセレクターから始めて、徐々に明示的でより具体的なセレクターに進みます。 ブラウザのリセットルールから始めて、要素セレクタに進み、btn-primary
などの明示的なルールに進むことができます。
低特異性から高特異性
すべてのCSSルールには特異性の重みがあります。これは、他のルールよりも多かれ少なかれ重要であるか、同等に重要である可能性があることを意味します。 この重みは、競合するルールがある場合に要素に適用されるプロパティを定義します。 上部に特定性の低いルールを維持し、その下に特定性の高いルールを維持することで、スタイルが適切にカスケードされ、競合や特異性の戦争を回避できます。
ローカライズされたものにまで及ぶ
プロジェクトの開始時には、CSSルールは多くのDOMに影響を与えますが、プロジェクトを進めるにつれて、ルールはDOMの影響を少なくし、コンポーネントに固有のものになります。 margins
とpaddings
をすべて拭き取るところから始めるかもしれません。 次に、すべてのタイプの要素のスタイルを設定してから、特定のクラスが適用されているすべてのタイプの要素に絞り込みます。 三角形の形を与えるのは、この段階的なリーチの絞り込みです。
利点
これらの3つの主要な指標に従うことには、いくつか言及すると、多くの利点があります。
-
グローバルで広範囲にわたるスタイルは、より効果的かつ効率的に共有されます。
-
CSSは特異性の観点から論理的かつ進歩的な順序で記述されているため、特異性戦争の可能性は低くなります。
-
CSSはより拡張可能になり、冗長なスタイルが回避されるため、ファイルサイズが小さくなり、遅延が発生します。
-
私たちのカスケードと特異性はすべて同じ方向を向いているので、私たちは物事を元に戻すのにほとんど時間を費やしません
ITCSSレイヤー
CSSをレイヤーに分割すると、上記の指標に固執するのに役立ちます。 各レイヤーは、メトリックと一致する場所に追加されます。 各レイヤーは通常、前のレイヤーの論理的な進行です。 レイヤーを進むにつれて、明示性と特異性が高まり、セレクターの範囲が狭くなります。
これは、CSSを以前に記述されたものに追加するだけの順序で記述しているため、CSSのスケーリングが容易になることを意味します。 また、すべてに独自の予測可能な住居があることを意味し、スタイルの検索と追加が容易になります。
ITCSSには7つのレイヤーがあり、ここで詳しく見ていきます。
設定
これは、CSSプリプロセッサを使用する場合の開始点です。 CSSプロジェクト内のどこからでもアクセスできるグローバル変数が含まれています。 グローバル設定の例は、フォントサイズと色の定義です。
ツール
これにはグローバル関数とミックスインが含まれ、ミックスインと関数がグローバル設定にアクセスする必要がある場合があるため、設定の後にあります。 プリプロセッサを使用している場合、この層は2番目の層です。 例としては、font-size
ミックスインpx-to-rem
ミックスインなどがあります。 最初の2つのレイヤーに実際のスタイルを記述しないようにすることが重要です。
ジェネリック
これは実際のCSSが書き込まれるポイントであり、プリプロセッサを使用していない場合の開始点でもあります。 これには、CSSリセットロール、グローバルボックスサイズ設定ルール、CSS正規化ルールなどのスタイルが含まれています。 ここでのスタイルは、DOMの多くに影響を与えます。
エレメント
このレイヤーには、要素セレクタースタイルが含まれています。 これには、裸のHTML要素と分類されていないHTML要素のスタイルが含まれています。 form
、heading
、img
、links
、table
要素のスタイルもここにあります。 ここでのスタイルはまだ非常に特異性が低いですが、DOMへの影響はわずかに少なくなっています。
オブジェクト
これは、クラスベースのセレクターを備えた最初のレイヤーです。 コンテナ、ラッパー、レイアウトシステムなどの非コスメティックオブジェクトのスタイルが含まれています。 このレイヤーは、最後のレイヤーよりもDOMへの影響が少なく、特異性が高く、クラスを使用してDOMの特定のセクションをターゲットにしていることを考えると、少し明確になります。
コンポーネント
このレイヤーは、プロジェクトの各コンポーネントのスタイルを保持します。 表示されているUI要素のスタイルを設定しているため、前のレイヤーよりも明確になっています。 Angular、Vue、Reactなどのコンポーネントベースのフレームワークでは、コンポーネントに直接含めない場合、これは各コンポーネントのスタイルをインポートするレイヤーです。
トランプ
このレイヤーは他のレイヤーよりも優れています。 ここで、ユーティリティとヘルパーのスタイルが定義されます。 それは特異性が重く、以前のスタイルを無効にすることができ、三角形の先端です。 ここのほとんどのスタイルには、!important
フラグが含まれています。
結果
すべてのレイヤーを組み合わせると、次のようになります。
// main.scss
@import "settings.fontsize";
@import "settings.colors";
@import "tools.functions";
@import "tools.mixins";
@import "generic.reset";
@import "generic.normalize";
@import "elements.forms";
@import "elements.table";
@import "objects.contianer";
@import "objects.grid";
@import "components.site-nav";
@import "components.buttons";
@import "components.carousel";
@import "trumps.clearfix";
@import "trumps.utilities";
ITCSSでのBEMの使用
Block Element Modifier(BEM)は、CSSスタイルに名前を付けるための方法論です。 Getbem によると、BEMは非常に便利で、強力で、シンプルな命名規則であり、フロントエンドコードを読みやすく、理解しやすく、操作しやすく、スケーリングしやすく、堅牢で明示的であり、もっと厳密に。
BEMは、クラスベースのセレクターが頻繁に使用されるITCSSの第6層および第7層に特に役立ちます。 BEMに従うと、読みやすくするためにクラスに適切な名前が付けられます。
BEM方法論の例
B(ブロック)ブロックは最上位ノードであり、コンポーネントの最上位の抽象化です。 これは、Webページ上のスタンドアロンエンティティまたはコンポーネントです。
例:
.btn {
rules
}
E(要素)要素はブロックの子です。 それらは独立した意味を持たず、意味的にブロックに結び付けられています。 要素には、ブロック名と二重下線が接頭辞として付けられます。
例:
.btn__text {
rules
}
.btn__icon {
rules
}
M(修飾子)修飾子は、ブロックまたは要素の外観を変更するために使用されます。 これらは、ブロックと要素のルールのバリエーションを作成する方法を提供します。
.btn--lg {
rules
}
.btn__text--light {
rules
}
.btn__icon--right {
rules
}
##結論
コードベースを変更する必要がある場合は、スタイルをオーバーライドしたり、特異性の戦争と戦ったりすることに時間を費やしたくありません。 逆三角形アーキテクチャは、コードベース全体の状態を簡単な用語で視覚化できるようにすることで、戦争が発生しないようにします。
その原則に従うことで、親しみやすく、予測可能で、推測可能で、ルールベースで、ファイルサイズが小さくなりがちで、スケーラビリティと成長に対応したシステムを作成できます。
CSSを多用するフロントエンドプロジェクトで作業している場合は、コードを読みやすく理解しやすくするために、BEMでITCSSを使用することをお勧めします。 これにより、コードの適切な保守が保証されるだけでなく、次の開発者への共感が促進されます。