Is there a CSS selector for elements containing certain text?
No. There is no standard CSS selector that matches elements based on their text content alone. In other words, you can’t write something like div:contains("Hello")
in pure CSS. Any “:contains” or similar text-matching selector you may have seen is typically a jQuery extension or another JavaScript library feature, not part of the official CSS specification.
1. Why No Text-Content Selector in CSS?
CSS selectors are designed to match elements based on:
- Tag/element type (e.g.,
div
,span
) - Attributes (e.g.,
[href]
,[target="_blank"]
) - Class and ID (e.g.,
.class
,#id
) - Hierarchical relationships (
div > span
,div ~ p
, etc.) - Pseudo-classes for states or relationships (e.g.,
:hover
,:not()
,:has()
, etc.)
But not on the element’s actual text content. This behavior is intentionally absent because CSS is meant for styling structure and attributes, not parsing and matching text strings.
2. Newer Features Like :has()
- The
:has()
pseudo-class introduced in the CSS Selectors Level 4 specification allows you to match an element if it contains a certain child or descendant that matches another selector. - However,
:has()
still doesn’t let you target raw text nodes—it only works with descendant elements. For example, you can style a<div>
if it contains an<img>
or if it has a child with a certain class, not if the text node inside it says “Hello world.”
/* Example: "style any .wrapper that has a <p> with class 'highlight' inside" */ .wrapper:has(p.highlight) { border: 1px solid red; }
This does not allow searching for a specific substring of text.
3. Workarounds or Alternatives
-
Attribute Selectors
If the text you’re trying to match is in an attribute (liketitle
ordata-*
), you can use attribute selectors. For instance:/* Matches elements whose title attribute contains "Hello" */ [title*="Hello"] { background: yellow; }
But this applies to attribute values, not the element’s text node content.
-
JavaScript
Use JavaScript (e.g.,document.querySelectorAll
, or jQuery’s:contains()
) to find elements containing certain text, then apply classes or inline styles dynamically:// Pure JS example: document.querySelectorAll("p").forEach(p => { if (p.textContent.includes("Hello")) { p.classList.add("has-hello"); } });
Then in CSS:
.has-hello { background: yellow; }
-
Server-Side / Preprocessing
If you have access to the server or a build process, you could preprocess or transform your HTML to insert classes where certain text is present.
4. Summary
- No built-in CSS feature exists for selecting or styling elements purely by their text content.
:contains()
is a jQuery (or similar library) extension, not a CSS selector.:has()
in modern CSS can look for child elements, but not text strings within them.- If you need to style elements containing a specific text string, rely on JavaScript (or other build-time logic) to find and label those elements.
Key Takeaway
You can’t directly use a “text-based” selector in CSS. You either use JavaScript or other non-CSS approaches to identify and style elements that contain certain text.