CSSで複数のクラスやIDに同じスタイルを適用させるとき、どうしてますか?
.class-name1,
.class-name2,
#id1 {
// 適用したいスタイル
}
こんな感じが多いと思います。
でも適用したいクラスやIDを羅列するのはコードが見にくくなるし、何よりめんどくさい・・・、ですよね?
そんなときに便利なのが部分一致!
今回は一括でスタイルを適用させられて、かつコードがスッキリする便利な「CSSによる部分一致」のお話です。
部分一致の基本
前方一致
前方一致は、要素のクラス名やIDの先頭が指定の文字列で始まっている場合に使えて、^=
という書き方をします。
例えば、[id^="section-"]
とすることで、ID名が
で始まる全ての要素にスタイルを適用させることができます。section
-
[id^="section-"] {
// 適用したいスタイル
}
後方一致
後方一致は、要素のクラス名やIDの末尾が指定の文字列で終わっている場合に使えて、$=
という書き方をします。
例えば、[class$="-item"]
とすることで、クラス名が-item
で終わる全ての要素にスタイルを適用させることができます。
[class$="-item"] {
// 適用したいスタイル
}
部分一致
部分一致は、要素のクラス名やIDに指定の文字列含まれている場合に使えて、*=
という書き方をします。
a[href*="/file/"] {
// 適用したいスタイル
}
a[href*="/file/"]
とすることで、aタグのhref属性で/file/
を含む要素にスタイルを適用させることができます。
この属性セレクタが一番柔軟にスタイルを適用させやすい反面、柔軟すぎるがゆえにスタイルを適用させたくない要素にも反映されてしまうリスクが高くなるデメリットがあります。
例えば、[class*="item"]
としたとき、
class="item"
class="item-list"
class="main-item"
といった、意味合いが違う要素にも同じスタイルが反映されてしまいますので注意が必要です。
部分一致(単語一致)
こちらも部分一致ですが、先ほどの部分一致よりも厳格なチェックが行われ、要素のクラス名やIDに指定の“単語”が含まれている場合に使えて、~=
という書き方をします。
[class~="logo"] {
// 適用したいスタイル
}
「*=」と「~=」の違いは?
*=
と違いがよく分からないと思いますので、下の例をご覧ください。
<!-- 「~=」が適用される例 -->
<a class="logo">Logo</a>
<a class="header logo footer">Logo</a>
<!-- 「~=」が適用されない例 -->
<a class="logotype">Logotype</a>
<a class="logomark">Logo</a>
適用されるものとされないもので何が違うかをこの例でいうと、logo
という単独の単語であるかどうか、ということです。
つまり、logotype
だとlogotype
という単語として認識されてしまい、logo
という単語とは一致しないということになってしまいます。
言ってしまえば、*=
は指定の文字列を含む部分一致、~=
はほぼ完全一致になります。
部分一致セレクタ早見表
つらつらと書いてしまいましたので、パッと見で知りたい方は早見表をどうぞ!
種類 | 記法 | 使用例 | 適用される要素 |
---|---|---|---|
前方一致 | ^= | section[id^="section-"] | ID名の始めがsection- から始まるsection タグ |
後方一致 | $= | li[class$="-item"] | クラス名の始めが-item から始まるli タグ |
部分一致 | *= | a[href*="/file/"] | リンクのパスに/file/ を含むa タグ |
部分一致(ほぼ完全一致) | ~= | img[class~="logo"] | クラス名にlogo が完全一致で含まれるimg タグ |
便利だけどこんな落とし穴も
部分一致は柔軟で使い勝手のいい方法ですが、使う前にいくつか考慮する点があります。
前方一致と後方一致は属性値全体でチェックされる
「どういうこと?」と思うところですが、次の例をご覧ください。
<style>
[class^="content"] {
color: red;
}
</style>
<h2 class="title content-main">タイトル</h2>
<div class="meta content-sub">カテゴリー</div>
<div class="content">この記事のコンテンツがここに入ります。</div>
3つすべてのdivタグにcontent
から始まるクラス名が含まれているので、すべて文字色が赤になると思われますが、実は1つしかスタイルは反映されません。
「content
~ってクラス名と前方一致してるじゃないか!」と思いますが、タグに設定された属性値全体と前方一致しているかどうかでチェックされます。
つまり、[class^="content"]
だったらclass="content~"
で始まらないと一致したとみなさないよ、ということです。

「前方一致/後方一致でスタイルを指定してるのに、なぜか効かない💦」ということも・・・。
どのようになるか、実際の表示をご覧ください。
See the Pen Untitled by mimihokuro (@mimi_hokuro) on CodePen.
上記の例ですべてにスタイルを当てたい場合は部分一致(*=
)で指定するか、属性値の並び順を変える必要があるので、使う場面には見極めが必要です。
パフォーマンスの問題
部分一致セレクタは非常に便利なのですが、コード量の多い大規模なDOM構造に対して使用する場合は、パフォーマンスにも注意が必要です。
特に*=
セレクタは、すべての要素をチェックするため、処理が重くなることがあります。
例えば、DOMが100個でCSSルールが50個あった場合、100×50=5,000回のマッチング処理が行われることになります😱
優先度の問題
部分一致セレクタは、他のセレクタと組み合わせて使用することができますが、優先度に注意が必要です。
優先度が高いセレクタがある場合、部分一致セレクタが期待通りに機能しないことがあります。
優先度は、IDセレクタが最も高く、次にクラスセレクタ、最後にタグセレクタの順で優先されます。
さいごに
いかがでしたでしょうか?
部分一致はちょっとしたときに便利なんですが、ビシッと指定しないと「こんなとこに何でこのスタイルが!?」ということも十分にあり得るので、部分一致は最終手段程度に考えてもらえるといいかな思います👍