再利用できるセレクタの書き方をレクチャー
よく初学者・初級者向けの教材では、HTMLやCSSについて、わかりやすさを優先して説明するためにHTML要素タグを用いたセレクタ指定(クラス名ではなく、<p>や<div>に直接指定する方法)で教えることがあります。
しかしながら、その方法でのCSSスタイリングは多くの問題を抱えています。
皆さんが何気なくやっているセレクタ指定の方法を改めて考えてみることで、スマートなHTMLやCSSを書くことがいかに大事なのか、その必要性に気が付きます。
クラス名をつけるということ
クラス名とは、HTMLに名前をつけることで、CSSでスタイリングしたり、JavaScriptで処理する時の目印になったりするものです。
<h1 class="heading">再利用できるコードとは</h1>
クラス名を付けることで、特定の部分にだけCSSを反映させることができますので、例えば上記のHTMLの場合、
.heading {
font-size: 30px;
}
というようにCSSを書くことで、「.heading」クラスをつけているHTML要素に対し、指定のスタイルが当たるようになります。
つまり、HTMLタグを区別するためにクラス名を設定しているというわけです。
そう考えると、クラスを付けるということは、コードを閲覧する際の読みやすさを向上させる役割もあることがわかります。
………
さて、あなたが書くコードや、コーディングについて学べる教材などで、以下のようなCSSのコードを見た覚えはありませんか?
p.box {
}
h2 {
}
.list {
}
.list li {
}
実はこの書き方、すごくもったいない書き方だということをご存知でしょうか。
もったいない とはどういう事なのでしょうか。
ひとつずつ見ていきましょう。
もったいないパターン1
まず初めに、下記の図とHTML,CSSをご覧ください。
<p class="box">
もったいないパターン1についてお話するためのサンプル用のボックスです。
</p>
p.box {
padding: 20px;
background-color: #f7f4f3;
}
Aのデザインを再現するために、「box」クラスを指定した<p>タグに対してスタイルを設定していますね。
よく見かけるコードだと思いますが、これはもったいないパターン1と言えます。
なぜなら、このようにCSSのセレクタ指定をおこなってしまうと、もう<p>タグ以外に「box」クラスは指定できないということになってしまうのです。
サンプルを例に説明いたします。
下の図をご覧ください。
先ほどのAをコーディングしたあとに、しばらくしてBのようなデザインが出現したとします。
Bの見た目は、Aとほとんど同じ(画像が増えただけ)で、同じクラスを使いまわすことができれば、下記のようなHTMLで実装が可能なはずです。
<p class="box">
もったいないパターン1についてお話するためのサンプル用のボックスです。
</p>
<div class="box">
<img src="image.png" alt="">
<p>
もったいないパターン1についてお話するためのサンプル用のボックスです。
</p>
</div>
しかしながら、CSSのセレクタ指定で「p.box」と記述してしまったため、思い通りにスタイリングするためには、以下のようにセレクタ指定を追加したCSSを書く必要があります。
p.box,
div.box {
padding: 20px;
background-color: #f7f4f3;
}
「いや、こんなふうに記述するくらいなら……」
.box {
padding: 20px;
background-color: #f7f4f3;
}
「もともとこうやって書いておけばよかったよね……?」
ということです。
スタイリングした要素が、今後どのようなHTMLタグで表す要素として出てくるかは誰にもわかりません。
HTML要素タグをセレクタに指定してしまうと、無駄なCSSを生む原因になりえます。そもそも書かないという手段を取ることで、そういった問題も予防できますし、記述量が減ることで読みやすくなりますので、CSSのメンテナンスが楽になるでしょう。
これが再利用できるコードを考えるということです。
他にももったいないパターンがありますので、一緒に見ていきましょう。
もったいないパターン2
h2 {
font-size: 20px;
color: #333333;
}
CSSには、上記のようにHTML要素タグのみ、つまりクラス名をつけずにHTMLタグの名前そのものだけで指定する方法があります。
これはさきほどのパターンと少し似ているケースなのですが、特に見出しタグでよく発生する問題がありますので、その点をお話します。
ここに、ごく一般的なWebサイトのトップページのデザインがあります。
Webサイトのトップページの<h1>には、そのサイトのタイトルを含む要素を指定しますので、多くの場合、ロゴに<h1>タグを指定します。
その後、<h2>や<h3>タグでマークアップできるような見出しが出てきますので、それぞれマークアップをおこない、以下のようなCSSを設定したとします。
h1 {
width: 180px;
}
h2 {
background-color: #f7f4f3;
color: #333333;
font-size: 18px;
padding: 20px;
}
h2 span {
padding-left: 10px;
border-left: 5px solid #2cb696;
}
h3 {
font-size: 15px;
color: #333333;
}
はい、ここまでは問題ありません。
しかしながら、下層ページのコーディングに移った時に、問題は発生します。
下層ページでは、ロゴに<h1>タグを設定しません。
基本的に<h1>は、他のページとは違うユニーク(固有)なものを指定した方が良いとされています。これはHTMLの仕様としてそうしなければいけないわけではなく、検索エンジンに対してWebサイトの情報を明確に伝える上で有用な施策ということで実践されているケースです。
そう考えると、下層ページでの<h1>タグは、トップページの時にキャッチコピーがあった場所にある「ページタイトル」部分に設定する必要があります。
もうお気づきかもしれませんが、<h1>タグに指定されたスタイルはロゴに対してのCSSを記述しているので、下層ページでは使えません。
小手先な対応をするとすれば、下層ページの場合は<h1>のスタイルを上書きするというのも手です。
しかしながら、さらにややこしい以下のパターンが出てくると、もうお手上げかもしれません。
ニュースというページの下層に、『再利用できるコードの書き方をレクチャー』という名前の記事ページがあったとします。
ニュースの記事ページでは、上の図のようにメインビジュアル部分に「ニュース」というページカテゴリを表す文字があって、ニュース記事のタイトルはその下のレベルで表現される事が多いです。
なぜかと言うと、メインビジュアル部分にニュース記事のタイトルを載せてしまうと、そのページが何のカテゴリのページなのかがわかりにくくなってしまうからです。
このようなデザインの場合、「ニュース」という文字はこのページのタイトルには成り得ないので、マークアップは<p>タグ(または<div>タグなど)を利用します。
そして、先ほどから<h2>タグ扱いだった見出しが、<h1>として利用されるようになります。
先ほどと同じように小手先な対応をして、ニュースのページだけは、<h1>を<h2>の見た目になるようにCSSを上書きすることもできます。
でも、こんなことを繰り返しやっていたら、CSSの見た目はますますしんどいことになっていくでしょう。もう相当な量を上書きしてしまっているので、無駄なCSSの記述も増えています。
この場合の解決策は、例えば「heading-a」、「heading-b」のような名前のクラスをはじめから用意しておくことで、たとえHTMLのマークアップ上の見出しのレベル感が変更になっても、クラス名を付け替えることで見た目を維持することができます。
このように、拡張性を考えたコードの設計は非常に重要になります。
ここまでパターンを出したら、もう完全に理解されたかと思います。
CSSのセレクタにHTML要素タグを指定してはいけない
繰り返します。
CSSのセレクタにHTML要素タグを指定してはいけない
ある意味、CSSのセレクタにHTML要素タグを指定することは、再利用できるコードを書くことの邪魔にしかならないのです。
例外はありません。
もったいないパターン3
ちょっとばかり例外に見えなくもないパターンを紹介します。
以下のHTMLとCSSをご覧ください。
<ul class="list">
<li>項目A</li>
<li>項目B</li>
<li>項目C</li>
</ul>
.list {
margin-top: 30px;
}
.list li {
margin-left: 10px;
}
今回のパターンは、はじめにHTML要素タグを指定せず、リストに「.list」という名前のクラス名をつけて、それをセレクタに指定しています。
その後、そのリストの項目のスタイルとして「margin-left: 10px;」を指定するために、「.list li」というセレクタ指定をおこなっています。
これも非常によく見るパターンです。
一見問題無さそうに見えますが、以下のようなHTMLが追加された場合を考えてみましょう。
<ul class="list">
<li>
項目A
<ul>
<li>項目A-1</li>
<li>項目A-2</li>
</ul>
</li>
<li>項目B</li>
<li>項目C</li>
</ul>
「項目A」に対して、更に下位レベルの項目「項目A-1」と「項目A-2」が加わりました。
すると、CSSに記述した「.list li」のルールでいくと、「項目A-1」や「項目A-2」に対しても「margin-left: 10px;」が反映されてしまいます。
このように、想定していなかった箇所にスタイルが影響してしまうのは、かなり問題があります。
最初は良かったとしても、Webサイトが運用されていく中で思わぬところに不要なスタイルが反映されてしまうことになります。
このパターンに関しても、以下のコードのように初めから<li>タグに「.list-item」のようなクラス名をつけておけば、
<ul class="list">
<li class="list-item">
項目A
<ul>
<li>項目A-1</li>
<li>項目A-2</li>
</ul>
</li>
<li class="list-item">項目B</li>
<li class="list-item">項目C</li>
</ul>
「項目A-1」「項目A-2」に対して「margin-left: 10px;」が反映されることはなかったでしょう。
まとめ
もったいないパターン1~3が示してくれたように、CSSセレクタの指定でHTML要素タグを使わず、クラス名を必ずつけてセレクタ指定することが再利用性・拡張性があるコードを書くための最初のステップであることがわかります。
まずは「HTMLタグを書いたら、必ずクラス名をつける」ということを徹底してみることで、スマートなコーディングを始めてみましょう。