CSSで属性セレクタの後方一致($=)を使ったのに、思った通りにスタイルが当たらないことがあります。特に、class属性に対して後方一致を使うと、見た目は合っていそうなのに一致しないケースがよくあります。この記事では、css 後方一致 効かないときにまず確認すべき点と、実務で安全に使う代替案を整理します。
結論からいうと、後方一致は「属性値の末尾そのもの」を見るため、classのように複数の値が空白で並ぶ属性とは相性がよくありません。classを狙うなら、まずはクラスセレクタ.classnameや単語一致の[class~="classname"]を検討したほうが安全です。
まず結論
後方一致が効かないときは、次の3点を先に確認してください。
- 対象属性が本当に
classなのか、idやdata-*なのかを確認する - 属性値の末尾が完全一致しているかを確認する
class属性に対しては、後方一致ではなくクラスセレクタや単語一致を使う
つまり、$=自体が壊れているのではなく、セレクタの選び方が合っていないことが多いです。ここを外すと、デバッグが長引きます。
後方一致が効かない典型例
たとえば、次のような書き方です。
[class$="section_tpLYew"] {
border: 1px solid #000;
}
HTMLが次のようになっているとします。
<div class="section_section_tpLYew section">
...
</div>
この場合、class属性の値全体はsection_section_tpLYew sectionです。末尾はsectionなので、[class$="section_tpLYew"]には一致しません。
ここで混乱しやすいのは、見た目にはsection_tpLYewという文字列が含まれているのに、後方一致は「含まれているか」ではなく「末尾かどうか」を見ている点です。
後方一致の仕組みを整理する
後方一致は属性値の末尾だけを見る
属性セレクタの$=は、指定した文字列で属性値が終わる要素だけを選びます。[id$="section"]なら、id="top-section"やid="section"は一致しますが、id="section-top"は一致しません。
この挙動は単純ですが、実務では思った以上に外しやすいです。クラス名が複数つく、末尾に別の識別子が付く、JavaScriptで順番が変わる、といった理由で一致条件が崩れます。
class属性は空白区切りで複数入る
class属性は、1つの値ではなく空白区切りのクラス名の集合です。たとえばclass="section_section_tpLYew section"のように、複数のクラスが並びます。
このとき、$=は「クラスの1個1個」を見るのではなく、属性値全体を1つの文字列として比較します。なので、末尾に別クラスが付くだけで一致しなくなります。
つまり、classに対する後方一致は、クラス追加や順番変更に弱い書き方です。HTML生成元がWordPress、ビルダー、CSS Modules、JavaScriptなどの場合は、特に崩れやすいです。
効かない理由の切り分け方
「後方一致が効かない」と感じたら、次の順で切り分けると原因が見つかりやすいです。
- 開発者ツールで対象要素を選び、実際の属性値を確認する
- セレクタが
class向けなのかid向けなのかを見直す - 末尾にスペースや別クラスが付いていないか確認する
- 上書きされていないか、優先度も確認する
- キャッシュや古いCSSが残っていないか確認する
最後の2つは後方一致そのものの問題ではありませんが、実務ではよく混ざります。セレクタが正しくても、別のルールが勝っていれば見た目には効いていないように見えます。
classに対しては別の書き方を使う
もっとも安全なのはクラスセレクタです
対象が1つのクラスで特定できるなら、最優先は.classnameです。これは属性値全体の末尾に依存しないので、もっとも読みやすく、壊れにくいです。
.section_tpLYew {
border: 1px solid #000;
}
もし要素に複数クラスがあっても、.section_tpLYewはそのクラス単体に一致します。class="section_section_tpLYew section"のような構成でも問題ありません。
単語一致なら[class~="..."]を使います
class属性の中の1つの単語に一致させたいだけなら、[class~="classname"]が向いています。これは空白区切りのクラスのうち、指定した単語が含まれているかを見ます。
[class~="section_tpLYew"] {
border: 1px solid #000;
}
ただし、これも「そのクラス名が単独の単語として存在する」場合に限られます。section_tpLYew-extraのような派生名まで拾いたいなら、$=や*=の使い方を再検討する必要があります。
どうしても後方一致を使うなら対象を絞ります
後方一致を使う場面があるとすれば、属性値の命名規則を自分で管理できるときです。たとえば、data-section="tpLYew"のように、末尾一致させやすい属性を別に用意する方法があります。
<div class="section section_tpLYew" data-section="tpLYew">
...
</div>
[data-section$="tpLYew"] {
border: 1px solid #000;
}
このように、後方一致はclassよりも、命名を統制しやすいdata-*属性のほうが向いています。実務では、CSSの都合にHTMLのクラス設計を無理に合わせないほうが安定します。
すぐ試せる確認方法
調査の手順を固定しておくと、後方一致が効かない原因を短時間で特定できます。
- 開発者ツールで対象要素を選び、実際の属性値を確認する
- CSSセレクタを一度
.classnameに変えて、対象が取れているか確認する - クラスが複数あるなら
[class~="classname"]に置き換えてみる - 同じ要素に別のルールが当たっていないか、優先度を確認する
- CSSファイルの読み込み順とキャッシュを確認する
特にWordPressでは、テーマ側、プラグイン側、ブロック側のCSSが重なります。後方一致の問題だと思っていたら、単に別のルールが勝っていたというケースも少なくありません。
よくある誤解
部分的に含まれていれば一致するわけではありません
[class$="tpLYew"]は、tpLYewが文字列のどこかにあれば良いわけではありません。末尾にある必要があります。途中に含まれているだけでは一致しません。
クラス名の順番が変わると外れます
class="section_tpLYew section"とclass="section section_tpLYew"では、後方一致の結果が変わることがあります。クラスの追加順が保証されないなら、後方一致は不安定です。
見た目が似ていても別の属性です
idとclassは役割が違います。[id$="section_tpLYew"]が必要な場面と、[class$="section_tpLYew"]が必要な場面は別です。対象属性を取り違えると、セレクタは一切ヒットしません。
まとめ
CSSの後方一致が効かないときは、まず「属性値の末尾を見ている」という基本に立ち返るのが近道です。特にclass属性は複数のクラス名を持てるため、後方一致と相性が悪いです。
実務では、.classnameを優先し、必要なら[class~="classname"]を使います。どうしても末尾一致が必要な場合だけ、data-*属性など命名を統制しやすい対象に絞ると安定します。
「効かない」と感じたら、セレクタの文法だけでなく、HTMLの実際の属性値、クラスの順番、上書きされる別ルール、キャッシュまで順に確認してください。原因を切り分ければ、不要な試行錯誤を減らせます。


Comment