PR
TIPS

CSSの後方一致が効かないときの原因と対処法

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の実際の属性値、クラスの順番、上書きされる別ルール、キャッシュまで順に確認してください。原因を切り分ければ、不要な試行錯誤を減らせます。

この記事を書いた人
Naokazu Yokoo

エンジニア歴20年以上。現在はWeb / AI領域で活動中。
開発環境・サーバー環境ともに速度と効率性を追求しています。

Follow Naokazu Yokoo
Follow Naokazu Yokoo

Comment

タイトルとURLをコピーしました