CSSについて考える 良いCSSとは?編
いまさらだがCSSについて記事をまとめる
既にネットの世界には、優れたエンジニア達によって描かれた、CSSに関する有用な記事が膨大に溢れているが、自分はあえてその宇宙に余りにも小さく脆い一石の記事を投稿する羽目になった
それは何故か??
会社のミッションで設定してしまったからだぁぁ!!(怒)← 自分に対する怒
いやさ、勢いに任せてちょっとシンドめのミッションを設定してしまうってあるよね?
と言うことで今回は「良いCSSとは?」について自分の私見を述べると共に内容を纏めてみたのでよろしくお願いしますー
前提として「良いCSS」ってなんだい?
良いCSSって言うのを調べていくと、CSS Architectureて言う記事とそれを規範とした幾つかの記事に辿り着いた、それらによると、どうやら良いCSSと言うのは4つのポイントを押さえていることらしい
予測しやすい
[原文翻訳]
予測可能なCSSとは、ルールが期待通りに動作することを意味します。ルールを追加したり更新したりしても、意図しない部分に影響が及ぶことはありません。めったに変更しない小さなサイトでは、これはそれほど重要ではありませんが、何十、何百ページもある大きなサイトでは、予測可能なCSSは必須です。
再利用しやすい
[原文翻訳]
CSS ルールは抽象的で十分に分離されている必要があります。そうすることで、すでに解決したパターンや問題を再コーディングすることなく、既存の部分から新しいコンポーネントをすばやく構築できるようになります。
保守しやすい
[原文翻訳]
サイトに新しいコンポーネントや機能を追加、更新、または再配置する必要がある場合、既存の CSS をリファクタリングする必要はありません。ページにコンポーネント X を追加しても、その存在だけでコンポーネント Y が壊れることはありません。
拡張しやすい
[原文翻訳]
サイトの規模と複雑さが増すにつれ、通常はメンテナンスにより多くの開発者が必要になります。スケーラブルな CSS とは、1 人の開発者でも大規模なエンジニアリング チームでも簡単に管理できることを意味します。また、サイトの CSS アーキテクチャは、膨大な学習曲線を必要とせずに簡単に扱えることも意味します。現在 CSS に触れる開発者があなただけだとしても、それが常に当てはまるとは限りません。
なるほど、どれもCSSを記述する上でとても大事な観点だと思う
そしてこの目標を掲げている、という点がCSSを語る上で大事なポイントとなっていると私は感じた
CSSのベストプラクティスに関する総意を得る事は難しい
まずCSS Architectureが第一に述べていることとして、CSSのベストプラクティス(=最も効率の良い記法)に関する総意を得る事は難しい、なので代わりに「CSSが目指すベストな状態、目標を持つべきだ!」としている
要は「CSSはこう書くのが正解!」と言う誰もが納得するような"記述"を示すことは難しいので、そう言うことから考えるのではなく、まず「CSSがあるべき姿(=目標)を考えよう!」ということだ
うんうん、これはCSSを考えるにあたって非常に良いアプローチだと感じる
微妙なニュアンスの違いだが、"記述"を示すのと"目標"を示すのでは大きな差がある
"記述"は具体的な正解を示すが、"目標"は抽象的な正解を示す
"目標"はその達成において絶対的な正解を持たないのだ
とりわけCSSの様に、置かれた状況によってベストプラクティスが異なってしまうものに対して考えるときは、具体的な"記法"ではなく"目標"こそが必要とされるのだろう
誤解されないように補足するが、ベストプラクティスな記述を考える事自体を放棄しよう、と言うことでは無く、あくまで先ずは目標を掲げ、その上で各々が置かれた状況に対するベストプラクティスを考えよう!と言う話
よくある悪い習慣
続いてCSS Architectureでは上記の4つの目標達成の妨げとなる慣行について、いくつかの検討している、それが以下の4つだ
親に基づいてコンポーネントを変更する
これはつまり、HTML構造に依存しすぎている記述について「良くない」としている
以下のコードを4つ目標と照らし合わせて考えて欲しい
【原文引用:親に基づいてコンポーネントを変更する】
.widget {
background: yellow;
border: 1px solid black;
color: black;
width: 50%;
}
#sidebar .widget {
width: 200px;
}
body.homepage .widget {
background: white;
}
上記のコードは
- 「予測しやすい」においては、
.widget
が親要素によって見え方が変わってしまうため、HTMLの修正によって.widget
の再配置や構築があった際にCSSの内容を見るまで.widget
がどの様に振る舞うか予想が出来ない - 「再利用しやすい」においては、例えば
body.homepage .widget
と同じ見た目だがwidth: 150px;
にしたい、と言った場合においてclassを新しく設定する必要があるため、再利用しやすいとはいえない - 「保守しやすい」「拡張しやすい」においては、上記2つが達成されていない時点でこれらが達成されていないことは詳細を記述するまでもないと思う
述べた詳細については、あくまで私見なので納得いかない人もいるかもしれないが「HTML構造に依存しすぎているスタイルは良くない」この点について概ね共感してもらえるのではないだろうか
複雑なセレクター
これは言葉そのまま、要は「やたらと多く複雑なセレクターは良くない」と言うこと
以下のコード見て欲しい
【原文引用:過度に複雑なセレクター】
#main-nav ul li ul li div { }
#content article h1:first-child { }
#sidebar > div > h3 + p { }
先ず大前提として、先程の「HTML構造に依存しすぎている記述」になっているので、ほぼ同じ解釈で「予測しやすい」「再利用しやすい」「保守しやすい」「拡張しやすい」が達成されていない事が分かる
少し補足として、上記の例がHTML構造にあまり依存していないケース、、例えば過度なマルチクラスの使用においても、「多く複雑なセレクターは良くない」という事は合わせて頭に入れておきたい
.form .button.primary.large { }
.card.col-6.attention { }
みたいな場合(例があまり良くないかも、、)は良くないよね!ということ
過度に一般的なクラス名
これはつまり、「名前被りが起きてしまいそうな命名は良くないよね」と言うことだ
例えばWebページにカード式の「あなたにおススメコンテンツ」を表示させる場合、そのタイトルとなる要素にはどのようなclass名が良いだろう?と考えてみる
/* これはよくない 0点 */
.title { }
/* これはWebページの規模によるかなぁ、、50点 */
.cardTitle { }
/* これぐらいユニークな名前が良い 100点 */
.recommendCardTitle { }
またしても私オリジナルの例で大変恐縮だが、これは概ね共感を得る事が出来るのではないだろうか
.title
という命名はシンプルで直感的だが、それはつまり誰でも思い付きそうな名前であり、複数人で開発を想定した場合、意図しないスタイルの継承やオーバーライドが起きてしまう危険性がある
つまり「保守しにくく」「再利用しずらい」ことを意味する
そしてシンプル過ぎる命名故に、何処に使用するタイトルなのかclass名から「予想ができない」
.cardTitle
に関しては「カードのタイトル」と言う使用目的はハッキリしているものの、Webページの規模によっては、カード表示はあらゆる場面、意図で使用されることが多く、これもやはり意図しないスタイルの継承やオーバーライドが起きてしまう危険性がまだまだある様に感じる
やはり.recommendCardTitle
の様に「おススメカードのタイトル」くらいまで名前をユニークにした方が、先に話した「良いCSS」に最も準拠している
ルールを作りすぎる
これはつまり、「1つのclass(或いIDなど)に多くの処理を行わせるのは良くない」ということ
以下のコード見て欲しい
【原文引用:ルールを作りすぎると】
.widget {
position: absolute;
top: 20px;
left: 20px;
background-color: red;
font-size: 1.5em;
text-transform: uppercase;
}
.widget
の内容をみると、見た目だけでなくレイアウトも定義している
これはとてつもなく再利用がしずらい事が想像できるだろう、この.widget
はposition: absolute; top: 20px; left: 20px;
のレイアウトを許容できる場面でしか使用が出来ない
もしこれを再利用しなければならないとしたら、見た目に関するプロパティのみを引用という形で利用するか或いはposition
関係のプロパティを打ち消す新しいclassを作ることになり、いずれにしても冗長な記述は避けられない気がする、、
ただ誤解しないようにしたいのは「見た目とレイアウトが同一セレクターにあるのは良くない」のではなく「ルールを作りすぎること」が、あくまでも良くない、と言うことだ
今回の例で言うと.widget
みたいな、如何にも再利用されそうなパーツに「レイアウト」のプロパティが含まれていることは、ルールを作りすぎている事に該当する、ということ
これが例えばモーダルの「×」ボタンみたいなパーツであれば、見た目とレイアウトは同一に含まれていても全然問題ないだろう
くどいようだが、肝心なのはあくまでも「ルールを作りすぎること」に気を付ける慧眼を持つこと
自分が実装するパーツが「良いCSS」の観点において、何処までの役割を持つべきなのか?この感度が大事!ということですな
おわりに
今回は話した内容以外でもCSS Architectureはまだまだ続きます
ただコア部分、このくらい纏めておけば、或いは理解しておけば良いのかな?と言う部分を今回は抜粋して記事にしました!
いやぁ~CSSってまるで哲学!(笑)
この記事が自分もそうですが、誰かの役に立てば幸いです。
Discussion