(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) |