PR
TIPS

Causes and Solutions When CSS Backward Compatibility Doesn't Work

Even when using the CSS attribute selector ($=), the styles may not apply as expected. In particular,classwhen using a trailing match for attributes, there are often cases where the styles don’t match even though they appear to be correct. In this article,css 後方一致 効かないwe’ll outline the first things to check and safe alternatives for practical use.

To put it simply, since the trailing match checks “the very end of the attribute value,”classit does not work well with attributes that have multiple values separated by spaces, such asclassIf you’re targeting such attributes, start by using class selectors.classnameor a word-match[class~="classname"].

First, the conclusion

When trailing matches do not work, please check the following three points first:

  • Is the target attribute reallyclass,idordata-*,
  • Check whether the end of the attribute value matches exactly
  • classFor attributes, use class selectors or exact matches rather than partial matches

In other words,$=it’s often not that the code itself is broken, but rather that the selector is chosen incorrectly. If you miss this point, debugging will take a long time.

A typical example where trailing matches don’t work

For example, consider the following code.

[class$="section_tpLYew"] {
  border: 1px solid #000;
}

Suppose the HTML looks like this:

...

In this case,classthe entire attribute value issection_section_tpLYew section. The end issection, so[class$="section_tpLYew"]it does not match.

What often causes confusion here is that, although the string appears tosection_tpLYew, but the back-end match checks whether the string ends with it, not whether it contains it.

Understanding how lookbehind works

A positional match only checks the end of the attribute value

The attribute selector$=selects only elements whose attribute values end with the specified string.[id$="section"]For example,id="top-section"orid="section"will match, butid="section-top"does not match.

This behavior is simple, but in practice, it’s easier to miss than you might think. Matching conditions can break down for reasons such as multiple class names, additional identifiers at the end, or changes in order caused by JavaScript.

The `class` attribute accepts multiple values separated by spaces

classThe attribute is not a single value, but a collection of class names separated by spaces. For example,class="section_section_tpLYew section", multiple classes are listed.

In this case,$=the browser does not examine “each individual class” but compares the entire attribute value as a single string. Therefore, simply adding a different class at the end will cause the match to fail.

In other words,classa case-insensitive match against this is a fragile approach when classes are added or their order is changed. This is particularly prone to breaking when the HTML source is generated by WordPress, a builder, CSS Modules, JavaScript, etc.

How to troubleshoot why it doesn’t work

If you feel that “reverse matching isn’t working,” you can easily find the cause by troubleshooting in the following order.

  • Select the target element in the developer tools and check the actual attribute value
  • Check if the selector targetsclassis intendedidCheck
  • Check if there are any trailing spaces or other classes
  • Check if it’s being overridden and verify the priority
  • Check for cached or outdated CSS

The last two points aren’t strictly about trailing matches, but they often come up together in practice. Even if the selector is correct, if another rule takes precedence, it may appear as though it isn’t working.

Use a different syntax for classes

The safest approach is to use class selectors

If the target can be identified by a single class, the top priority is.classname. Since this does not depend on the end of the entire attribute value, it is the most readable and least prone to breaking.

.section_tpLYew {
  border: 1px solid #000;
}

Even if an element has multiple classes,.section_tpLYewit will match that specific class.class="section_section_tpLYew section"A structure like this is also fine.

For exact word matching,[class~="..."]use

classIf you only want to match a single word within an attribute,[class~="classname"]is suitable. This checks whether the specified word is included in any of the space-separated classes.

[class~="section_tpLYew"] {
  border: 1px solid #000;
}

However, this is limited to cases where “the class name exists as a single word.”section_tpLYew-extraIf you want to capture derived names like$=you need to*=you’ll need to reconsider how you use them.

If you absolutely must use lookbehind, narrow down the scope

The only situation where you might use a trailing match is when you can manage the naming conventions for attribute values yourself. For example,data-section="tpLYew"you can prepare a separate attribute that is easy to match at the end, as shown here.

...
[data-section$="tpLYew"] {
  border: 1px solid #000;
}

In this way, trailing matchesclassis better suited fordata-*. In practice, it’s more stable not to force your HTML class design to fit CSS constraints.

A quick way to check

By standardizing your troubleshooting steps, you can quickly identify why trailing matches aren’t working.

  • Select the target element in the developer tools and check the actual attribute value
  • Change the CSS selector to.classnameand check if the element is selected
  • If there are multiple classes,[class~="classname"]try replacing it with
  • Check the priority to see if another rule is being applied to the same element
  • Check the loading order of CSS files and the cache

Especially in WordPress, CSS from themes, plugins, and blocks can overlap. It’s not uncommon for what you thought was a back-matching issue to actually be caused by a different rule taking precedence.

Common Misconceptions

Partial matches do not guarantee a match

[class$="tpLYew"]It is not the case thattpLYewit’s not enough for the string to appear anywhere in the text. It must be at the end. If it’s only contained in the middle, it won’t match.

The match fails if the order of class names changes

class="section_tpLYew section"andclass="section section_tpLYew"can result in different back-matching outcomes. If the order in which classes are added is not guaranteed, back-matching is unstable.

They are different attributes even if they look similar

idandclasshave different roles.[id$="section_tpLYew"]The situations where[class$="section_tpLYew"]are distinct. If you confuse the target attributes, the selector will not match at all.

Summary

When CSS suffix matching doesn’t work, the quickest solution is to go back to the basics: “it checks the end of the attribute value.” In particular,classattributes can have multiple class names, making them incompatible with suffix matching.

In practice,.classname, and use[class~="classname"]. Only when trailing matches are absolutely necessary should youdata-*limit it to elements like attributes where naming conventions are easier to control for more stable results.

If you feel it’s “not working,” check not only the selector syntax but also the actual HTML attribute values, the order of classes, any overriding rules, and even the cache, in that order. By isolating the cause, you can reduce unnecessary trial and error.

Comment

Copied title and URL