読者です 読者をやめる 読者になる 読者になる

人生リアルタイムアタック

当面はPython学習帳

2015年時点のCSSセレクタ42個ぜんぶ纏めてみた

Sassにせよcssにせよ、出来る限り限定的にCSSセレクタを指定できるといいよねってことで、W3C記載の表に基づいてCSSセレクタを纏めてみた。
なお、CSS3セレクタに関するW3Cのテクニカルレポートとして Selectors Level 3 が著名だが、 2015年時点のCSS情報を纏めた CSS Snapshot 2015CSS WG members によって作成されているのでこちらの情報を参考としている。*1

ブラウザ互換についてだが、まず HTML5 & CSS3 Web Design のCSS3 Selectorsの項を見る限り、IE10で全セレクタ対応されている。
そして、IE10以下はVista IE9を除き2016年1月12日(米国時間)にサポート終了する。
Internet Explorerサポートポリシー変更の重要なお知らせ - Microsoft

Vista IE9はシェアがかなり少ないことから、実質ブラウザ互換を考える必要はなさそうである。
IE6に苦しまれたブラウザ互換については、CSSに関しては今後はほぼ考えずに済みそうだ。(たぶん)

CSSセレクタ42個まとめ

セレクタパターン セレクタの意味 セレクタが最初に定義されたCSS Level
* すべての要素 全称セレクタ 2
E E要素 セレクタ 1
E[foo] "foo"属性を持つE要素 属性セレクタ 2
E[foo="bar"] "foo"属性の値が"bar"と等しいE要素 属性セレクタ 2
E[foo~="bar"] "foo"属性の値がスペース区切りのリストで、そのいずれかが"bar"と等しいE要素 属性セレクタ 2
E[foo^="bar"] "foo"属性の値が"bar"で始まるE要素 属性セレクタ 3
E[foo$="bar"] "foo"属性の値が"bar"で終わるE要素 属性セレクタ 3
E[foo*="bar"] "foo"属性の値が"bar"を含むE要素 属性セレクタ 3
E[foo|="en"] "foo"属性の値がハイフン区切りのリストで、"en"はじまりであるE要素 属性セレクタ 2
E:root ドキュメントルートであるE要素 構造模擬クラス 3
E:nth-child(n) n番目の子要素であるE要素 構造模擬クラス 3
E:nth-last-child(n) 最後から数えてn番目の子要素であるE要素 構造模擬クラス 3
E:nth-of-type(n) n番目の兄弟要素であるE要素 構造模擬クラス 3
E:nth-last-of-type(n) 最後から数えてn番目の兄弟要素であるE要素 構造模擬クラス 3
E:first-child 最初の子要素であるE要素 構造模擬クラス 2
E:last-child 最後の子要素であるE要素 構造模擬クラス 3
E:first-of-type 最初の兄弟要素であるE要素 構造模擬クラス 3
E:last-of-type 最後の兄弟要素であるE要素 構造模擬クラス 3
E:only-child 他に子要素を持たないE要素 構造模擬クラス 3
E:only-of-type (兄弟要素のうち、)他に同一要素を持たないE要素 構造模擬クラス 3
E:empty (テキストノードも含めて)空のE要素 構造模擬クラス 3
E:link 未閲覧のハイパーリンクを持つE要素 リンク擬似クラス 1
E:visited 閲覧済みのハイパーリンクを持つE要素 リンク擬似クラス 1
E:active アクティブなE要素 ユーザアクション擬似クラス 1と2
E:hover ホバー中のE要素 ユーザアクション擬似クラス 1と2
E:focus フォーカス中のE要素 ユーザアクション擬似クラス 1と2
E:target 参照URIのターゲットであるE要素 ターゲット擬似クラス 3
E:lang(fr) 言語"fr"のE要素 :lang()擬似クラス 2
E:enabled enabled属性であるE要素 UI要素状態擬似クラス 3
E:disabled disabled属性であるE要素 UI要素状態擬似クラス 3
E:checked checked属性であるE要素 UI要素状態擬似クラス 3
E::first-line E要素の最初の行 ::first-line擬似要素 1
E::first-letter E要素の最初の文字 ::first-letter擬似要素 1
E::before E要素の前に生成されるコンテンツ ::before擬似要素 2
E::after E要素の後に生成されるコンテンツ ::after擬似要素 2
E.warning "warning"クラスを持つE要素 クラスセレクタ 1
E#myid ID"myid"を持つE要素 IDセレクタ 1
E:not(s) 単純セレクタsにマッチしないE要素 否定擬似クラス 3
E F E要素の子孫であるF要素 子孫結合子 1
E > F E要素の子であるF要素 子結合子 2
E + F E要素の直後にあるF要素 隣接兄弟結合子 2
E ~ F E要素の後ろにあるF要素 一般兄弟結合子 3

解説

E F, E > F, E + F, E ~ F などは皆知ってると思うので、CSS Level3で定義されたセレクタを中心に解説する。

E[foo="bar"], E[foo~="bar"]

既にCSSを利用している人は使ったことがあると思うので注意点のみ。
例えば、

<header class="navbar navbar-static-top bs-docs-nav">

の場合、header[class="navbar"] はヒットしない。header[class~="navbar"] はヒットする。
これは定義通り、E[foo="bar"]が単一要素と同一な場合に適用されるセレクタであり、E[foo~="bar"]複数要素のなかに該当要素が含まれる場合に適用されるセレクタだからである。

Bootstrapをはじめ、マルチクラス設計で作られたCSS Frameworkや、jQueryを利用する場合には複数のクラスを持つケースが多いので、classを指定する場合には、素直に header.navbar を利用した方が良いだろう。

構造擬似クラスの幾つかを解説

E[foo^="bar"], E[foo$="bar"]

"bar"で始まる、または"bar"で終わる要素にマッチする。

利用例

a[href^="#"] {background-color:gold}
a[href$=".cn"] {color: red;}

と指定すると、ページ内リンクを持つa要素にのみ背景色を金にしたり、.cnドメインへのリンクのみ赤字にしたりできる。

属性セレクタ - CSS | MDN

E:nth-child(n), E:nth-last-child(n)

n番目の子要素であるE要素にマッチする。

<div>
  <p>1</p>
  <p>2</p>
  <p>3</p>
</div>

に対して p:nth-child(2) と指定すると<p>2</p>がマッチする。
nth-last-childは最後から数えたn番目の要素とマッチする。

E:nth-of-type(n), E:nth-last-of-type(n)

n番目のE要素にマッチする。

<div>
  <p>1</p>
  <p>2</p>
  <span></span>
  <p>3</p>
</div>

p:nth-of-type(3) と指定すると、<p>3</p>がマッチする。
ちなみに、括弧内に(odd)(even) を指定すると奇数/偶数番目にマッチする。
実は :nth-child(2n) で偶数や :nth-child(3n+1) で3の倍数+1にマッチできたりもする。

Selectors Level 3 に仕様が書いてあるが

:nth-child( +3n - 2 )
:nth-child( -n+ 6)

とか書いてあってなかなかキモい。

E:first-child, E:last-child, E:first-of-type, E:last-of-type

*-child は最初(後)の子要素であるE要素にマッチする。
*-of-type は兄弟要素の内、最初(後)のE要素にマッチする。

<div>
  <p>1</p>
  <p>2</p>
  <span></span>
  <p>3</p>
</div>
<div>
  <p>4</p>
  <p>5</p>
  <span></span>
  <p>6</p>
</div>

p:first-childであれば、 <p>1</p><p>4</p> がマッチする。
p:first-of-typeであれば、 <p>1</p><p>4</p> がマッチする。

ただしこの場合、
span:first-childは、ここではspanは最後の子要素では無いためいずれの要素もマッチせず、
span:first-of-typeであれば、 <span>あ</span><span>い</span> がマッチする。

*-child が子要素全体の中からの検索であり、*-of-typeは該当要素のみの検索であることを考慮する必要がある。

E:only-child, E:only-of-type

E:only-child は唯一の子要素である場合にのみE要素がマッチする。
E:only-of-type は兄弟要素のうち、他にE要素が存在しない場合にのみE要素がマッチする。

<div>
  <p>1</p>
  <p>2</p>
  <span></span>
  <p>3</p>
</div>

の場合、span:only-child は該当なし、 span:only-of-type<span>あ</span> がマッチする。

否定擬似クラスの解説

E:not(s)

単純セレクタsにマッチしないE要素にマッチする。

<li class='active'>1</li>
<li>2</li>
<li>3</li>

の場合、li:not(.active)とすると、 <li>2</li><li>3</li> がマッチする。

ちなみに、単純セレクタとは、要は普段cssdiv.class-name {...;} と定義している際の div.class-name のことである。 Selectors Level 3 の内容を参照するに、

が該当する。つまり#idも.classも:hoverも:linkも大体使える。

纏め

CSSセレクタ多用しまくると何がなんだか分からなりそうなので、使う時はBEMによるCSS設計に基いたりSassを使ったりして構造化を意識して利用しよう。(戒め)。

構造的なCSS設計, Sass設計については、やはり以下の書籍が参考になるのでフロントエンドを学ぶ技術者でまだ買っていない人はぜひ一読をオススメしたい。

参考:

*1:といってもCSSセレクタの内容に変更はない。