CSS case insensitive attribute selector

Today I learnt that you can specifify case-insensitivity with CSS attribute selectors with the `i` flag.

Apr 9, 2022 | Read time 6 minutes

🔔 Table of contents

Today I learnt that you can specifify case-insensitivity with CSS attribute selectors with the i flag.

a[title="bar" i] { /* ... */}

What are attribute selectors?

When styling elements, you can use attribute selectors to style elements that matches the value of attributes. You can even not specify a value, but the mere presense of the attribute as well.

Some examples are as follows.

/* Selects all links with title attribute. E.g <a title>Link</a>*/
a[title] {
  color: purple;
}

/* Selects all links with an href matching "https://example.org" 
E.g <a href="https://example.org">Link</a> */
a[href="https://example.org"] {
  color: green;
}

/* Selects all links with an href containing "google"  
E.g <a href="https://google.com">Link</a>*/
a[href*="google"] {
  font-size: 2em;
}

/* Selects all links with an href ending ".org" 
E.g <a href="https://example.org">Link</a>*/
a[href$=".org"] {
  font-style: italic;
}

/* Selects all links whose class attribute contains the word "logo" 
E.g <a class="logo1">Link</a> */
a[class~="logo"] {
  padding: 2px;
}

Case sensitive by default

Most CSS selectors are case sensitive by default, but the properties and values that it specifies is case-insenstive. Weird right?

Well this is because CSS respects the case sensitivity of the document language (https://www.w3.org/TR/selectors-4/#case-sensitive).

This means that the document language element names, attribute naes, and attribute values (since these depend on the document language)

For example, we have the following three divs:

<div id="green">Hello.</div> <!-- This text is green -->
<div id="Green">Hello.</div> <!-- This text is green -->
<div id="gReEn">Hello.</div> <!-- This text is black by default -->
#green { color: green; }
#Green { cOlOr: Green; } /* Match second div and styled since properties and values are case-insensitive */
#greeN { color: green; } /* No match */

The first div will be green because it matches the first style.

The second div text will also be green because it matches the selector #Green. Keep in mind that properies (cOlOr) and values (Green) are case-insensitive!

By default, attribute selectors must treat the following attribute values as case-insensitive.

https://html.spec.whatwg.org/multipage/semantics-other.html#selectors

  • accept
  • accept-charset
  • align
  • alink
  • axis
  • bgcolor
  • charset
  • checked
  • clear
  • codetype
  • color
  • compact
  • declare
  • defer
  • dir
  • direction
  • disabled
  • enctype
  • face
  • frame
  • hreflang
  • http-equiv
  • lang
  • language
  • link
  • media
  • method
  • multiple
  • nohref
  • noresize
  • noshade
  • nowrap
  • readonly
  • rel
  • rev
  • rules
  • scope
  • scrolling
  • selected
  • shape
  • target
  • text
  • type
  • valign
  • valuetype
  • vlink

For example, if you have a selector:

[bgcolor="#ffffff"] 

This will match any HTML element with a bgcolor attribute with values including #ffffff, #FFFFFF and #fffFFF.

Any values that is not on this list, the values are treated as case-sensitive.

How to select attributes and ignore case

One thing to note from the above examples is that attribute selectors are case sensitive. We can get around this default setting by using the i or I flag at right before the closing backet ]

This is useful when we are trying to select a class name.

For example - lets say we have the following buttons with the btnPrimary class:

<button class="btnPrimary">Apply</button> <!-- red button -->
<button class="btnprimary">Apply</button> <!-- green button -->

You can specify i or I after the attribute selector to indicate that you want to ignore case:

[class*="btnPrimary" i] { /* matches btnPrimary and btnprimary */
  border: 10px solid green;
}

[class*="btnPrimary"] { /* matches only btnPrimary */
  border-color: red;
}

The above, we are using a wildcard to select any class that has btnPrimary in the class name. In the first example, we specify the i flag and this will ignore case.

The second example, we do not apply the i flag and it will select with case sensitivity.

Keep in mind, this applies for characters within the ASCII range (i.e. [a-z] and [A-Z] are equivalent).

Browser Support

When applying the case insensitive flag to attribute selector, keep in mind the browser support. From https://caniuse.com/css-case-insensitive we can see that support for this is not available with IE11 or lower.

By default the selector is case-sensitive but this is based on the HTML document language.

If you are using a document language that has case-insensive by default or if you want to force case sensitivity with attribute selectors, we can use the s or S flag. Similar to the case insensitive flag, this applies for characters within the ASCII range (i.e. [a-z] and [A-Z] are equivalent).

Final thoughts

Using attribute selectors and specifying to select with case-insensitivity is a great way to style elements that you do not know the case in advance.

For example, the HTML might be coming dynamically from some other system that you do not have control with.

Some things to keep in mind when using case-insensitive selectors is that:

  • check the browser support. As an example, IE11 or versions below that do not support this flag.
  • this applies to ASCII characters only (i.e. [a-z] and [A-Z] are equivalent).

Additionally since this is a pattern matching CSS selector feature, the performance can deteriorate, so use them sparingly.

👋 About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember 😅)

Follow along on Twitter , GitHub and YouTube