(2017.6.24) 最近の状況に更新. Sassを追加。
CSSセレクタについて。
2017.6現在の仕様の最新版は, CSS Snapshot 2017 W3C Working Group Note, 31 January 2017
そこからいろいろな仕様が参照されている。CSSセレクタについては、Selectors Level 3 が CSS 2.1のセクション5を丸ごと置き換えている。
一方, CSS 2.2は、2016年4月で更新が止まっており、やる気がない。
ロジックで言えば Level 3だけを見ればいいんだろうけど、まずはCSS 2.1を押さえておく。
仕様を読んでいても、例示ばかりで、技術的にはっきりしない。技術文書らしからぬ書き方。構文で確認していく。
構文上 ruleset がパタンと指示内容の組み合わせ。パタンはセレクタを組み合わせたもの。
セレクタを','で区切るのが、一番優先順位が低い.
,' S* selector ]*{' S* declaration? [ ';' S* declaration? ]* '}' S*
次いで, E F, E + F と E > F が同一順位.
+' S* | '>' S*
要素名は, こうなっている。
*'
属性のほうは, 次のようになる。simple_selector を再掲。複数の条件を連ねるのは、論理積 (AND) になる。構文上は IDセレクタを複数書けることになっているが、意味ない.
#' {nmchar}+
.' IDENT
[' S* IDENT S* [ [ '=' | "~=" | "|=" ] S*]'
:' [ IDENT | IDENT '(' S* [IDENT S*]? ')' ]
','で区切って複数のセレクタを並べられる。CSSだと構文の優先順位が一番低く, セレクタを全部並べる必要がある。Sassで展開する.
| Sass | |
|---|---|
| CSS (output) |
| パターン例 | 意味 |
|---|---|
* | いかなる要素にもマッチする。 |
E | いかなるE要素にもマッチする。 |
ユニバーサルセレクタは, 文書ツリー内のすべての要素にマッチする。simple_selector の唯一の構成要素でない場合, '*' を省略できる。ANDなんだから当然といえば当然。
*.warning と .warning は等価.
*#myid と #myid は等価.
| パターン例 | 意味 |
|---|---|
E F | E要素の子孫のF要素にマッチ。 |
E > F | E要素の子であるF要素にマッチ. |
E + F
| 隣接兄弟セレクタ。隣接セレクタとも。Matches any F element immediately preceded by a sibling element E. |
子孫セレクタが記号を使わずに空白で表現しているので, .class1.class2 みたいなセレクタにうっかり空白を挿入すると, 意味が変わってしまう.
'*' はユニバーサルセレクタで、演算子ではない。次のように書くと、孫以上という限定になる。
div * p
次は、p は liの子孫、li は ol の子, ol は div の子孫、を全部満たすp要素にマッチする.
div ol > li p
隣接兄弟セレクタE + Fは、同じ親を持ち, かつE の直後 (直下ではない.) にFがくる場合の, 要素F にマッチする.「直後」というのは、非要素ノード(テキストノードやコメントなど)は無視する。要素だけを見る。
隣接セレクタと子孫 (子でも) セレクタを組み合わせることもできる。パッと見、何にマッチするか分かりにくいが。
次の CSS片は, e4要素にマッチする。
e1 e2 + e3 e4 { color:blue; }
CSSはカッコなどで優先順位を付けることができない。が、おそらく, 式を展開すれば同じ条件で書き直せるはず。
e1 + (e2 e3) => e2 e1 + e3
Sassで書くと、親子関係は, 二つの書き方がある.
| Sass |
CSS
|
|---|---|
| CSS (output) |
CSS
|
'&' を使えば、単なるネストでない書き方もできる。
| Sass | |
|---|---|
| CSS (output) |
属性セレクタは, 複数の条件を連ねて, AND で限定できる。条件の順序はマッチするかには影響しない。
| パターン例 | 意味 |
|---|---|
E[foo]
| "foo"属性を持つE要素にマッチ。属性値は問わない。 |
E[foo="warning"]
| "foo"属性の属性値が厳密に"warning"と一致するE要素にマッチ。 |
E[foo~="warning"]
| "foo"属性の属性値が空白区切りのリストであって、その一つが"warning"である, E要素とマッチ。 |
E[lang|="en"]
| "lang"属性値がハイフン区切りの文字列で、最初のハイフンより左の文字列が"en" である、要素Eにマッチ。~= と違って, 最初の区切りまでの文字列しか見ない。
|
DIV.warning
| HTMLでは DIV[class~="warning"] と同じ。XML では、適用ルールを定める、何らかの外部の仕様で決める?
|
E#myid
| IDセレクタ。HTMLでは, "id" 属性値が "myid" である要素Eにマッチ。XMLではスキーマによる。が、スキーマ付きのXMLなど滅多にないので、実用ではない。 |
#p123 と [id=p123] は同じではない. 意味が同じでも、IDセレクタのほうが優先される. 何でそんなことになっているのか?
複数のクラスを持つ要素、は '&' を使えばいい。&.cls2 &.cls3 とすると, 子孫セレクタになるのに注意。
| Sass |
CSS
|
|---|---|
| CSS (output) |
CSS
|
構文は同じだが, 適用される優先順位は, (属性セレクタ, 擬似クラス pseudo-class) のほうが (要素名, 擬似要素 pseudo-element) より上.
| パターン例 | 意味 |
|---|---|
E:first-child
| 要素Eが親の最初の子であるとき、要素Eにマッチ。テキスト・空白などはスキップされる。要素だけを見て、最初の子. |
| E:link E:visited | Matches element E if E is the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited). |
| E:active E:hover E:focus | Matches E during certain user actions. |
E:lang(c)
| Matches element of type E if it is in (human) language c (the document language specifies how language is determined). |
:first-line
:first-letter
:before & :after
| Sass | |
|---|---|
| CSS (output) |