CSS — Attr Selectors
Select by attribute, not class
Any HTML attribute can be a styling hook:
/* has the attribute at all */
[target] {
color: purple;
}
/* exact value */
input[type="text"] {
border: 1px solid #ccc;
}
a[href^="https://"] { … } /* starts with */
a[href$=".pdf"] { … } /* ends with */
img[alt*="cat"] { … } /* contains */
The seven operators
| Syntax | Matches when… |
|---|---|
[attr] | attribute exists (any value) |
[attr="val"] | exactly val |
[attr~="val"] | one of several space-separated words equals val |
[attr|="en"] | equals val OR starts with val- (language codes) |
[attr^="val"] | begins with val |
[attr$="val"] | ends with val |
[attr*="val"] | contains val anywhere |
Case-insensitive variant: [attr="val" i].
Everyday uses
External links get an icon
a[href^="http"]::after {
content: " ↗";
font-size: 0.85em;
}
File-type links
a[href$=".pdf"]::after { content: " (PDF)"; color: crimson; }
a[href$=".doc"]::after { content: " (DOC)"; }
(Users see the file type before clicking — accessibility and UX in two lines.)
Form fields by type
input[type="email"] { border-color: teal; }
input[type="submit"] {
background: teal;
color: white;
cursor: pointer;
}
The data-attribute superpower
data-* attributes are your custom metadata channel:
<div class="alert" data-variant="warning">Check your input</div>
<button data-loading="true">Save</button>
.alert[data-variant="error"] { background: #fee2e2; }
.alert[data-variant="warning"] { background: #fef3c7; }
.alert[data-variant="success"] { background: #dcfce7; }
button[data-loading="true"] {
opacity: 0.6;
pointer-events: none; /* block clicks while loading */
}
JavaScript flips one attribute; CSS renders all states — the cleanest JS↔CSS contract there is:
btn.dataset.loading = "true"; // dataset maps to data-*
Attribute selectors vs classes
| Use classes for | Use attribute selectors for |
|---|---|
| Primary design system hooks | State (data-loading, aria-*) |
| Named components | Type distinctions (input[type=…]) |
| Everything you control | Third-party/legacy markup you can't edit |
Attribute selectors have class-level specificity — they combine cleanly with your existing system.
Performance note: fine on modern engines. Avoid absurd patterns like
[class*="btn"]matching everything containing "btn".
Mini Practice
- Mark every external link with a ↗ via
[href^="http"] - Add file-size hints after
.pdf/.ziplinks - Style three alert variants from one class + data-variant values
- Build a save button whose data-loading grays out and blocks clicks
- Case-insensitive search:
a[href*="GITHUB" i] - Refactor one state class toggle into a data-attribute toggle
Next: specificity →
Related Topics
Frequently Asked Questions about Attr Selectors
What is Attr Selectors in CSS?
Attr Selectors is a fundamental concept in CSS. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn Attr Selectors?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Attr Selectors.
Why is Attr Selectors important in CSS?
Attr Selectors is essential for CSS development. Understanding this concept will help you write better code and solve real-world problems more effectively.