October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
CSS

How to Select Elements by Attribute Using CSS Selectors

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use an attribute selector when the element you need is identified by an HTML attribute rather than by a class or ID. Put the attribute name in square brackets: [disabled] matches every element that has a disabled attribute, while input[type="email"] matches only email inputs. Add a type selector, combine multiple attribute tests, and choose an operator that fits the value you actually need to match.

This guide explains presence, exact, token, language-prefix, prefix, suffix and substring matching; case rules; practical patterns; debugging; and a way to capture the resulting page without configuring a browser.

Attribute-selector syntax at a glance

An attribute selector is a name, optionally followed by a matching operator and value, enclosed in square brackets. It can stand alone or follow a type selector such as a, input or [data-state]. The selector tests the represented attribute value; it does not infer an element’s intended role.

Selector form Matches Example
[attr] The attribute exists, including an empty value a[title]
[attr="value"] The complete value is exactly equal input[type="email"]
[attr~="value"] One whitespace-separated word equals the value a[rel~="nofollow"]
[attr|="value"] The value is exact, or starts with that value followed by a hyphen [lang|="en"]
[attr^="value"] The value starts with the string a[href^="#"]
[attr$="value"] The value ends with the string a[href$=".org"]
[attr*="value"] The value contains the string anywhere a[href*="example"]

Quote values when they contain spaces or characters that need string syntax. Whitespace between the attribute name, operator and value is optional, but consistent formatting improves readability.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Match an attribute’s presence

Use brackets without an operator

[attr] asks only whether the attribute is present. It does not require a nonempty value, so both <button disabled> and <button disabled=""> match button[disabled].

/* Any link carrying a title attribute */
a[title] {
  text-decoration: underline;
}

/* Any element with a data-testid, regardless of its value */
[data-testid] {
  outline: 1px dashed gray;
}

Presence is useful for boolean attributes such as disabled, required and hidden, and for locating hooks such as data-testid. It is different from checking whether an attribute’s text is a particular value.

Match an exact attribute value

Use = for the whole string

[attr="value"] succeeds only when the complete attribute value equals the quoted string. For example:

input[type="email"] {
  border-color: teal;
}

button[data-state="open"] {
  background: lightgreen;
}

An exact selector will not match data-state="open busy" or type="email address". Use it when additional words or characters should disqualify the element.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose the operator that matches your data

Whitespace-separated tokens: ~=

Use [attr~="value"] when an attribute contains a space-separated list and you need one token. a[rel~="nofollow"] matches rel="external nofollow", but not rel="nofollowed". This is the safer way to test one class-like word in a multi-token attribute.

/* Finds a token, not merely a substring */
a[rel~="nofollow"] {
  color: #955;
}

Language-style prefixes: |=

[attr|="value"] matches the exact value or that value immediately followed by a hyphen. Thus [lang|="en"] matches lang="en" and lang="en-US", but not lang="english" or lang="en_GB". It is designed for language subtags, not general substring searches.

Starts with: ^=

[attr^="value"] matches values beginning with the supplied string. A common pattern selects fragment links:

a[href^="#"] {
  scroll-behavior: smooth;
}

It also works for protocol or path filtering, such as a[href^="https://"]. Remember that it tests the literal attribute value; it does not resolve relative URLs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Ends with: $=

[attr$="value"] tests the final characters. For example, a[href$=".org"] finds links whose written href ends in .org. Query strings or trailing slashes can prevent a match, so use this form only when the ending is stable.

Contains anywhere: *=

[attr*="value"] finds a substring at any position:

a[href*="example"] {
  color: purple;
}

This is the broadest and most error-prone operator. It can match incidental text (for example, notexample.com), so prefer exact, token, prefix or suffix tests when your data has a clearer shape.

Combine selectors to narrow the result

Join a type and an attribute

[href] can match non-link elements that carry an href attribute. Prefixing it with a limits the result to anchors: a[href]. This makes intent clearer and avoids styling unrelated markup.

Require several attributes on one element

Concatenate bracket conditions with no combinator. Every condition must match the same element:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
/* Secure .org links only */
a[href^="https://"][href$=".org"] {
  color: green;
}

/* A visible, open dialog hook */
[role="dialog"][aria-hidden="false"] {
  display: block;
}

These conditions are an AND relationship. A comma creates separate alternatives (an OR-style selector list), while a space would mean a descendant relationship and change the target entirely.

Control case sensitivity explicitly

Case behavior depends on the document language and the attribute’s semantics. HTML attribute names are case-insensitive. Some defined enumerated HTML values are also matched without regard to case, while values of class, id and data-* are case-sensitive by default.

For ASCII characters, append i for an ASCII case-insensitive comparison or s to request case-sensitive matching:

/* Matches .ORG, .org and other ASCII case variants */
a[href$=".ORG" i] {
  font-weight: bold;
}

/* Requires the exact lowercase token */
[data-mode="dark" s] {
  color: white;
}

Support for modifiers can vary in older user agents. If a target browser does not support a modifier, the selector will not match; verify the environments you support before making it essential to the design. The MDN attribute-selector reference records current syntax and compatibility notes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common mistakes and safer fixes

  • Testing a token with =: [class="button"] requires the entire class attribute to be exactly button. Use [class~="button"] when other classes may appear.
  • Using |= as a general contains test: it means exact-or-hyphen-prefix, not arbitrary substring. Use *= only when incidental matches are acceptable.
  • Assuming presence means a useful value: [data-note] also matches data-note="". Add an exact or nonempty-value convention in your markup when that distinction matters.
  • Forgetting URL details: a suffix selector may miss https://site.org/ or https://site.org?a=1. Normalize URLs or select on a more stable attribute.
  • Overly broad substring matches: [href*="admin"] can select unrelated domains and paths. Combine it with a, a protocol prefix, or a more specific path.
  • Expecting semantics or validation: CSS matches the represented attribute text. It does not confirm that role, type or a custom data value is appropriate for the element.

Debug an attribute selector in the browser

  1. Inspect the element and copy the attribute exactly as it appears in the DOM. Check for whitespace, case, query strings and trailing slashes.
  2. In DevTools’ Elements panel, press Ctrl+F (Windows/Linux) or Command+F (macOS), then search for the selector, such as a[href^="#"].
  3. In the Console, run document.querySelectorAll('a[rel~="nofollow"]'). A result length of zero means the selector did not match the current DOM.
  4. Temporarily add a visible rule such as outline: 3px solid red to determine whether the selector matches but is losing a cascade or specificity conflict.
  5. If dynamically generated markup is involved, run the query after the component renders. CSS selectors cannot match an attribute that has not yet been added.

Browser support and standards

Attribute selectors are broadly available across modern browsers; MDN describes the feature as well established across many devices and browser versions, with broad availability since July 2015. Individual details, particularly case-modifier behavior, can vary. Consult the MDN learning guide and the W3C Selectors Level 4 specification when targeting older or specialized user agents.

Or skip the browser setup

If you need a clean image of a page showing these selectors, ScreenshotNeo provides a one-request screenshot API and an MCP server for AI agents. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status.

Capture with cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Capture with Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Capture with Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the complete parameter list and response details in the ScreenshotNeo documentation. Features include full-page and element capture, device presets, retina scale, PDF output, custom CSS and JavaScript, click and wait conditions, request blocking, headers, cookies, geolocation, signed links, asynchronous webhooks, bulk capture and a usage API. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for the free plan.

Frequently Asked Questions

Can an attribute selector target a data attribute?

Yes. Use the literal name, for example [data-testid="checkout"] or [data-role~="tab"]. Data-attribute values are case-sensitive by default.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can I select an element when an attribute is empty?

Use the presence form, such as [title], if empty and nonempty values should both match. An exact empty-string test, [title=""], restricts the result to an explicitly empty value.

Do attribute selectors work in JavaScript?

Yes. The same selector grammar can be passed to querySelector and querySelectorAll, provided the selector is valid for the current document.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.