10 min read

CSS Attribute Selectors: Targeting Elements by Their Attributes

10 min read
243 words
15 sections14 code blocks

What Are Attribute Selectors?

Attribute selectors target elements based on their HTML attributes or attribute values. They let you style elements without adding extra classes, based purely on the attributes already in your HTML.

CSS
/* Select all elements with a title attribute */
[title] {
  cursor: help;
  border-bottom: 1px dotted #999;
}

Attribute Presence Selector [attr]

Targets elements that have a specific attribute, regardless of its value:

CSS
/* Any element with a disabled attribute */
[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Any element with a required attribute */
[required] {
  border-left: 3px solid #e74c3c;
}

/* Links with a target attribute */
a[target] {
  padding-right: 1.2em;
}

/* Images with alt text */
img[alt] {
  border: none;
}

Exact Match [attr="value"]

Targets elements where the attribute exactly matches the given value:

CSS
/* Only text inputs */
input[type="text"] {
  border: 1px solid #ddd;
  padding: 0.5rem;
}

/* Only email inputs */
input[type="email"] {
  border-left: 3px solid #3498db;
}

/* Links that open in new tab */
a[target="_blank"] {
  color: #e74c3c;
}

/* Specific language */
[lang="en"] {
  font-family: 'Inter', sans-serif;
}

Begins With [attr^="value"]

Targets elements where the attribute value starts with the given string:

CSS
/* External links (start with http) */
a[href^="http"] {
  padding-right: 1em;
}

/* Secure links */
a[href^="https"] {
  color: #27ae60;
}

/* Tel links */
a[href^="tel:"] {
  color: #3498db;
  text-decoration: none;
}

/* Email links */
a[href^="mailto:"] {
  color: #8e44ad;
}

/* Classes starting with "icon-" */
[class^="icon-"] {
  display: inline-block;
  width: 24px;
  height: 24px;
}

Ends With [attr$="value"]

Targets elements where the attribute value ends with the given string:

CSS
/* PDF links */
a[href$=".pdf"] {
  color: #e74c3c;
}

a[href$=".pdf"]::after {
  content: ' (PDF)';
  font-size: 0.8em;
  color: #999;
}

/* Image file links */
a[href$=".jpg"],
a[href$=".png"],
a[href$=".gif"] {
  border-bottom: 2px solid #3498db;
}

/* ZIP downloads */
a[href$=".zip"]::after {
  content: ' \2913'; /* Download arrow */
}

Contains [attr*="value"]

Targets elements where the attribute value contains the given string anywhere:

CSS
/* Links containing "youtube" */
a[href*="youtube"] {
  color: #e74c3c;
}

/* Links containing "github" */
a[href*="github"] {
  color: #333;
}

/* Any class containing "btn" */
[class*="btn"] {
  cursor: pointer;
  border: none;
}

/* Data attributes containing a value */
[data-status*="active"] {
  background: #d4edda;
}

Space-Separated [attr~="value"]

Targets elements where the attribute contains the exact word in a space-separated list:

CSS
/* Element with "featured" in class (exact word) */
[class~="featured"] {
  border: 2px solid gold;
}

/* Title containing the exact word "important" */
[title~="important"] {
  color: #e74c3c;
}

This is different from contains (*=) because it matches whole words only.

Hyphen-Separated [attr|="value"]

Targets elements where the attribute value is exactly the given value or starts with that value followed by a hyphen:

CSS
/* Language codes: en, en-US, en-GB */
[lang|="en"] {
  font-family: 'Inter', sans-serif;
}

/* French variants: fr, fr-FR, fr-CA */
[lang|="fr"] {
  font-family: 'Playfair Display', serif;
}

Case-Insensitive Matching

Add i before the closing bracket for case-insensitive matching:

CSS
/* Match .PDF, .pdf, .Pdf, etc. */
a[href$=".pdf" i] {
  color: #e74c3c;
}

/* Match type="Text", "text", "TEXT" */
input[type="text" i] {
  border: 1px solid #ddd;
}

Styling with Data Attributes

Data attributes (data-*) are perfect for attribute selectors:

CSS
/* Status indicators */
[data-status="active"] { color: #27ae60; }
[data-status="inactive"] { color: #e74c3c; }
[data-status="pending"] { color: #f39c12; }

/* Priority levels */
[data-priority="high"] { border-left: 4px solid #e74c3c; }
[data-priority="medium"] { border-left: 4px solid #f39c12; }
[data-priority="low"] { border-left: 4px solid #27ae60; }

/* Size variants */
[data-size="small"] { font-size: 0.875rem; padding: 0.25rem 0.5rem; }
[data-size="medium"] { font-size: 1rem; padding: 0.5rem 1rem; }
[data-size="large"] { font-size: 1.25rem; padding: 0.75rem 1.5rem; }
HTML
<span data-status="active">Online</span>
<div data-priority="high">Urgent task</div>
<button data-size="large">Submit</button>

Practical Patterns

Form Input Styling by Type

CSS
input[type="text"],
input[type="email"],
input[type="password"],
input[type="url"],
input[type="tel"],
input[type="search"] {
  width: 100%;
  padding: 0.75rem;
  border: 1px solid #ddd;
  border-radius: 4px;
}

input[type="checkbox"],
input[type="radio"] {
  margin-right: 0.5rem;
}

input[type="range"] {
  width: 100%;
}
CSS
/* Add icon to external links */
a[href^="http"]:not([href*="yourdomain.com"])::after {
  content: ' \2197';
  font-size: 0.75em;
  vertical-align: super;
}

Accessibility Debugging

CSS
/* Highlight images without alt text */
img:not([alt]),
img[alt=""] {
  outline: 3px solid red;
}

/* Highlight links without href */
a:not([href]) {
  background: yellow;
}

/* Highlight empty buttons */
button:empty {
  outline: 3px solid orange;
}

Summary

CSS attribute selectors target elements based on their HTML attributes without extra classes. Use [attr] for presence, [attr="val"] for exact match, [attr^="val"] for starts-with, [attr$="val"] for ends-with, and [attr*="val"] for contains. Combine with data attributes for component styling, file type indicators, and accessibility debugging. Add the i flag for case-insensitive matching.