You will be able to style elements by matching parts of attribute values, such as links ending in .pdf or images whose src contains thumb, without adding extra classes.
What it is
Advanced attribute selectors let CSS match elements based on the value of an attribute, not just its presence. Instead of writing [href] for any link with an href, you can test whether the value starts with, ends with, or contains a substring. The common operators are ^= for prefix, $= for suffix, and *= for substring. Related selectors include = for exact match, ~= for whitespace-separated word match, and |= for hyphen-separated value match.
The mental model is simple: the selector asks, “Does this attribute value look like this?” For example, a[href$=".pdf"] means “select anchors whose href ends with .pdf.” This is useful when markup is generated by a CMS, analytics tool, or component system and you cannot easily add classes.
Why it matters
- It styles file-type links, such as PDFs, ZIPs, or DOCX files, without editing each link.
- It targets images, icons, or avatars by filename patterns, such as
thumb,avatar, orbanner. - It supports data attributes, such as
[data-theme^="dark"], for component states. - It reduces class proliferation when the attribute already carries semantic information.
- It helps debug or enhance third-party markup that you cannot change directly.
Syntax or steps
The smallest useful pattern is:
element[attr operator="value"] { property: value; }
Choose the operator based on where the match should occur:
^=matches the beginning of the attribute value.$=matches the end of the attribute value.*=matches anywhere inside the attribute value.
Quote the value when it contains punctuation, spaces, or characters that are not safe as a CSS identifier. For example, use href$=".pdf", not href$=.pdf.
Example
<a href="/files/report.pdf">Annual report</a>
<a href="/files/notes.txt">Notes</a>
<img src="/images/thumb-cat.jpg" alt="Cat thumbnail">
<img src="/images/full-cat.jpg" alt="Full cat image">
a[href^="/files/"] {
color: #0b6;
}
a[href$=".pdf"] {
font-weight: bold;
}
img[src*="thumb"] {
border: 1px solid #999;
}
Part by part:
a[href^="/files/"]selects links whosehrefstarts with/files/, making internal file links green.a[href$=".pdf"]selects links whosehrefends with.pdf, making PDF links bold.img[src*="thumb"]selects images whosesrccontainsthumbanywhere, adding a border to thumbnails.
Common mistakes
- Assuming suffix matching handles query strings.
a[href$=".pdf"]will not matchreport.pdf?download=1. Usea[href*=".pdf"]if the extension may appear before a query string, or normalize URLs. - Using substring matching too broadly.
img[src*="thumb"]also matchesthumbnail,thumbprint, ormy-thumb.jpg. If that is unwanted, use a more specific pattern such assrc^="/images/thumb-". - Forgetting quotes. Values with dots, slashes, or spaces should be quoted.
[href^="/files/"]is safer than[href^=/files/]. - Expecting case-insensitive matching by default. Attribute values are matched case-sensitively in many contexts. If you need case-insensitive matching, use the supported
iflag, such as[href$=".PDF" i], and test in your target browsers.
When to use it
Attribute selectors are best when the attribute already contains the information you need. Class selectors are best when you want an explicit styling hook that does not depend on URL structure or generated filenames.
| Need | Use | Why |
|---|---|---|
| Style PDF links | a[href$=".pdf"] | The file type is already in the URL. |
| Style a component state | [data-state="open"] | The state is explicit and stable. |
| Style a design-system button | .btn-primary | Classes are intentional and less fragile than filenames. |
| Enhance third-party markup | img[src*="avatar"] | You may not be able to add classes. |
Practice
Guided exercise: write CSS that makes links ending in .zip bold and images whose src contains banner have a 2-pixel solid border.
a[href$=".zip"] {
font-weight: bold;
}
img[src*="banner"] {
border: 2px solid #333;
}
Challenge: select elements whose data-theme attribute starts with dark, such as dark-blue or dark-mode. Hint: use [data-theme^="dark"].
Quick check
Which selector matches an image whose src contains the word thumb anywhere in the value?
img[src*="thumb"]
Summary
Advanced attribute selectors let you match prefixes, suffixes, and substrings inside attribute values, which is useful for links, images, and data attributes. Use them when the attribute already carries meaningful information, and prefer classes when you need a stable, intentional styling hook.