CSS Attribute Selectors
You can already target elements by tag, class, id, and tree relationships. Attribute selectors add another lever: style elements because of an HTML attribute — a type on an input, an href on a link, or a custom data-* flag — without inventing a new class for every case.
What are CSS attribute selectors?
An attribute selector matches elements that have a named HTML attribute, optionally with a value test. You write the attribute name in square brackets: [attr]. Operators let you require an exact value or a partial match at the start, end, or middle of the value.
Operators at a glance
Start with these five patterns. They cover most everyday attribute-selector work.
📊 CSS attribute selector operators
| Pattern | Matches | Example |
|---|---|---|
[attr] |
Elements that have the attribute (any value) | a[target] |
[attr="value"] |
Attribute equals this value exactly | input[type="email"] |
[attr^="value"] |
Attribute value starts with this text | a[href^="https"] |
[attr$="value"] |
Attribute value ends with this text | a[href$=".pdf"] |
[attr*="value"] |
Attribute value contains this text anywhere | a[href*="docs"] |
Presence — [attr]
Square brackets with only a name mean “this attribute exists.” The value can be anything, including empty in some cases — presence is enough.
Presence — links that open a new tab
cssa[target] {
font-weight: 600;
}
When presence helps
Use [attr] for optional markup flags: links with target, images with alt you want to highlight in a review stylesheet, or elements carrying a data-state attribute regardless of its value.
Exact value — [attr="value"]
Equals (=) requires the whole attribute value to match. Quotes around the value are a safe habit, especially when the value has dashes or digits.
Exact value — email inputs
cssinput[type="email"] {
border: 1px solid #0f766e;
}
Class vs attribute for type
input[type="email"] is clearer than inventing .email-field when the HTML already carries the truth in type. Prefer a class when the same look must apply to elements that do not share that attribute.
Starts with — [attr^="value"]
The ^= operator matches when the attribute value begins with the given text. It is perfect for URL schemes and shared prefixes.
Starts with — secure links
cssa[href^="https"] {
color: #0f766e;
}
Ends with — [attr$="value"]
The $= operator matches when the value ends with the given text — useful for file extensions in href or src.
Ends with — PDF links
cssa[href$=".pdf"] {
font-style: italic;
}
Contains — [attr*="value"]
The *= operator matches when the text appears anywhere in the attribute value. It is powerful and easy to over-match — prefer ^= or $= when you know the position.
Contains — docs paths in links
cssa[href*="docs"] {
text-decoration: underline;
}
Practical habits
- Put quotes around attribute values in selectors (
type="email") for clarity and safety - Combine with a type selector when helpful:
input[type="search"]is clearer than a bare[type="search"]on a busy page - Attribute selectors are case-sensitive for many values in HTML documents served as text/html — match the casing in your markup
- Do not replace every class with attributes; use attributes when the HTML already exposes the fact you care about
Try it yourself
- Create a short page with three links: one
https://…URL, one ending in.pdf, and one path that includesdocs, plus<input type="email">and<input type="text">. - Add
a[href^="https"] { color: #0f766e; }and confirm only the secure link changes color. - Add
a[href$=".pdf"] { font-style: italic; }and confirm the PDF link becomes italic. - Add
input[type="email"] { border-color: #0f766e; }and confirm only the email field picks up the border. - Optional: try
a[href*="docs"]and notice it can match more URLs than a strict prefix or suffix.
Common mistakes
- Writing
[type=email]without quotes in stylesheets where tooling or values make quotes safer — prefer[type="email"] - Using
*=when you meant^=— contains matches the middle too, so unexpected links light up - Styling with
[class]instead of.namefor ordinary reusable design — classes stay the default for look-and-feel - Forgetting that exact
=needs the full value —type="text"will not matchtype="textbox" - Assuming attribute selectors ignore spelling —
hreflangandhrefare different attributes
Summary
- Attribute selectors match elements by HTML attributes inside
[ ] [attr]checks presence;[attr="value"]checks an exact value^=starts with,$=ends with,*=contains anywhere- Prefer the tightest operator that still expresses your intent
- Combine with element names when it makes the rule clearer
- Practice on real
hrefandtypeattributes, then refresh
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top