jQuery.contains(container, contained) (alias $.contains) returns true when contained is a descendant of container — direct child or nested deeper (since jQuery 1.4).
Get two element nodes, then ask if the second lives inside the first.
Pick the container element (ancestor candidate).
Pick the contained element (possible descendant).
If you have jQuery objects, unwrap with [0].
Call $.contains(container, contained) and branch on true / false.
Piece
Required?
Role
container
Yes
DOM element that may contain the other
contained
Yes
DOM element that may be a descendant
Return
—
Boolean
Pseudocode
Pseudocode
function contains(container, contained):
if contained is not an element node:
return false
// walk ancestors of contained (or use native check)
return contained is inside container (not equal to container)
// Official demo:
$.contains(document.documentElement, document.body) → true
$.contains(document.body, document.documentElement) → false
Reference
Cheat Sheet
Keep these facts handy while testing DOM ancestry.
Siblings.box-a and box-b share a parent but neither contains the other.
Self. An element is not considered a descendant of itself → false.
Click-outside tip. Test $.contains(menu, event.target) — clicks on the menu root itself are outside this helper’s “descendant” rule; include an extra menu === event.target check when needed.
Boolean only. No exception — unrelated pairs simply return false.
Example 4 — Unwrap jQuery Objects
Always pass raw elements from a collection.
jQuery
// <nav id="menu"><a id="menu-link" href="#">Link</a></nav>
var $menu = $("#menu");
var $link = $("#menu-link");
console.log($.contains($menu[0], $link[0])); // true
Select.$("#menu") and $("#menu-link") are jQuery collections.
Unwrap.[0] reads the first matched DOM element.
Call.$.contains($menu[0], $link[0]) gets native elements as required.
Result. The link sits inside the nav → true.
Edge Cases & Pitfalls
Check these before using $.contains() in UI logic.
types
jQuery objects are not valid arguments
Pass $el[0], not $el. The first argument must be a DOM element.
nodes
Text and comment nodes return false
Only element nodes count for contained. Prefer event.target when it is an element, or walk up with .closest().
self
An element does not contain itself
For click-inside checks, use container === target || $.contains(container, target).
native
Native Node.contains() is broader
Modern browsers support element.contains(node) for any node type. Keep $.contains when you already use jQuery and want element-only checks.
Compatibility
Browser Support
jQuery.contains() needs a browser DOM. It has been available since jQuery 1.4+ in all modern browsers — it is not supported in Node.js, Bun, or Deno without a DOM.
✓ jQuery 1.4+ · Browsers only
jQuery.contains()
Works in Chrome, Firefox, Safari, Edge, and other browsers with jQuery loaded. No Node.js support — this helper checks real DOM ancestry.
100%Browser 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()Browsers
Bottom line: Use $.contains(container, contained) in the browser with DOM elements. Unwrap jQuery objects with [0] first.
Analysis
Performance Notes
Approach
Cost
Best for
$.contains(a, b)
O(depth)
Known element pairs
$a.find(sel)
Higher
Search when you do not have the child node yet
$a.has(sel)
Higher
Filter a collection by descendant match
Prefer $.contains when both nodes are already known — it is a targeted ancestry check, not a full selector scan.
One line: ask $.contains(ancestor, descendant) with raw elements — unwrap jQuery, and remember self-checks are false.
Frequently Asked Questions
jQuery.contains(container, contained) returns true when contained is a descendant of container — a direct child or nested deeper. It returns false when the nodes are unrelated, siblings, or when contained is not inside container.
No. Both arguments must be native DOM elements. Unwrap jQuery collections with [0] or .get(0) before calling $.contains(container, contained).
No. Only element nodes are supported for the second argument. Text and comment nodes return false even when they appear inside the container.
Native Node.contains() accepts any Node type, including text nodes. jQuery.contains() is stricter — elements only for the second argument — and was added for consistent cross-browser checks in jQuery apps.
contains() is a boolean test between two known element nodes. .find() searches descendants from a jQuery collection. .has() filters a collection to elements that contain a matching descendant.
No. It needs a browser DOM. Use it in the browser with jQuery loaded; on the server, use a DOM library or skip this helper.