DEV Community

allround.io
allround.io

Posted on • Originally published at allround.io

The power of CSS attribute selectors

Besides the obvious utility of selecting elements with an exactly matching data attribute, there are a lot more things we can achieve with CSS attribute selectors.
In general, the attribute selector can target any attribute that's attached to an HTML element. By default, the selector is case sensitive and has a lower specificity than id's and classes.

Here's an attribute selector in its simplest form, selecting every anchor element that has an href attribute — regardless of the actual href URL:

a[href] {
    /* ... */
}
Enter fullscreen mode Exit fullscreen mode

If we want it to be more specific about which href to target, we can explicitly pass the URL to the attribute selector like this

a[href="https://specific-url.com"] {
    /* ... */
}
Enter fullscreen mode Exit fullscreen mode

One of the latest specs changes introduced a new flag for attribute selectors, which allows us to make the matching case insensitive, by adding an i after our selector. This is fairly well supported and works across all modern browsers, except IE11.

a[href="https://specific-url.com" i] {
    /* matches <a href="https://SpEciFic-url.com"></a> ... */
}
Enter fullscreen mode Exit fullscreen mode

Special types of attribute selectors

Besides matching an attribute with an existing attribute or a specific value, we can use other types of attribute selectors to achieve partial matching on the
value of an attribute. These selectors can also be combined to match very specific elements.

CSS attribute contains

Using the wildcard operator * we can match any element that has an attribute containing the given string in any form.
That means the example below would match the exact string value but also something value something as well as somethingvaluesomething.

[data-attribute*="value"] {
  /* ... */
}
Enter fullscreen mode Exit fullscreen mode

CSS attribute starts with

If we want to look for an attribute whose value starts with a given string, we can use the ^ operator lie below.
In that case, we'd only match value something and valuesomething but not something value.

[data-attribute^="value"] {
  /* ... */
}
Enter fullscreen mode Exit fullscreen mode

CSS attribute ends with

Conversely to looking for matched at the start, we can also look at the very end of an attribute's value by useing the $ operator.
We'd match something value but not value something. This is especially interesting because we know that files always have a certain extension and by passing
the full name into a data-attribute, we'd be able to match elemenets that represent PDF documents like this a[href$="pdf"].

[data-attribute$="value"] {
  /* ... */
}
Enter fullscreen mode Exit fullscreen mode

CSS attribute is in space-separated or dash-separated lists

There are two selectors that allow us to specifically look for matches inside lists, where one is only matching when the value is dash-separated | and the other operator
matches everything inside a space-separated list ~. Especially the space separation can also be achieved with other operators mentioned above.


[data-attribute~="value"] {
  /* matches eg. <li data-years="thor value loki">...</li> */
}

[data-attribute|="value"] {
  /* matches eg. <li data-years="value-2021">...</li> */
}
Enter fullscreen mode Exit fullscreen mode

Combining attribute selectors

Of course, we can also use multiple attribute selectors simultaneously to select specific elements. This can be especially handy when the HTML
provides us with enough info to create different styles only through our attributes. Let's say we want to give icons to every file download link
on a site and a special icon to PDFs. We can combine the contains and ends with selectors to select all files and then specifically find all PDFs.

a[href*="/downloads"] {
    /* file is in /downloads directory */
}

a[href*="/downloads"][href$="pdf"] {
    /* file is in /downloads directory */
    /* AND ends with pdf */
}
Enter fullscreen mode Exit fullscreen mode

Negating the attribute selector with :not

All the attribute selectors above can also be combined with the CSS :not selector, so we could also take our example above and find all files
that are inside the downloads directory but are specifically not PDF files.

a[href*="/downloads"]:not([href$="pdf"]) {
    /* file is in /downloads directory */
    /* AND ends NOT with pdf */
}
Enter fullscreen mode Exit fullscreen mode

Using attribute selectors in Javascript

Just like using regular class and id selectors, we can also utilize all of the above selectors when writing JavaScript to select DOM elements.

let team = document.querySelector('img[src*="team"]');
Enter fullscreen mode Exit fullscreen mode

Discussion (0)