# Attribute Selectors

Attribute selectors reach elements by what their tags say, such as every checkbox, the song that's playing now, every link to a PDF or every link that leaves your site, with no class added.

Apprentice · CSS · Updated November 1, 2026

## After this lesson you can

- Write an attribute selector that matches by an attribute's presence or exact value
- Match part of an attribute's value with ^=, $= and \*=, such as links to PDFs or to other sites

## Key takeaways

- Square brackets select by attribute. `[href]` reaches every element that has an href, and `[type="checkbox"]` every element whose type is exactly checkbox.
- `^=` is read "starts with", `$=` "ends with" and `*=` "contains". They match part of an attribute's value.
- `a[href$=".pdf"]` reaches links to PDF files, and `a[href^="https://"]` reaches links that go to another site.
- Put the value in quotes. An attribute selector counts as much as a class in specificity.

A site's links sit side by side: one opens a page on the same site, one downloads a 4 MB PDF, one sends the reader off to someone else's site. A careful site marks the difference, so nobody waits for a download they didn't expect or loses their place. Nobody wants to add a class to every link by hand, and on a blog or a store the links are written by people who've never heard of your classes. The links already say where they go, in their `href`. **Attribute selectors** let CSS read it.

## What a tag already tells you

An **attribute** is the extra information in an opening tag, written as a name, an equals sign and a value in quotes: `type="checkbox"`, `href="road-trip-mix-lyrics.pdf"`. Here are two songs and the footer from the *Road Trip Mix* page:

```html
<li aria-current="true">
  <strong>Mile Marker 88</strong>
  <span>Coyote Radio</span>
  <span>4:05</span>
  <input type="checkbox" aria-label="Like Mile Marker 88">
</li>
<li data-rating="explicit">
  <strong>Gas Station Coffee</strong>
  <span>Lucky Static</span>
  <span>2:58</span>
  <abbr title="Explicit lyrics">E</abbr>
  <input type="checkbox" aria-label="Like Gas Station Coffee">
</li>

<footer>
  <p><a href="road-trip-mix-lyrics.pdf">Lyrics for every song (PDF)</a></p>
  <p><a href="https://example.com/road-trip-mix">Share this mix</a></p>
</footer>
```

Three attributes here are new:

- `aria-current="true"` tells a screen reader "this is the current one": the song that's playing now.
- `data-rating="explicit"` is a **data attribute**. Any attribute whose name starts with `data-` is one a site makes up for its own use, and the browser leaves it alone. This page uses it to mark songs with explicit lyrics.
- `<abbr>` marks an abbreviation, and its `title` says what the letters stand for.

## \[name\]: has the attribute

Square brackets around an attribute's name make an **attribute selector**. `[href]` reaches every element that has an `href`, whatever its value. Put a type in front to narrow it: `a[href]` is "a link that has an `href`".

```css
input[type="checkbox"] {
  width: 1.25rem;
  height: 1.25rem;
}

li[aria-current="true"] {
  background-color: #fff3c4;
}
```

With an equals sign and a value, the attribute must have *exactly* that value. The first rule sizes every checkbox and leaves any text box on the page alone. The second picks out the one song that's playing now.

## Quotes, capitals and specificity

- **Put the value in quotes.** `[type=checkbox]` works too, but a value with a dot, a space or a slash (`.pdf`, `https://`) only works in quotes, so quoting every value saves you from guessing.
- **Values match exactly, capitals included.** `[data-rating="Explicit"]` doesn't match `data-rating="explicit"`. Put `i` before the closing bracket to ignore capitals: `[data-rating="explicit" i]`.
- **An attribute selector scores like a class.** In the specificity columns from *Specificity: Scoring a Selector*, `li[aria-current="true"]` is (0, 1, 1), the same as `li.playing` would be.

## ^= $= \*= : part of a value

Sometimes you know only part of the value: how a link starts, or how it ends. Three operators match part of it:

| Operator | Read | Matches when the value… | Example |
|---|---|---|---|
| `^=` | "starts with" | starts with the text | `a[href^="https://"]`: links to another site |
| `$=` | "ends with" | ends with the text | `a[href$=".pdf"]`: links to a PDF |
| `*=` | "contains" | has the text anywhere in it | `a[href*="lyrics"]`: links with *lyrics* in the address |

(`^` is the caret, above the 6 on most keyboards, and `$` is the dollar sign.) Here they mark the footer's two links:

```css
a[href$=".pdf"] {
  font-weight: bold;
}

a[href^="https://"] {
  font-style: italic;
}
```

The lyrics link ends in `.pdf`, so it's bold; the share link starts with `https://`, so it's italic. A new PDF link added next month is bold the moment it appears, with no class and no change to the CSS. The next lesson but one, *Pseudo-Elements: ::before, ::after and ::marker*, puts a small "↗" after outside links, which is how many sites mark them.

**Try it.** In your `road-trip.html`, add the footer and the two rules. Then add a third link of your own, such as `<a href="setlist.pdf">Setlist (PDF)</a>`, save, and watch it turn bold. Change the `.pdf` rule's `$=` to `^=` and save: why does nothing match now?

## Reaching the right things without classes

Attribute selectors fit wherever the HTML already says what something is:

- **Form fields by type:** `input[type="email"]`, `input[type="checkbox"]`, a `[required]` field.
- **Links by where they go:** files (`$=".pdf"`, `$=".zip"`), outside sites (`^="https://"`), email links (`^="mailto:"`).
- **States other tools set:** `[aria-current="page"]` for the current page in a menu, `[aria-expanded="true"]` for an open menu. Styling the attribute keeps what screen readers hear and what everyone sees in step.

## Check yourself

2 questions to try on the lesson page.

## So what

The HTML already says a lot about every element. Attribute selectors let your CSS read it, so the page stays styled correctly as people add links, songs and form fields you never saw.

## Key terms

- [Attribute selector](https://www.ask-codey.com/glossary/attribute-selector)
- [Attribute](https://www.ask-codey.com/glossary/attribute-html)
- [Attribute value](https://www.ask-codey.com/glossary/attribute-value)

## Cheat sheets

- [Attribute Selectors](https://www.ask-codey.com/cheat-sheets/css-attribute-selectors-cheat-sheet)

## Related

- [Combinators: Descendant, Child and Sibling](https://www.ask-codey.com/lessons/css-combinators)
- [Pseudo-Classes: :hover, :focus-visible, :nth-child() and More](https://www.ask-codey.com/lessons/css-pseudo-classes)

Source: https://www.ask-codey.com/lessons/css-attribute-selectors
