:contains(text) (since jQuery 1.1.4) selects elements whose text content includes the given string. The text may sit on the element itself, in any descendant, or both. Matching is case-sensitive. Quotes around the text are optional.
Remember
$("div:contains('John')") // text includes "John"
$("div:contains(John)") // same — quotes optional
$(":contains('John')") // avoid — scans every element
// Case-sensitive: "john" ≠ "John"
// Prefer a tag or parent: $("#list li:contains('apple')")
Pick a tag or container first, then filter by the substring you need.
Start with a tag or scoped selector: $("div:contains('…')") or $("#box p:contains('…')").
Pass the search string — with or without quotes; casing must match.
Remember parents match when a child holds the text (aggregated text content).
Do not use bare $(":contains('…')") on large pages — it scans everything.
For attributes (not text), use [attr*="value"] instead.
Piece
Required?
Role
text
Yes
Case-sensitive substring to find
Tag / context
Recommended
Limits which elements are tested
Quotes
Optional
Bare word or '…' / "…"
Return value
—
jQuery collection of matching elements
Pseudocode
Pseudocode
matches = []
needle = given text // case-sensitive
for each element in search context:
haystack = element.textContent // includes all descendants
if haystack contains needle:
matches.add(element)
return matches
Reference
Cheat Sheet
Keep these facts handy when searching by text.
Topic
Detail
Syntax
$("div:contains('text')")
Since
jQuery 1.1.4
Standard?
No — jQuery / Sizzle extension
Case
Case-sensitive
Descendants
Yes — nested text counts
Quotes
Optional around the text
vs attributes
Use [attr*="…"] for attributes
Empty set
No match → length 0
Try it
Live Preview
Run div:contains(…) against the official-style name list.
Sample divs
John Resig
George Martin
Malcom John Sinclair
J. Ohn
Case-sensitive — try John vs john. J. Ohn does not contain John.
Result
$("div:contains('John')").length
→ 2
matched → John Resig, Malcom John Sinclair
Code
jQuery Examples
Short, copy-ready snippets. Open DevTools Console, or use Try It Yourself for a live editor.
Different jobs. One link can match both, either, or neither.
Pick. Use text search for labels; attribute search for URLs/data.
Edge Cases & Pitfalls
Check these before shipping text-based filters.
case
Case-sensitive by design
:contains("john") will not match John. There is no built-in ignore-case flag.
parents
Parents match nested text
A container matches when any descendant holds the string. Scope to the element type you really want (e.g. li, not ul).
perf
Bare $(":contains()") is slow
It tests every element. Prefer $("div:contains()") or a parent context.
css
Not valid in native CSS APIs
querySelectorAll does not support :contains(). Keep it inside jQuery $().
Compatibility
Browser Support
:contains() is a jQuery extension (since 1.1.4). It works wherever your jQuery / Sizzle build runs — not in native CSS selectors.
✓ jQuery extension · 1.1.4+
jQuery :contains()
Supported across jQuery 1.x, 2.x, and 3.x in every browser that runs your jQuery build. Prefer current jQuery 3.x for modern projects.
100%jQuery selector support
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
:contains()Universal (via jQuery)
Bottom line: Available everywhere jQuery runs. Scope the selector, respect case sensitivity, and remember it is not standard CSS.
Analysis
Performance Notes
Approach
Cost
Best for
$("#id li:contains('x')")
Cheapest
Local text filters
$("div:contains('x')")
Moderate
Small/medium pages
$(":contains('x')")
Expensive
Avoid on large DOMs
$("a[href*='x']")
Cheap
Attribute substring (not text)
:contains() walks text content. Narrow the candidate set with a tag or parent before applying the text filter.
Remember
Key Takeaways
Role: match elements whose text includes a substring.
Case: matching is case-sensitive — John ≠ john.
Scope: prefer $("li:contains('x')") over bare $(":contains('x')").
Extension: jQuery-only — not valid in native CSS APIs.
One line::contains() finds text substrings inside elements — case-sensitive, jQuery-only, and best when scoped.
Frequently Asked Questions
:contains(text) selects every element whose text content includes the given string — as direct text, inside descendants, or both. $("div:contains('John')") matches a div showing "John Resig" or "Malcom John Sinclair" because "John" appears in that element’s aggregated text.
Yes. Official jQuery docs state the search is case-sensitive. :contains("john") does not match "John Resig". Match the exact casing you expect in the DOM.
Yes. The matching text can appear directly in the element, in any descendant, or a combination. A parent div matches when a nested span holds the search string.
:contains() searches element text content. [name*="value"] searches HTML attribute values such as href or title — not rendered text. Use the right tool for text vs attributes.
No. :contains() is a jQuery extension — not valid CSS. It works inside $() / Sizzle only. document.querySelectorAll(":contains('John')") throws a syntax error.
Prefer scoping: $("#list li:contains('apple')") or $("div.item").filter(":contains('sale')"). Bare $(":contains(text)") scans every element and can be slow on large pages.