jQuery .has() Method

Beginner
6 min read
Updated: Oct 2026
5 examples
Live preview

What Is .has()?

.has(selector|element) (since jQuery 1.4) reduces the matched set to elements that contain a matching descendant. The result is the containers — not the inner matches.

Remember
// Official pattern — li that contain a nested ul
$("li").has("ul");

// Yes/No: does the ul contain any li?
$("ul").has("li").length ? "Yes" : "No";

// Same idea as :has() at query time
$("li:has(ul)");

// Not the same as .find() (returns descendants)
$("li").find("ul");
NeedUse
Containers that hold a match$el.has("ul")
The matching descendants.find("ul")
Element itself matches.filter("li")
Selector form$("li:has(ul)")
Boolean test.is(":has(ul)")

How to Use .has()

Select candidates, then keep only those that contain a match inside.

  1. Select the candidate containers — e.g. $("li") or $("div.card").
  2. Call .has("selector") or .has(domElement).
  3. Remember: the result is a subset of the original set.
  4. Chain methods on those containers — .text(), .addClass(), …
  5. Use .find() instead when you need the inner matches.
PieceRequired?Role
Matched setYesCandidate containers
selectorOne ofDescendant pattern to look for
elementOne ofSpecific DOM node that must be inside
Depth—Any depth (not just direct children)
Return value—New jQuery set (subset of parents)

Pseudocode

Pseudocode
call $(candidates).has(target)

result = empty set
for each candidate in the matched set:
    look inside candidate for descendants
    if any descendant matches target (selector or element):
        add candidate to result

return result
    → containers, not the inner matches

Cheat Sheet

Keep these differences next to .find() and .filter().

TopicDetail
Syntax.has(selector|element)
SincejQuery 1.4
ReturnsContainers from the current set
DepthAny descendant depth
vs .find()Parents vs descendants
vs .filter()Inside vs the element itself
vs :has()Method mid-chain vs selector string
Official demo$("li").has("ul")

Live Preview

Mark li that contain a nested ul, or compare .has() with .find().

Only item 2 contains a nested list. .has("ul") keeps that li; .find("ul") returns the inner ul.

  • list item 1
  • list item 2
    • list item 2-a
    • list item 2-b
  • list item 3
  • list item 4
Result
Ready — pick an action and click Run.

jQuery Examples

Short, copy-ready snippets. Use Try It Yourself for a live editor.

Example 1 — Official $("li").has("ul")

Mark the list item that contains a nested list (CSS-free).

jQuery
$("li").has("ul").append(" [has ul]");
Try It Yourself

How It Works

  1. Candidates. All li elements are considered.
  2. Test. Keep only those with a descendant ul.
  3. Mark. Append runs on the container li.
  4. Skip. Leaf items without a nested list stay unmarked.

Example 2 — Does the ul Contain an li?

Official Ex. idea: report Yes/No from .has().length.

jQuery
$("#out").text(
  "Does the UL contain an LI? " +
  ($("ul.demo").has("li").length ? "Yes" : "No")
);
Try It Yourself

How It Works

  1. Container. Start from ul.demo.
  2. Has. Keep it only if an li descendant exists.
  3. Length. Non-zero means Yes.
  4. Use. Handy for empty-state checks in UI.

Example 3 — .has() vs .find()

Same list — containers vs the nested lists themselves.

jQuery
$("#out").text(
  "has('ul') → " + $("li").has("ul").length +
  " | find('ul') → " + $("li").find("ul").length
);
Try It Yourself

How It Works

  1. has. Returns the parent li that wraps a ul.
  2. find. Returns the nested ul element(s).
  3. Counts. May match in size but point at different nodes.
  4. Pick. Style the parent with .has(); style the child with .find().

Example 4 — .has() vs .filter()

.filter() tests the element; .has() tests what is inside it.

jQuery
$("#out").text(
  "filter('.open') → " + $("div.card").filter(".open").length +
  " | has('span.badge') → " + $("div.card").has("span.badge").length
);
Try It Yourself

How It Works

  1. filter. Keeps cards that themselves have class open.
  2. has. Keeps cards that contain a span.badge inside.
  3. Different tests. Self vs descendants.
  4. Combine. Chain both when you need both rules.

Example 5 — .has(domElement)

Keep the container that holds a specific DOM node.

jQuery
var target = document.getElementById("chip");
$("div.box").has(target).append(" [contains chip]");
Try It Yourself

How It Works

  1. Target. Grab a known DOM node with getElementById.
  2. Has. Keep boxes that contain that exact node.
  3. Mark. Only the true container is labeled.
  4. Use. Handy when you already hold an element reference.

Edge Cases & Pitfalls

Check these when .has() returns an empty set.

result

You get parents, not children

$("li").has("ul") returns li nodes. To style the nested ul, use .find("ul").

self

The element itself does not count

$("ul").has("ul") looks for a nested ul. A lone outer ul does not match itself.

depth

Any depth counts

Grandchildren match too. If you need only direct children, combine with .children() logic instead.

scope

Start from the right set

$("li").has("ul") and $("div").has("ul") answer different questions — choose the candidate containers carefully.

Browser Support

.has() is a core jQuery traversing method since 1.4. It works in every browser that runs your loaded jQuery version. The related CSS :has() selector is separate and depends on browser CSS support.

✓ Stable · jQuery 1.4+

jQuery .has()

Universal across jQuery-supported browsers. Prefer .has() mid-chain; use :has() in selector strings when the browser/CSS engine supports it.

1.4+ jQuery since
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
.has() Universal

Bottom line: Safe for everyday UI. Remember it returns containers — use .find() when you need the inner matches.

Performance Notes

ApproachCostBest for
Scoped $("#menu li").has("ul")CheapMenus, cards, local trees
$("li").has("ul")Cheap–moderatePage-wide parent filtering
Deep trees + broad candidatesModerateNarrow the set before .has()

Scope candidates first. .has() must look inside each element, so a smaller starting set is faster on large pages.

Key Takeaways

  • Role: keep elements that contain a matching descendant.
  • Result: containers from the current set — not the inner matches.
  • vs .find(): parents vs descendants.
  • Also: accept a selector or a DOM element since 1.4.

One line: .has() answers “which of these contain X?” — use .find() when you want X itself.

Frequently Asked Questions

.has() reduces the current jQuery collection to elements that contain at least one descendant matching a selector or DOM element. It returns the container elements — not the matching descendants themselves.
.find() returns the descendant elements that match. .has() returns the ancestors from the current set that contain such descendants. $("li").find("ul") gives nested uls; $("li").has("ul") gives li elements that wrap a ul.
.filter() tests each element in the current set — the element itself must match. .has() tests descendants inside each element — the parent stays if any descendant matches.
Yes, since jQuery 1.4. .has(domElement) keeps elements from the current set that contain that DOM node as a descendant.
No. .has() checks all descendants at any depth — grandchildren and deeper included.
Both mean “elements that have X inside.” $("div:has(p)") does it at query time; $("div").has("p") applies the same idea to an existing collection.

Next: .is() method

Test whether the current set matches a selector or condition.

.is() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful