セレクタ

目次

  1. セレクタの基礎
  2. 全称セレクタ
  3. タイプセレクタ
  4. 子孫セレクタ
  5. 子供セレクタ
  6. 隣接セレクタ
  7. クラスセレクタ
  8. IDセレクタ
  9. 属性セレクタ
  10. 疑似クラス
  11. 疑似要素

セレクタの基礎

CSSでは、セレクタによって文書ツリー中のどの要素に対してスタイルを適用するのかを決定します。セレクタの条件が文書ツリー中のある要素に当てはまるとき、セレクタがその要素にマッチ(match)すると表現します。CSS 2.1で利用できるセレクタには次の表の通りです。

セレクタ一覧表
セレクタ名 形式 説明
全称セレクタ * 全ての要素にマッチ
タイプセレクタ E E要素にマッチ
子孫セレクタ E F E要素の子孫であるF要素にマッチ
子供セレクタ E > F E要素の直接の子要素であるF要素にマッチ
隣接セレクタ E + F E要素の直後に来るF要素にマッチ
属性セレクタ E[att] att属性を持つE要素にマッチ
属性セレクタ E[att=val] att属性の値がvalであるE要素にマッチ
属性セレクタ E[att~=val] att属性の値が空白文字類で区切られた値のリストであり、そのひとつがvalであるE要素にマッチ
属性セレクタ E[att|=val] att属性の値がハイフンで区切られた値のリストであり、その1番目がvalであるE要素にマッチ
クラスセレクタ E.val (X)HTMLではE[class~=val]に同じ
IDセレクタ E#myid ID属性がmyidであるE要素にマッチ
:first-child疑似クラス E:first-child 親要素から見て最初の子要素であるE要素にマッチ
:link疑似クラス E:link 未訪問のハイパーリンクのアンカーであるE要素にマッチ
:visited疑似クラス E:visited 訪問済みのハイパーリンクのアンカーであるE要素にマッチ
:hover疑似クラス E:hover マウスポインタなどで指し示されたE要素にマッチ
:active疑似クラス E:active マウスのボタンが押されるなどしてアクティブになったE要素にマッチ
:focus疑似クラス E:focus タブキーなどでフォーカスが当てられたE要素にマッチ
:lang疑似クラス E:lang(C) Cという言語で書かれているE要素にマッチ
:first-line疑似要素 E:first-line E要素の1行目にマッチ
:first-letter疑似要素 E:first-letter E要素の1文字目にマッチ
:before疑似要素 E:before E要素の内容の直前に内容を挿入
:after疑似要素 E:after E要素の内容の直後に内容を挿入

セレクタのうち、全称セレクタかタイプセレクタに属性セレクタ、クラスセレクタ、IDセレクタ、疑似クラスが0個以上続いたものを、単純セレクタ(simple selector)と言います。属性セレクタ、クラスセレクタ、IDセレクタ、疑似クラスの順序は任意です。次の例は全て単純セレクタです。

単純セレクタは結合子(combinator)で連結することができます。結合子には空白文字類、">"、"+"の3種類があります。次の例は単純セレクタを結合子でつないだセレクタです。

セレクタにマッチしスタイルの適用対象となる要素を、セレクタの主体(subject)と言います。単純セレクタであればそのセレクタにマッチする要素が主体となります。結合子でつながれている場合、最後の単純セレクタにマッチする要素がそのセレクタの主体になります。

上の例ではどれもp要素が主体となることに注意してください。div要素はp要素を限定するための条件ではあっても、スタイルの適用対象にはならないのです。

複数のセレクタはカンマ(,)で区切ってグループ化することができます。次の例では三つのセレクタ("h1"と"p.classX"と"div p")をグループ化しています。

p, div.classX, div p { ... }

次に、上の表に挙げた各セレクタの働きを詳しく説明します。

全称セレクタ

全称セレクタ(universal selector)は"*"で示され、文書ツリー中の全ての要素にマッチします。全称セレクタの後に属性セレクタ、クラスセレクタ、IDセレクタ、疑似クラスが続くとき(つまり単純セレクタに全称セレクタ以外のセレクタが付いているとき)は、"*"を省略することができます。

* { ... } /* 全ての要素にマッチ */
*.classX { ... } /* class="classX"を持つ全ての要素にマッチ */
.classX { ... } /* 上に同じ */
*[title] { ... } /* title属性を持つ全ての要素にマッチ */
[title] { ... } /* 上に同じ */

タイプセレクタ

文書言語中の要素型名をそのまま記述したものをタイプセレクタ(type selector)と言います。タイプセレクタはその名前に一致する文書ツリー中の要素にマッチします。

p { ... } /* p要素にマッチ */
em { ... } /* em要素にマッチ */

子孫セレクタ

子孫セレクタ(descendant selector)は、文書ツリー中で特定の要素の下位にある要素(子孫)にマッチするセレクタです。Aの子孫であるBにマッチさせるには"A B"のように、それぞれの単純セレクタを空白文字類で区切ります。

div em { ... } /* div要素の子孫であるem要素にマッチ */
<div>div要素中の<em>em要素</em>にマッチ</div>
<div><p>div要素中のp要素中の<em>em要素</em>にもマッチ</p></div>

子供セレクタ

子供セレクタ(child selector)は、ある要素の直下にある要素(子)にマッチするセレクタです。Aの子であるBにマッチさせるには"A > B"と、それぞれの単純セレクタを">"で区切って記述します。

div > em { ... } /* div要素の子であるem要素にマッチ */
<div>div要素中の子である<em>em要素</em>にマッチ</div>
<div><p>div要素中のp要素中の<em>em要素</em>にはマッチしない</p></div>

隣接セレクタ

隣接セレクタ(adjacent sibling selector)は、ある要素の直後にある要素(兄弟)にマッチするセレクタです。"A + B"のように"+"で単純セレクタを区切ると、Aの直後にあるBにマッチします。このときマッチする主体はBであり、Aではありません。

h2 + p { ... } /* h2要素の直後にあるp要素にマッチ */
<h2>h2要素</h2>
<p>このp要素にマッチ</p>
<p>このp要素にはマッチしない</p>

クラスセレクタ

(X)HTMLではclass属性で要素にクラス名を与えますが、クラスセレクタ(class selector)を用いると特定のクラス名を持つ要素にセレクタをマッチさせることができます。クラスセレクタはピリオド(.)の後にクラス名を続けて記述します。

p.note { ... } /* class="note"であるp要素にマッチ */
<p class="note">このp要素にマッチ</p>

(X)HTMLのclass属性では、空白文字類で区切ってクラス名を複数与えることができます。複数クラス名を持つ要素にマッチさせるには、".クラス名"を複数列挙します。順番は任意です。

p.note.caution { ... } /* class属性に"note"と"caution"を持つp要素にマッチ */
<p class="note caution">このp要素にマッチ</p>

ちなみに(X)HTMLはなくXMLの場合はどうかというと、UAs may apply selectors using the period (.) notation in XML documents if the UA has namespace specific knowledge that allows it to determine which attribute is the "class" attribute for the respective namespace.)(5.8.3 Class selectors - Selectors)とされており、SVGMathMLなどUAが既知の規格なら使えるかもしれないようです。

IDセレクタ

(X)HTMLではid属性によって要素にユニークなIDを割り振ることができます。IDセレクタ(ID selector)は、文書ツリー中においてそのような方法で割り当てられた特定のIDを持つ要素にマッチします。IDセレクタは"#"の後にIDの値を続けて記述します。

p#myid { ... }
<p id="myid">このp要素にマッチ</p>

CSSではどの属性が要素のIDを特定するのかについては指定できません。XMLであればDTDでそれを判別できるのですが、ユーザーエージェントが常にDTDを読み取るとは限らず、IDセレクタが機能しないかもしれません。そのような恐れがあるときは、IDセレクタではなく属性セレクタを使うといいでしょう。

属性セレクタ

属性セレクタ(attribute selector)は文書ツリー中で特定の属性を持つ要素にマッチする要素です。属性セレクタには次の四通りの記述方法があります。

[att]
att属性を持つ要素にマッチする。値は関係しない。
[att=val]
att属性の値がvalである要素にマッチする。
[att~=val]
att属性が空白で区切られたリストになっており、その内の一つがvalである要素にマッチする。
[att|=val]
att属性がハイフンで区切られたリストになっており、その1番目がvalである要素にマッチする。

次の例はtitle属性を持つp要素にマッチします。

p[title] { ... } /* title属性を持つp要素にマッチ */
<p title="foo">この要素にマッチ</p>

次の例ではtitle="bar"であるp要素にマッチします。

p[title=bar] { ... } /* title=barであるp要素にマッチ */
<p title="bar">この要素にマッチ</p>

次の例ではclass属性に"hoge"を含むp要素にマッチします。前述のクラスセレクタと同じ働きをします。

p[class~=hoge] { ... } /* title=barであるp要素にマッチ */
<p class="foo bar hoge">この要素にマッチ</p>

HTMLではlang属性で言語を指定しますが、lang属性の値には"en"の他、"en-US"のようにハイフンで副コードが付けられていることがあります。"|="を使うと副コードによらずに言語ごとにスタイルを変えることができます。

p[lang|=en] { ... } /* 言語が英語であるp要素にマッチ */
<p lang="en">この要素にマッチ</p>
<p lang="en-US">この要素にもマッチ</p>

言語によって要素にマッチさせるには、これ以外に:lang疑似クラスを使う方法があります。

疑似クラス

上述のセレクタは要素の属性や文書ツリー上における位置によって要素を特定しますが、疑似クラス(pseudo-class)はそれ以外の特性によって要素のマッチングを行います。例えば、ハイパーリンクが訪問済みであるかは文書ツリーからは判別できませんが、それを特定するのが疑似クラスです。

疑似クラスには次のようなものがあります。

:first-child疑似クラス
ある要素の子要素の中で最初に現れる要素にマッチします。
div > p:first-child { ... } /* div要素の1番目の子であるp要素にマッチ */
<div>
<p>この要素にマッチ</p>
<p>この要素にはマッチしない</p>
</div>

注意しなければならないのは、E:first-childとしたときにマッチするのは「ある要素の中で最初に現れるEである要素」ではなく「ある要素の中で1番目にあり、かつEである要素」だということです。上の規則は次の例のp要素にはマッチしません。p要素はdiv要素の2番目の子要素だからです。

<div>
<h2>h2要素</h2>
<p>この要素にはマッチしない</p>
</div>

ハイパーリンクの状態を表す疑似クラスには、次の二つがあります。

未訪問のハイパーリンクに適用されます。
:visited疑似クラス
訪問済みのハイパーリンクに適用されます。

これらの状態は同時に起こりえず、相互排他的です。ハイパーリンクのスタイルを指定するときには、両方使うべきでしょう。

a:link { ... } /* 未訪問のとき */
a:visited { ... } /* 訪問済みのとき */

次の疑似クラスは、マウスポインタの移動、キーボードによる選択などのユーザーの行動に対するレスポンスとして、動的にスタイルを変化させることができます。

:hover疑似クラス
マウスポインタなどによって指し示された要素に適用されます。
:active疑似クラス
マウスボタンが押される、Enterキーが押されるなどしてアクティブになった要素に適用されます。
:focus疑似クラス
タブなどでフォーカスが当てられた要素、入力可能になったテキストボックスなどに適用されます。

これらの状態は同時に起こりえます。そのときは、ひとつの要素に複数の疑似クラスがマッチすることになります。

CSSでは、どの要素が上述の状態になるのか、どのような操作で上述の状態になるのかといった点は定義されていません。ユーザーエージェントの実装によります。

これらの疑似クラスを使ってハイパーリンクのスタイルを変更するときは、記述の順序に注意が必要です。詳細は:hover疑似クラスは宣言順序に注意が必要です - Web標準普及プロジェクトを参照してください。

言語を指定する方法は、HTMLのlang属性、XMLのxml:lang属性、またmeta要素やHTTPヘッダなど様々に存在しますが、:lang疑似クラスを使うと汎用的にテキストの言語によって要素を特定することができます。

:lang疑似クラス
:lang(C)とすると内容がCという言語で書かれている要素にマッチします。

:lang疑似クラスは属性セレクタの"|="と同じように、副コードに関係なく言語を指定できます。

*:lang(en) { ... } /* 英語 */
*:lang(ja) { ... } /* 日本語 */

:lang(en)[lang|=en]の違いは、:lang(en)は内容が英語で書かれていさえすればマッチするのに対し、[lang|=en]はlang属性を持たなければマッチしないという点にあります。次の例では、body要素は両者ともにマッチしますがp要素には:lang(en)しかマッチしません。

<body lang="en">
<p>[lang|=en] doesn't match this element</p>
</body>

また、当然次の例のp要素にも[lang|=en]はマッチしません。

<p xml:lang="en">[lang|=en] doesn't match this element</p>

疑似要素

段落の1行目、1文字目など、文書ツリーからは特定できない要素を表すのが疑似要素(pseudo-element)です。

:first-line疑似要素
ブロックレベル要素の1行目に適用されます。

:first-line疑似要素が適用できるのは、ブロックレベル要素、inline-block、table-caption、table-cellのみです。次の例はp要素が生成するボックスの1行目にマッチします。

p:first-line { ... }

疑似要素はソース文書中には直接記述されません。そのため、次のようなHTML文書が

<p>
このように長い段落はレンダリングされる際に
いくつかの行に分割されます。1行目には架空
のタグが挿入されたかのように扱われます。
</p>

以下のようにレンダリングされたとしたら、

このように長い段落はレンダリングされる際にいくつかの
行に分割されます。1行目には架空のタグが挿入されたか
のように扱われます。

元のソース文書中には"<p:first-line>"、"<p:/first-line>"という架空のタグが存在していると考えます。

<p>
<p:first-line>このように長い段落はレンダリングされる際に
いくつかの</p:first-line>行に分割されます。1行目には架空
のタグが挿入されたかのように扱われます。
</p>
:first-letter疑似要素
ブロックレベル要素の1行目の1文字目に適用されます。画像など別の内容が文字より前にあるときはマッチしません。約物("「"等)が先行するときは、1文字目にそれを含んでマッチします。

:first-letter疑似要素が適用できるのは、block、list-item、inline-block、table-caption、table-cellのみです。次の例はp要素の1文字目にマッチします。

p:first-letter { ... }

:first-letter疑似要素も:first-line疑似要素と同じように、元のソース文書中に架空のタグがあるように考えます。例えば、次のHTMLは

<p>段落の始まり…</p>

次のように"<p:first-letter>"、"</p:first-letter>"が存在していると考えられます。

<p><p:first-letter>段<p:first-letter>落の始まり…</p>
:before疑似要素
ある要素内容の直前を表します。
:after疑似要素
ある要素内容の直後を表します。

:before疑似要素、:after疑似要素はcontentプロパティと組み合わせて要素の内容の前後に内容を生成するために使います。詳しくは内容生成を参照してください。

Information