マークアップのあれこれ#3

セレクタの初歩

セレクタ

selector { ... }

プロパティを適用するターゲットを指定するもの、だそうです。
ここにh1とか書けばh1にそのプロパティが適用されます。

主なセレクタの種類

セレクタ 名称 適用対象
ユニバーサルセレクタ 全ての要素
要素名 タイプセレクタ 指定した要素
class クラスセレクタ 指定したクラスが付与されている要素
id IDセレクタ 指定したidが付与されている要素

p.something { ... } はsomethingクラスが指定されているpタグに対して適用されるクラスセレクタ
よく見る形である、.something { ... } は *.something { ... } の*を省略した形。

気になることがあったので下に例を1つ。

<div class="classA">
	<div class="classB">
		<div>てすと</div>
		<div class="classC">テスト</div>
	</div>
</div>
.classA:hover {
	background-color: red;
}

.classA .classB:hover {
	background-color: green;
}

.classA .classC:hover {
	background-color: blue;
}

この場合、"てすと"にカーソルを合わせると"てすと"と"テスト"のどちらも背景が緑色になる。
また、"テスト"にカーソルを合わせると"てすと"が緑色、"テスト"が青色になる。

何が気になったのかと言うと、「複数のセレクタが指定されている場合、左側のセレクタの適用対象の中に含まれる右側のセレクタの適用対象にプロパティを適用する」らしいのですが、
上記のようにclassCが指定されているdivは div.classA -> div.classB -> div.classC という階層になっており、
.classBをすっ飛ばして .classA .classC という書き方でclassCを対象にできるのか?と思いました。
div.classAを親要素とするネストの中にdiv.classCが含まれてるからそりゃ適用されるわけだ

(直接の子要素であることを指定する、 > というキーワードがあるそうな)

優先順位

どの指定が優先されて適用されるのかは以下。

1. !important が付与されている
2. 優先度が高い(後述)
3. 優先度が同じであれば後に書かれたものが有効

優先度の計算

まず、a > b > c のそれぞれの帯があります。
それぞれに点数が振られ、より高位帯の得点が高いものほど優先されます。
a=0, b=2, c=3の指定Aと、a=1, b=0, c=0の指定Bならば、最高位であるa帯に関して指定Bの方が高いので指定Bが適用されます。
a=0, b=2, c=3の指定Aと、a=0, b=2, c=4の指定Bならば、最高位であるa帯が同点であり、次に高位なb帯も同点であり、更に次のc帯に関して指定Bの方が高いので指定Bが適用されます。

得点は以下のルールの下に計算されます。
a: IDセレクタ(#)の数
b: クラスセレクタ(.)の数 + 属性セレクタ([])の数 + 擬似クラス(:)の数
c: タイプセレクタ(要素名)の数 + 擬似要素(::)の数

※1, ユニバーサルセレクタ(*)は一切無視する。
※2, 同じセレクタを重複させるとそれだけ優先度の点数が増加する。

※2の検証をしましょう。

<p class="repeated">重ねた場合はどうか</p>
.repeated.repeated {
	background-color: purple;
}

.repeated {
	background-color: pink;
}

結果はpurpleが適用されました。
優先度が同点であれば後のもの(pink)が適用されるはずなので、このルールは正常に動いていると言えます。

優先度計算の誤謬

aを100点、bを10点、cを1点とする計算法を例示している本やサイトもあるのですが、
b=10(つまり100点相当)であるところでa=1の100点と同価値であるかと言われれば、まったくそんなことはないのではっきり言って誤謬なんでしょう。
どこから流行ったんでしょう?と思ってw3.orgを見たら…公式がこれかよひでぇなぁ

念のため検証

<p id="id1" class="class1 class2 class3 class4 class5 class6 class7 class8 class9 class10">ここには何が適用されるのか?</p>
#id1 {
	background-color: red;
}

p.class1.class2.class3.class4.class5.class6.class7.class8.class9.class10 {
	background-color: yellow;
}

.class1.class2.class3.class4.class5.class6.class7.class8.class9.class10 {
	background-color: blue;
}

結果はredが適用されました。
インスペクタで見ると、red(100点) > yellow(101点) > blue(100点)、の順に優先度が高かったです。
理由は言わずもがな、aが一番高いのがredだから。
(ひどいなぁ)