Enduring CSS 04
-- WIP --
ECSSの紹介
最後の章では、既存のCSSの方法論を考えましたが、あなたの謙虚な作者の必要性のために、それらは不足していました。
私は、Enduring CSSのアプローチが「アルファとオメガ」であることをあなたに納得させるつもりはありません。しかし、それは既存のアプローチとは異なる強みと目的を持っています。したがって、卸売りをしても魅力的ではない場合でも、自分の問題を解決するために借りることのできるものがあることを願っています。
ECSSのハイライト:
各ビジュアルパターンを分離することにより、メンテナンス性が向上します。
セクション/機能/コンポーネントを無断で削除することができるため、ファイルサイズは長期間にわたって最小限に留まります。
ルールは「自己検疫」です。
クラス名/セレクタは、コンテキスト、元のロジック、バリエーションを伝達することができます。
モジュールを作成するすべての言語/技術ファイルは、共有フォルダ内に含まれています。
私が最初にEnduring CSSについて書きましたが、私は一種の反発を予想していました。その時(2014年8月)、誰も私が示唆していることを本当に主張していませんでした。よく知覚される知恵は、ビジュアルパターンを抽象化し、可能な限りデザインを正規化し、コードを消し去ることでした。永続的なCSSは、ある意味で、これらの信念の逆説である。
あなたが略語を認識していない場合、DRYはDo not Repeat Yourselfの略です。これはコーディング時の一般的な目標であり、ロジックがコードベースで一度だけ記述され、単一の真実のソースを提供します。
これに入る前に、使用される用語を明確にすることが役立つと思います。ページの視覚的部分を定義するために使用される用語は、異なるアプローチで異なる名前によって知られている。私が示唆していることや、私が使っている言葉には何の啓示もありません。私たちがこれに入る前に、私たちは皆同じページにいることが重要です。
用語の定義
私は、「モジュール」という用語を使用して、機能の領域および/またはそれを作成するコードを指定しています。例示するために、ウェブサイトのヘッダーはモジュールと見なすことができます。ヘッダーモジュールは、他の機能の小さな部分で構成されます。たとえば、ドロップダウンメニューや検索ボックス。これらのネストされた機能は、コンポーネントとして定義されます。最後に、最小の「アイテム」はコンポーネントまたはモジュールを構成する子ノードです。
だから、繰り返します:
モジュールは、機能の広い、視覚的に識別、個々のセクションです。
コンポーネントとは、モジュール内に含まれるネストされた機能です
子ノードは、コンポーネント(通常はDOM内のノード)を構成する個々の部分です。
簡潔にするために、私がモジュールを指しているとき、それはモジュールまたはコンポーネントである可能性があります。ECSSオーサリングの観点との違いは重要ではありません。
ECSSが解決する問題
ECSSの私の主な目標は、スタイルを抽象化するのではなく、スタイルを分離することでした。
通常は、共通の機能を抽象化したCSSクラスを作成するのが理にかなっています。その利点は、さまざまな要素に再利用して再適用できることです。それは原理的には十分に健全です。問題は、大きくて複雑なユーザーインターフェイスでは、あなたが意図していなかったことにうっかり影響を与えることなく、それらの抽象化に軽微な調整や修正を加えることが不可能になることです。したがって、ECSSの指針は、意図されたターゲットにスタイルを分離することでした。あなたの目標に応じて、繰り返しのコストでさえ、分離はあなたに大きな利点を買うことができます。予測可能なスタイリングとスタイルの単純なデカップリングが可能です。
スタイルを分離するもう1つの利点は、既存のビジュアルパターンに煩わされることなく、デザイナーが必要なものを持ち出せるようにすることです。コード化する必要がある新しいモジュールはすべて、未処理のものにすることができます。私は、漠然とした抽象的な数から構築しようとするよりもはるかに速く設計をコーディングすることができることを発見しました。
詳細度の扱い
私はまた、特異性を取り巻く問題を否定したいと思っていました。この目的のために、私は、すべてのセレクタが単一の(または可能な限り理想に近い)クラスベースのセレクタを使用することを主張する広く使用されているアプローチを採用しました。
CSSの問題がある場合は、私はあなたのために悪い感じ、息子、私は99の問題があるが、特異性は1つではありません。
さらに、構造的なHTML要素(擬似要素を除く)は、スタイルシートではタイプセレクタとして決して参照されません。さらに、IDセレクタはECSSでは完全に回避されています。IDセレクタ自体が悪いからではありませんが、セレクタの強さのプレーフィールドが必要なためです。
コンポーネントに対する「変更」は単純なオーバーライドによって処理されます。しかし、オーサリングの観点からそれらを処理する方法は、管理しやすくするための理由があります。
特定のコンテナ内にある場合、異なる幅にする必要がある要素があるとします。簡単に言えば、オーバーライドが起こるような方法で厳しくする必要はありません。特定の要素に適用される修飾子は必要ありません。我々は非常に緩やかで典型的なシナリオを扱うことができますが、自信を持って管理します。オーサリングスタイルシートに以下のように記述します:
code:ecss04_01.css
.my-Module_Component {
width: 100%;
/* If in the sidebar */
.sw-Sidebar & {
width: 50%;
}
}
そして、それはこのCSSをもたらすだろう:
code:ecss04_02.css
.my-Module_Component {
width: 100%;
}
.sw-Sidebar .my-Module_Component {
width: 50%;
}
これは微妙な利益のように思えるかもしれません。結局のところ、オーバーライドを入れ子にすることで、少し違った方法でオーサリングするかもしれませんが、最終的な結果は典型的なCSSです。別のより具体的なセレクタに基づいて異なるスタイルを取得する要素。
しかし、このアプローチを採用することで、オーサリングの観点から、各キーセレクタに「真の単一のソース」を作成します。そのキーセレクタに変更を加えるすべてのものは、中括弧のセットの中に入れ子になっています。さらに、そのキーセレクタはルートルールとして再び定義されることはありません。このアプローチは、本書の後半で触れるテーマです。
DRYの異なる解釈
私は、他のCSS担当者が追求していたDRYコードの目標とその恩恵を称賛することは、私が欲しいDRYコードと同じ種類であるとは確信していませんでした。それをもう少し説明するために、私は規則の中で繰り返される値とペアについてはほとんど気にしませんでした。これはほとんどの人がDRYアウトに集中していたことです。私が心配していたのは、キーセレクタがコードベースで繰り返されていないということでした。キーセレクタは私の「真実の単一のソース」であり、それは私がDRYしたい領域でした。
そのために、ECSSでは、キーセレクタがプロジェクト全体で複数回定義されないようにするオーサリング規則が施行されています。これについては、「Sane Style Sheetsの十戒」の章で詳しく説明します。
これは重要
奇妙な機会に1つのオーバーライドの存在が十分でない場合、我々は信頼できる!important。
!important特異性とはほとんどを持っている、あなたはおそらく間違った状況で、それは避けるべきであることを承知しているであろう。ここでは、MDNをについて言いたいことがあるものです!important。
スタイル宣言で!importantなルールが使用されている場合、この宣言は、宣言リスト内のどこにあっても、CSSで行われた他の宣言よりも優先されます。!importantなのは特殊性とは関係ありませんが、重要なのは、スタイルシートの自然なカスケードを壊してしまうので、デバッグが難しくなるためです。
しかし、私たちのコントロールを超えたイベント(たとえば、サードパーティのCSSファイルがページにロードされているなど)のスタイルが混乱していて、勢いが必要な場合は、取り入れることができ!importantます。ここから、いくつか余分な歓迎を受けている状態変化の例があります!important:
code:ecss04_03.css
transform: translate3d(0, -$super-height, 0)!important;
}
私は正直に言うと、私は本当に多くの睡眠を失うことはありません!important。
反復の受け入れ
私はそれが可能な「部屋の象」を扱うことが重要だと思います。私は、ファイル全体でプロパティと値の繰り返しをなくすことは、保守の観点から、必要に応じてコードベースから簡単に削除できる堅牢で包括的なモジュールセットを購入するほどではないと納得させる必要があります。
ECSSのアプローチは、CSSのプロパティと値の繰り返しを含んでいます。
ECSSを使用すると、すべての単一のビジュアルモジュールまたはコンポーネントに、他のモジュールやコンポーネントから分離するためのマイクロ名前空間が作成されます。次に、作成されたECSSルールの典型的な例を示します(オーサリング構文はSassと非常によく似ていますが、通常はPostCSSによって容易になります)。
code:ecss04_04.css
.ip-SubHeader_Wrapper {
@mixin Headline;
align-items: center;
/* We want the subheader hidden by default on mobile */
display: none;
font-size: $text12;
background-color: $color-grey-54;
border-bottom: 1px solid color($color-grey-54 a(.5));
min-height: $size-fine-quadruple;
@include MQ(Mplus) {
display: flex;
background-color: $color-grey-a7;
color: $color-grey-54;
font-size: $text13;
min-height: 1.5rem;
border-bottom: 1px solid $color-grey-54;
border-top: 1px solid $color-grey-33;
}
/* However, even on mobile, if the SubHeader Wrapper is in section 1, we want to see it */
.ip-Classification_Header-1 & {
display: flex;
}
}
OOCSSとAtomic CSSの方法論に傾いている人は、それを見て震えるかもしれません。以下のようなものcolorとは、font-sizeほとんどのコンポーネントで宣言されています。@mixin Headlineミックスインは、あまりにも特定のフォントスタックを指定するCSSのかなりのチャンクを生成します。そう、はい、スタイルをまたいだ繰り返しがあります。
ただし、
それは冗長ですが、それは何にも依存しません。
これは一般的にコンテキストに依存しません(配置される場所のサイズのコンテキストを除いて)、このコンポーネントに影響を与えるメディアクエリは、この単一の中括弧のセット内で定義されます。
名前空間付きモジュールは、一度だけ記述されます。このモジュールを変更する必要がある場合は、この1つの場所を調べるだけです。
すべてのオーバーライドがネストされたルールを作成すると、ある種のマイクロカスケードが作成されます。通常、CSS内のどこにでも上書きできる場合、このメソッドを遵守すると、それらを特定の領域に限定することができます。それは、それがルールに関連しているので、特異性を理由づけてはるかに簡単になります。
ゼロコンポーネント抽象化
ECSSでは、既存のコンポーネントと似ていて微妙に異なるコンポーネントを作成する必要がある場合、この既存のコンポーネントから抽象化または拡張することはありません。代わりに、新しいものが書かれます。はい、私は深刻です。たとえそれの95%が同じであっても。
これの利点は、各コンポーネントが独立して分離されていることです。1つは他のものなしで存在することができる。しかし、一方は他方から独立して変更する必要があります。当初は明らかな美的類似性にもかかわらず、他の同様の外観のコンポーネントを感染させたり、汚したりすることなく、必要に応じて突然変異を起こすことができます。生物学的なメタファを拡張するために、私たちは独自のネームスペースのおかげで「自己隔離」するコンポーネントを手に入れました。
さらに、BMW 3シリーズはBMW 5シリーズと共通しています。しかし、彼らは同じではありません。彼らはいくつかの/多くの部分(CSSのプロパティと値の組み合わせに相当)を共有するかもしれませんが、それらは同じではありません。彼らの違いはそれらを定義します。彼らは本質的に異なるものがあるので、まったく同じ部分で作ることはできません。私はECSSで定義されたモジュールとコンポーネントで同じケースであると主張します。CSS言語はIS抽象化。CSSのプロパティ/値のペアは、すでに個々の部分から必要なものを構築できることを意味しています。
繰り返しのコスト?
ECSSの利点を十分に生かすためには、ECSSが作り出す財産と価値の反復に慣れておく必要があります。この時点で、あなたは私が欺かれたと信じているかもしれません。このような重複を抱えて、このECSSアプローチはどのように実行可能な選択肢になりますか?私は、その言葉をgzipという1つの単語で取り上げます。
はい、私はうそをついた。私はそれ以上の資格を与えたいと思います。
gzipは繰り返し文字列を圧縮するのに非常に効率的です
私は実際のECSSのようなアプローチで、実際の世界の違いとプロパティ/値ペアの繰り返しの冗長性が何かと不思議でしたか?実験:
私がECSS方法論を使って作業していたCSSファイルは、gzipされたときに(これは「ワイヤー上で」提供されるため)42.9KBでした。
このスタイルシートからOOCSSクラスに抽象化できる最も一般的で冗長なパターンは、コンテナ内のコンテンツを垂直方向に配置するために豊富に使用される2つのFlexベースのルールです。古いデバイスでのサポートを可能にするために、Autoprefixerによってかなりのコードが追加されているため、これらはさらに冗長です。たとえば、結果のCSSは次のようになります。 code:ecss04_05.css
.flex {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
テストスタイルシートでは、これらの4行のCSSを193回繰り返しました。
それはその半分です。これらのアイテムの多くは、内部で整列する必要があります。それはCSSでもこれを必要としました:
code:ecss04_06.css
.flex-center {
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
そのブロックを117回繰り返した。OOCSSクラスに抽象化するより良い理由はないようですね。それはそこに深刻な肥大を引き起こしているに違いない?あまり速くない、バットマン!
これらのコードブロックが削除され、ファイルが再圧縮されると、CSSファイルのサイズは41.9 KBに減少しました。
最も一般的で冗長なビジュアルパターンをOOCSSクラスに抽出することで、1KBのCSSだけをワイヤで保存できました。そして、CSSにわずか1KBの節約にもかかわらず、これらのスタイルをクラスに抽象化する場合、視覚的効果を元に戻すために、関連するOOCSSクラスでHTMLを捨てる必要があります。
それは価値がありました?
私の本ではなく、ファイルサイズの観点から、他のプロパティの組み合わせには、そのような冗長と繰り返しのようなものはありませんでした。(テンプレートとCSSの両方を変更するために抽象化が必要なため、オーサリングとイテレーションを遅くする必要があります)、応答性の高い柔軟性(別のビューポートでは何かを変えたい場合) CSSの重み。それは、「ピーターがポールを奪うのを奪う」というCSSに相当するものです。
私はかなり明確にしましょう。gzipの有効性にもかかわらず、優先順位がCSSファイルサイズをできるだけ小さくしている場合、ECSSは最良の選択ではありません。代わりに、Atomic CSSを見てみましょう。クリエイターは賢い人です。実際にThierry Koblentzは私が知っている最もスマートなCSSのひとつです。私はACSSがあなたのニーズにうまく対応できると確信しています。 一方、ECSSの優先順位は、開発者のエルゴノミクス(理解できるクラス命名規則)、容易な保守性(コンポーネントで構成され、削除が簡単なスタイル)、スタイルカプセル化(名前空間による漏出抽象化の防止)です。
異なる問題、異なる解決策。
まとめ
あなたがメンテナンス可能なスタイルシートを作成しようとしているのであれば、繰り返されるプロパティ値に執着したり、ペアを組むことが最善の方法ではないかもしれないと考えてもらえたらうれしいです。次の章では、ECSS命名規則のメリットを見るだけでなく、プロジェクトの組織的アプローチが、クラス抽象化と再利用よりもはるかにリーンなスタイルシートを長期的に生成すると主張します。
-- WIP --