Skip to main content
Syllabus
On this page

CSS Attribute Selectors: [attr], ^=, $=, *= and More

Badar KhalilUpdated September 29, 2026 4 min read

CSS Attribute Selectors: Style Elements by Their Attributes

CSS attribute selectors target elements based on the presence or value of an HTML attribute such as href, type, src, target, lang, disabled or data-*. They are extremely useful for forms, links, images and components, and let you style elements without adding extra classes.

Attribute Selector Syntax Overview

All attribute selectors are written in square brackets. Quotes around the value are optional in simple cases, but recommended for values containing spaces, symbols or starting with digits.

SelectorMeaningExample
[attr]Attribute exists[disabled]
[attr='value']Exact value match[type='email']
[attr~='value']Value is one word in a space-separated list[class~='card']
[attr|='value']Value equals or starts with value followed by a hyphen[lang|='en']
[attr^='value']Starts with[href^='https']
[attr$='value']Ends with[href$='.pdf']
[attr*='value']Contains the substring[href*='example']

1. Presence Selector: [attr]

Matches any element that has the attribute, whatever its value. For example, [required] matches every required form field and a[target] matches links that have a target attribute.

2. Exact Match: [attr='value']

Matches only when the attribute value is exactly the given text. For example, input[type='password']. It is useful for styling different form input types separately.

3. Word Match: [attr~='value']

Matches when the value is one of several whitespace-separated words. It works like a class selector on any attribute, for instance [data-tags~='new'] matches data-tags='sale new featured'.

4. Language and Hyphen Match: [attr|='value']

Matches when the value is exactly the given text or begins with it followed by a hyphen. It was designed for language codes: [lang|='en'] matches en, en-US and en-GB.

5. Starts With: [attr^='value']

Matches when the value begins with the given string. Typical uses: external links (a[href^='https']), email links (a[href^='mailto:']) and phone links (a[href^='tel:']).

6. Ends With: [attr$='value']

Matches when the value ends with the given string. A classic example is adding an icon to file-type links: a[href$='.pdf'], a[href$='.zip'], img[src$='.svg'].

7. Contains: [attr*='value']

Matches when the value contains the substring anywhere. For example, a[href*='facebook'] or [class*='col-'] (matches col-1, col-md-6 and so on).

Case-Insensitive and Case-Sensitive Flags

By default, attribute values are case-sensitive in HTML for most attributes, although some (such as type) are matched case-insensitively. Add a flag before the closing bracket:

  • [href$='.PDF' i] ignores case (matches .pdf, .PDF, .Pdf).
  • [data-mode='Dark' s] forces case-sensitive matching.

Practical Use Cases

  • Form styling: style text, email, checkbox, radio and submit inputs differently.
  • External link indicators: add an arrow to links that start with https or open in a new tab.
  • Download icons: show a PDF icon on links ending with .pdf.
  • Disabled and required states: style [disabled] buttons and [required] fields with a marker.
  • Data attributes: theme or state hooks such as [data-theme='dark'] or [data-state='open'], very common in modern component libraries and design systems.
  • Accessibility states: style with [aria-expanded='true'] or [aria-current='page'] so that visual state always matches the accessible state.

Specificity

An attribute selector has the same specificity as a class: (0,1,0). So a[href^='https'] scores (0,1,1). This is important when you mix attribute selectors with class rules.

Best Practices

  • Always quote values to avoid errors with special characters.
  • Prefer classes for simple, general styling; use attribute selectors where the attribute already carries the meaning (type, href, aria-*, data-*).
  • Be specific: [href*='a'] is too broad and will match many unintended links.
  • Do not depend on attribute values that content editors may change often.

Common Mistakes

  • Confusing ^= (starts) with $= (ends).
  • Using ~= when you mean *=: word match needs whole, space-separated words.
  • Forgetting that a space in the value requires quotes.
  • Forgetting that the selector matches the HTML attribute, not the JavaScript property.

Key Takeaways

  • Attribute selectors use square brackets and match presence or value patterns.
  • ^= starts with, $= ends with, *= contains, ~= word, |= language prefix.
  • The i flag makes matching case-insensitive.
  • They have class-level specificity (0,1,0) and are great for forms, links and data-attribute state.
Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Exercise: Mark External LinksHTML

Make links whose href starts with 'https' green and add the text ' (external)' after them using ::after. Make links that end with '.zip' bold.

Try it Yourself HTML
Output

Press Run to execute.

Show expected output
Green https link with ' (external)' text, bold zip link, unchanged about link.

This is a self-check — compare your result with the expected output above.

Exercise: Style by data AttributeHTML

Give any element with data-priority='high' a red left border, and any element with data-priority='low' a gray left border. Elements with no data-priority stay unstyled.

Try it Yourself HTML
Output

Press Run to execute.

Show expected output
[data-priority='high'] { border-left: 4px solid red; } [data-priority='low'] { border-left: 4px solid gray; }

This is a self-check — compare your result with the expected output above.

Was this page helpful?