本付録は、メインシリーズであるWordPressのテーマ作成に役立ちそうな情報を補足していくパートだ。
そのため、WordPress固有の内容が含まれない可能性が高いので、そこはご了承願いたい。
逆に言えば、他でも使える汎用的な情報をお届けできるだろう。
さて、タイトルにも入れた通り、CSS設計を付録としてやっていこうと思う。
…というのも、これまでCSSの文法的な書き方は勉強したことがあるのだが、それをより良い形で実現する方法はあまり触れたことがなかった。
で、折角WordPressテーマを作るのなら、そのあたりも勉強したくなった。
なので勉強し、それを記事としてまとめておこう、ということだ。
今回は、まずそもそもCSS設計って何ぞやという部分を解説しよう。
当然だが、CSSが何かとか、基本的な文法は抑えていることを前提としている…が、私自身の復習も兼ねてセレクターとカスケーディングあたりは簡単にまとめている。
それを読んでもまだ不安な方は、先に進む前にCSS自体をもう一度勉強しておこう。
なお、この付録では新たに別の参考書を用意した。
Webで色々と調べたところこれが一番良さそうだったので、気になる方は調べたり買ったりしてみよう。
何も考えずにCSSを組むとどうなるか
さて、今回から始めるCSS設計なのだが、その解説に入る前にこれがないとどうなるかを考えてみよう。
何も知らない今の私がやろうとすると、恐らく行き当たりばったりでそれぞれの要素にクラス名をつけ、それに対して固有のスタイルを当てていく、という形を取るように思う。
以前、jQuery講座の中で実際のページっぽいサンプルを用意したのだが、そこがまさにこれをやってしまっていた。
その時はメインの内容ではなかったので目を瞑っていたのだが…当然、このやり方はよろしくない。
今回やろうとしているWordPressテーマのCSSでこれをやってしまうと…もはや地獄だろう。
どこに何が書いてあるか、ある1か所を直すと他のどんな場所に影響するか、などを考えるとぞっとする。
で、一旦作って終わりというわけにもいかず、いずれメンテナンスの必要性も出てくる。
その時にも、同じように地獄の中に足を踏み入れなければいけない。
…なのだが、なんでこんなことになってしまうのか。
それは、CSSの記述の影響範囲が要因の一つになっている。
参考書では、一個の見出しとして以下のように書かれている。
CSSはすべてがグローバルスコープ
CSS設計完全ガイド ~詳細解説+実践的モジュール集
そう、極端な書き方をすれば、全ての設定が互いに影響する可能性があるのだ。
そもそもCSSは初学者でもかなり簡単に操作できるよう、シンプルに組めるようになっている。
が、記述内容が複雑になってくると、今度はそれが裏目に出てしまう。
何も考えずに書いていると、ある1か所についての記述をすることで別の個所がその影響を受け、それを直すと今度はまた別の所に影響を与えて…なんてこともあるだろう。
簡単に書けるCSSの裏にはこんな危険がある、ということを認識しておこう。
もう一つあるとすると、CSSを適用するHTML側が複雑になってきた、という点も挙げられる。
まず前提として、CSSが提唱されたのが1994年。
そして、最初のCSSが世界的な標準仕様として認められた(これを勧告と呼ぶらしい)のが1996年12月。
今や2021年なので、それから20年以上も経過していることになる。
そこからある程度のアップデートはされているものの、大きくがらっと変わったことはないのだろう。
ということは、その当時に考えられていたHTMLへ適用することを前提としているので、HTMLの進化に追い付けていないとも考えられる。
こんな要因があり、何も考えないと簡単に地獄(あるいはカオス、スパゲッティコード)が出来上がってしまうのだ。
CSS設計
そこで、どうやってこのCSSを管理しやすくするか、という工夫はそれぞれの会社や個人で色々と取り組まれてきた。
参考書によると、このような各個が作成したCSSの規則をオレオレCSSと呼ぶらしい。
しかし、それでも完全に問題が無くなったわけではない。
それぞれが独自に考えているので、そこ1か所でしか使えなかったり、あるいは考慮漏れでそもそも規則として成り立たない、なんてこともあったようだ。
それを解決するため、2011年頃に初めて具体的なCSS設計手法が登場した。
最初はOOCSSというもので、そこからどんどんBEM、SMACSS、MCSSなどの手法も開発された。
この種類は多岐に渡り、日本でも幾つか開発がされているようだ。
…さて、今ざっと挙げただけでも4種類、もちろん他にもある。
これだけあるとどれを使えばいいのだろうか、という疑問が湧いてくる。
これには、明確な答えがない。
結局それぞれ特化している内容が異なるので、どんなWebページに対するスタイルを作るかによって適した手法が変わってくるからだ。
とはいえ、どのCSS設計手法にも、共通している事項がある。
参考書から抜粋しよう。
しかしどのCSS設計にも共通して言えることは
CSS設計完全ガイド ~詳細解説+実践的モジュール集
・抽象化する
・分ける
でしょう。
ということで、根本となる考え方は同じだ。
そのため、最初からこれを使おうと一つだけを勉強するのではなく、複数の内容を照らし合わせながら進めていくのが良さそうだ。
CSS設計の利点
利点と書いたが、CSSが組みやすく、また管理しやすくなるのは言うまでもない。
それ以外にも、一つ大きな利点がある。
それが、逆にHTML側のページデザインにも使える考え方だった、ということだ。
実際、デザインシステムを構築、運用する考え方の方法論として、Atomic Designというものがある。
この中でUIを5つの段階に分解し、再度組み合わせるということをしている。
さらに抽象化も行われているので、CSS設計と考え方が近く親和性も高い。
ここでAtomic Desingの解説は行わないが、ある程度学習が進んだらこちらも見てみるといいだろう。
まあ、要するにHTMLを書く時にもCSS設計を知っておくと書きやすいよ、ということだ。
復習:CSSの基礎
冒頭では前提知識としてしまったが、一応ここでざっと復習しておこう。
流石にブロック内の書き方であるプロパティ: 値;
は大丈夫だと思うし、その各プロパティを解説し始めると数が多すぎて本題に入れなくなる。
そのため、その設定をどこに適用するかというセレクターと、ちょっと厄介なカスケーディングをここで解説していく。
セレクター
単にセレクターと書いたが、ここにも色々な書き方がある。
本付録シリーズで使う呼称も、あれば併せて定義していこう。
要素型セレクター
要素型セレクターは、HTMLの特定のタグを指定するタイプのものだ。
セレクターの部分に、そのタグ名をそのまま書けばいい。
例えば、p
タグに対する要素型セレクター。
p {
/* 設定する内容 */
}
このように書けば、それが適用されたHTMLの全てのp
タグに内容が反映される。
全称セレクター
全称セレクターは、HTML内の全ての要素に対するセレクターだ。
これにはアスタリスクを使う。
* {
/* 設定する内容 */
}
属性セレクター
ある要素について、その中の属性が特定の値の要素にのみ適用するのがこの属性セレクター。
要素名の直後に[属性名="設定内容"]
と書くことで、この属性・設定内容の組が書かれている要素への設定が可能になる。
設定内容については前方一致や部分一致なども可能。
例えば、http://example.com
へのリンクを持つa
タグのみに適用する場合は…
a[href="http://example.com"] {
/* 設定する内容 */
}
これで指定ができる。
この場合、HTMLでは…
<a href="http://example.com">ここは適用される</a>
<a href="http://test.com">ここは適用されない</a>
こんな感じ。
もちろんa
タグでなくとも、あるいはhref
属性以外でも可能だ。
しかし、id
属性、class
属性の二つは個別で専用のセレクターが用意されているので、そちらを使おう。
一応仕組み上設定は可能なのだが、id
やclass
の値をこれで指定すると、後述する詳細度が変わってきてしまう。
それが意図したものであればいいのだが、そうでなければやはり誤動作の元なので避けるようにしたい。
クラスセレクター
今度は、class
属性に特定の値を持つ要素に適用するクラスセレクターだ。
タグ名の直後にドットを挟んでクラス名を指定する。
例えば、test
クラスを持つp
タグの設定を行いたい場合は…
p.test {
/* 設定する内容 */
}
これでOK。
また、タグの種類に制限を設けない場合は、タグを省略して…
.test {
/* 設定する内容 */
}
このように書くことができる。
クラス名は、HTMLでの指定時は半角スペースを挟むことで複数付けることができたことも思い出しておこう。
例えば、class="test1 test2"
と書いたら、test1 test2
という一つのクラス名ではなく、test1
とtest2
という二つのクラス名がついていることになる。
IDセレクター
今度はクラス名ではなくID名で絞るIDセレクター。
クラスセレクターのドットをシャープに変えればいい。
p#test {
/* 設定する内容 */
}
/* もちろん要素は省略可 */
#test {
/* 設定する内容 */
}
これまたHTML側の補足になってしまうが、同一ページ内で複数の要素に同じID名をつけることはできない。
逆に、クラス名は同じものが一つのページに複数あっても問題ない。
疑似クラス
疑似クラスは、ある要素に対して特定の状態の時、という条件を指定することができる。
書き方は、元のセレクターにスペースを挟まずコロンを書き、その後ろに状態を表す文言を入れる。
文言の部分に何を入れれるかは、公式のページを参照しよう。
よく見るのは、リンクの色をこれで使い分けているものだろう。
例えば、すでに訪れたことがあるページへのリンク色を変える時は…
a:visited {
/* 設定する内容 */
}
こんな書き方になる。
他にも多数あったり、その中でさらに分類があったりするが、このように一つのコロンを挟んで書くもの全般を本付録シリーズでは疑似クラスと呼ぶ。
ちなみにだが、ここまでのセレクターのことをまとめて単一セレクターと呼んだりする。
疑似要素
疑似要素は、元ある要素のうち特定の部分であったり、あるいは新たにスタイル用の要素を追加してそこに特定のスタイルを適用することができる。
一つ上の疑似クラスと似ているが、こちらはコロンを二つ挟んで書いていく。
この疑似要素には何があるのかについては、やはり公式のページを参照してほしい。
よくあるのは、アイコンの追加だろうか。
リンクのすぐ後ろにアイコンを追加するような時に、わざわざ新しくHTMLで要素を追加せずともCSSだけで追加できる。
a::after {
/* 設定する内容 */
}
疑似クラスと同じようにこれまた色々な種類などがあるが、こちらもコロン二つを挟んで書くもの全般を疑似要素と呼ぶことにしよう。
結合子
さて、ここまでは全て単一の要素に着目していた。
ここからは複数の要素の関係を見ていこう。
一つ目は子孫結合子、一般的には子孫セレクターと呼ばれているのでこちらで呼ぶことにしよう。
単にスペースで挟んで単一セレクターを並べればいい。
それにより、左に書いたセレクターに該当する要素の中に含まれる右のセレクターの要素全てに設定を行うことができる。
例えば、div
要素に含まれる全てのp
要素に対して設定を行う場合は…
div p {
/* 設定する内容 */
}
このように書くことができる。
注意としては、子孫なので、直下だけでなくさらに深い階層にも影響を与えるということ。
上の例では…
<p>ここは適用されない</p>
<div>
<p>ここは適用される</p>
<article>
<p>!ここも適用される!</p>
</article>
</div>
こんな感じになるので注意だ。
二つ目、今度は子結合子。
これも子セレクターと呼ぶことが多いため、こちらを使おう。
今度は二つの要素の間に>
を入れることで、左側の要素の直下にある右側の要素にのみ適用することができる。
例えば、以下のように書いたとき。
div > p {
/* 設定する内容 */
}
この時は、div
要素の直下にあるp
要素だけが対象となるので…
<p>ここは適用されない</p>
<div>
<p>ここは適用される</p>
<article>
<p>!ここは適用されない!</p>
</article>
</div>
こうなる。
最後、兄弟結合子というもので、これも二つに分けよう。
一つ目は隣接兄弟結合子、これまでと同じく呼び方は隣接兄弟セレクターにする。
書き方はプラスを二つの要素で囲む。
並んでいる二つの要素について、一つ目の直後にある二つ目だけ適用されるものだ。
厳密には、親が同じという条件もある。
例えば、div
要素のすぐ次にあるp
要素だけに適用する場合は…
div + p {
/* 設定する内容 */
}
このように書く。
HTML側では…
<div>
<p>ここは適用されない</p>
<div>
<p>ここは適用されない</p>
</div>
<p>ここは適用される</p>
<p>ここは適用されない</p>
</div>
<p>ここは適用される</p>
<p>ここは適用されない</p>
こんな感じ。
ラスト、一般兄弟結合子、呼び方は一般兄弟セレクター。
これは、二つの要素で~
を囲む。
要素1 ~ 要素2
と書いたとき…
- 要素1より要素2が後に出てくる
- 同じ親を持つ
この二つの条件を満たす要素2側のスタイルを設定できる。
先ほどの隣接兄弟セレクターをこの一般兄弟セレクターに変えると、CSSは以下のように。
div ~ p {
/* 設定する内容 */
}
HTMLでの変化は以下の通りになる。
<div>
<p>ここは適用されない</p>
<div>
<p>ここは適用されない</p>
</div>
<p>ここは適用される</p>
<p>ここも適用される</p>
</div>
<p>ここは適用される</p>
<p>ここも適用される</p>
以上、大雑把ではあるがセレクターの復習だ。
なお、コンマ区切りで複数のセレクターを同時に設定するグループセレクターがあったことも思い出そう。
カスケーディング
カスケーディングとは、同じ対象に複数のスタイルが指定されていた時、最終的にどの設定が有効になるかという規則のことだ。
これを決める優先度は以下の通り、数字が小さい方(上に書いてある方)が優先度が高い。
- 重要度
- 詳細度
- 記載順序
このうち、重要度は!important
をつけることで制御できたりするが、この中には制御できないものもあるので省略させてもらう。
また、記載順序はその前二つが同じであれば、後に書いた方が優先される、というだけ。
問題となるのは、その二つ目の詳細度だ。
この詳細度も以下の3段階に分けられ、やはり数字が小さい方が優先度が高い。
- IDセレクター
- クラスセレクター、属性セレクター、疑似クラス
- 要素型セレクター、疑似要素
あるセレクターの中に含まれる、それぞれの個数をカウントして、3段階ごとの数字を算出する。
そして、IDセレクターの数から順に比較していき、差があった時点で、その数値の大きい方が優先される。
ちなみに、これについてはIDセレクターが100の位で、クラスセレクターを含む部分が10の位で…といった解説を見たことがあるかもしれない。
確かにあれは直感的でわかりやすいが、実際にはクラスセレクターを100個用意したところで、一つのIDセレクターには敵わない。
そういった部分には注意しておこう。
また、上で書いたIDを属性セレクタ―で書くと詳細度が変わるという内容だが、この詳細度の分類を見てもらえれば分かると思う。
IDセレクターとして書くと1番目に、要素セレクターとして書くと2番目に該当することになるのだ。
なお、これを確かめるサイトがある。
Specificity Calculatorというサイトで、デフォルトだと幾つかすでにセレクターが入っている黒い部分があると思う。
そこが入力フィールドになっており、自分で作ったセレクターをそこに入れることでこの3段階の数字それぞれを確認することができる。
また、複数入れればそれらに対して適用される順に並び替えもしてくれる。
詳細度で困ったら、ここで実際に試してみるといいだろう。
おわりに
今回から付録シリーズとして、CSS設計を勉強して内容をまとめ始めた。
初回はそもそもCSS設計をなぜするのかの解説と、簡単なCSSの復習を行った。
もちろんだが、今後はCSSの内容を理解している前提で進んでいくので、不安な方は随時調べながら進めていこう。
さて、次回は早速本題…といく前に、実はまだ前提で幾つか書き足りていない部分がある。
具体的にはリセットCSSについてと、命名規則で使いそうな英単語の結合方式について。
前者はまだCSSに関連しているが、後者に至ってはCSSに限らない一般的な話だ。
まだ具体的なCSS設計の内容には入れないと思うが、下準備と思ってしっかり読み進めたい。
2021/3/11追記
次回の内容、リセットCSSと英単語の結合方式について解説した。
前者の方が重要だが、すぐに解説で使いそうなのは後者だ。
前者は色々と考える必要があるので、実際に作り始めるまでにはしっかりと把握しておきたい。
コメント