Complete CSS Course Module 6: Intermediate: The Cascade and Advanced Selectors

CSS Attribute Selectors

  • Beginner
  • Lesson 6.4
  • 4 min read
  • 27 of 77 in the course

In short

CSS attribute selectors target elements by their HTML attributes, like [type="email"] or links whose href starts with "https", so you can style things without adding extra classes. What is an attribute selector?

CSS attribute selectors target elements by their HTML attributes, like [type="email"] or links whose href starts with "https", so you can style things without adding extra classes.

What is an attribute selector?

HTML elements have attributes: extra information written inside the opening tag, like href, type, alt or target. An attribute selector uses square brackets to select elements based on those attributes.

There are two basic forms:

  • [attr] – the element has this attribute, with any value.
  • [attr="value"] – the attribute has exactly this value.
<form class="contact">
  <input type="text" placeholder="Your name">
  <input type="email" placeholder="Email" required>
  <input type="submit" value="Send">
</form>
.contact input[type="text"],
.contact input[type="email"] {
  border: 1px solid #d1d5db;
  padding: 10px;
  border-radius: 6px;
}

.contact input[type="submit"] {
  background: #2563eb;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 6px;
}

.contact input[required] {
  border-left: 4px solid #f59e0b;
}

The text and email fields get a light border and rounded corners. The submit button looks like a blue button. The required email field also gets an orange stripe on its left side, so users can see it must be filled in. You did not add a single class to the inputs.

Each attribute selector adds 0-1-0 to specificity, the same as a class.

Matching part of a value: ^=, $= and *=

Sometimes you only know part of the value. These operators match pieces of it:

SelectorMatches when the value...Example
[attr^="v"]starts with va[href^="https"]
[attr$="v"]ends with va[href$=".pdf"]
[attr*="v"]contains v anywherea[href*="youtube"]
[attr~="v"]contains the word v in a space-separated list[class~="card"]
[attr|="v"]is exactly v, or starts with v-[lang|="en"]

An easy way to remember them: ^ is the start of a line in many programming tools, $ is the end, and * means "anywhere".

The |= selector is mostly used for language codes: [lang|="en"] matches lang="en" and also "en-" followed by anything, like lang="en-US".

Tip: Add a space and the letter i before the closing bracket to ignore upper and lower case. a[href$=".pdf" i] matches both report.pdf and REPORT.PDF.

A common use is to show users where a link will take them. Here we mark external links and add a small label to download links:

<ul class="resources">
  <li><a href="/lessons/flexbox">Flexbox lesson</a></li>
  <li><a href="https://developer.mozilla.org/">MDN Web Docs</a></li>
  <li><a href="/files/css-cheatsheet.pdf">CSS cheat sheet</a></li>
  <li><a href="/files/starter-kit.zip">Starter kit</a></li>
  <li><a href="mailto:hello@example.com">Email us</a></li>
</ul>
.resources a {
  color: #2563eb;
}

.resources a[href^="https://"]::after {
  content: " ↗";
}

.resources a[href$=".pdf" i]::after {
  content: " (PDF)";
  color: #dc2626;
  font-size: 0.85em;
}

.resources a[href$=".zip" i]::after {
  content: " (ZIP)";
  color: #7c3aed;
  font-size: 0.85em;
}

.resources a[href^="mailto:"] {
  font-style: italic;
}

The MDN link shows a small arrow, which tells users it goes to another website. The cheat sheet shows a red "(PDF)" label and the starter kit a purple "(ZIP)" label. The email link is in italics. If you add more PDF links later, they get the label automatically.

Note: Links to your own site that use the full address (like https://yoursite.com/about) would also get the arrow. To exclude them, add a second rule such as a[href^="https://yoursite.com"]::after { content: none; }.

More useful attribute selectors

Attribute selectors are also handy for accessibility and state attributes:

img:not([alt]) {
  outline: 4px solid red;
}

a[target="_blank"] {
  text-decoration-style: dashed;
}

button[aria-pressed="true"] {
  background: #1e40af;
  color: white;
}

[data-status="sold-out"] {
  opacity: 0.5;
}

The first rule is a debugging helper: any image missing its alt text gets a big red outline, so you notice it right away. Links that open in a new tab get a dashed underline. A toggle button with aria-pressed="true" looks pressed. And any product card with data-status="sold-out" fades out. Custom data- attributes are a clean way to describe the state of an element in HTML and style it in CSS. You can find the full list of options on MDN's attribute selectors page.

Common mistake: Forgetting the quotes or adding spaces, like [type = email]. Spaces are allowed but make code harder to read, and values with special characters such as / or . need quotes. Always write [type="email"].

Practice exercise

Make a list of six links: two to other websites, one to a .pdf, one to a .docx, one tel: phone link and one normal page on your site. Use only attribute selectors (no classes on the links) to give each kind its own small label or color.

Hint: phone links start with tel:, so a[href^="tel:"] will match them. Use ::after with content for the labels.

Key takeaways

  • Attribute selectors use square brackets, like [type="email"].
  • [attr] checks that an attribute exists; [attr="v"] checks for an exact value.
  • ^= means "starts with", $= means "ends with" and *= means "contains".
  • Add a space and i inside the brackets to match without caring about letter case.
  • They are great for external links, file-type labels, form inputs and data- attributes.