jQuery .find() Method

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Descendant search

What You’ll Learn

The .find() traversing method searches descendants of each element in the current set and returns a new jQuery collection of matches. This tutorial covers the official nested list demo, paragraph span examples, jQuery collection filtering, chaining with .end(), and compares .find() with .children() and .filter().

01

Selector

.find("li")

02

Any depth

All descendants

03

Not self

Parent excluded

04

jQ / DOM

Since 1.6

05

vs .children()

One vs all levels

06

Since 1.0

Core API

Introduction

After selecting a container — a list item, a div, a table cell — you often need elements inside it: nested list items, spans in paragraphs, inputs in a form section. The .find() method walks down the DOM tree from each matched parent and collects descendant elements that match your selector.

Available since jQuery 1.0 (with jQuery object / DOM element filtering since 1.6), .find() is one of the most-used traversing tools. It is equivalent to scoped selector context: $("li.item-ii").find("li") works like $("li", "li.item-ii").

Understanding the .find() Method

Given a jQuery object representing a set of DOM elements, .find(selectorOrElement) searches through the descendants of those elements and constructs a new jQuery object from the matches. The starting elements themselves are never included — only nodes below them in the tree.

Unlike .children(), which stops at one level, .find() continues through nested structures at any depth. Unlike .filter(), it can return elements that were not part of the original matched set.

💡
Beginner Tip

$("p span") finds spans at query time from the document root. $("p").find("span") finds spans only inside already-matched paragraphs — ideal when you already have a jQuery collection from earlier in a chain.

📝 Syntax

General forms of .find:

jQuery
.find( selector )

.find( element )

.find( jQueryObject )

Parameters

  • selector (since 1.0) — a string containing a selector expression. Required unless passing an element or jQuery object. Use "*" for all descendants.
  • element (since 1.6) — a DOM node; keeps only descendants matching this element.
  • jQuery object (since 1.6) — keeps only descendants that appear in the provided jQuery collection.

Return value

  • A new jQuery object containing descendant elements that match the selector or intersect with the provided element/collection.

Official jQuery API nested list example

jQuery
$( "li.item-ii" ).find( "li" ).css( "background-color", "red" );

// Red on A, B, 1, 2, 3, C — item II itself is NOT included

⚡ Quick Reference

GoalCode
All descendant li inside a scope$("li.item-ii").find("li")
Spans inside paragraphs$("p").find("span")
Every descendant element$("div.panel").find("*")
Direct children only (one level)$("ul").children("li")
Intersect with existing collection$("p").find(allSpans)
Return to parent set after find$("p").find("span").end()

📋 .find() vs .children() vs .filter()

Three methods that change which elements you work with — different direction and scope.

.find()
descend

Search all levels inside matched elements

.children()
one level

Direct child elements only

.filter()
subset

Narrow current set — no new nodes

Includes self?
no

.find() never returns the starting element

Examples Gallery

Examples 1–4 follow the official jQuery API documentation. Use DevTools or the Try-it links to run each snippet in the browser.

📚 Getting Started

Official jQuery demos with nested lists and paragraph span searches.

Example 1 — Official Demo: Nested List Descendants

From item II, find every descendant li and highlight them red — the core nested-list lesson from the jQuery docs.

jQuery
$( "li.item-ii" ).find( "li" ).css( "background-color", "red" );
Try It Yourself

How It Works

.find("li") walks every level below item II. Even though item II matches li, it is excluded because .find() only returns descendants — never the element you call it on.

Example 2 — Official Demo: Find Spans Inside Paragraphs

Start with all paragraphs, then color descendant span elements red — same as $("p span").

jQuery
$( "p" ).find( "span" ).css( "color", "red" );
Try It Yourself

How It Works

When you already have a jQuery collection of paragraphs, .find("span") scopes the search to those containers only — a pattern you will use constantly in chained code.

📈 Practical Patterns

jQuery collection filtering, .end() chaining, and comparison with .children().

Example 3 — Official Demo: Filter with a jQuery Collection

Pass an existing jQuery object of all spans — only spans inside paragraphs turn red.

jQuery
var spans = $( "span" );

$( "p" ).find( spans ).css( "color", "red" );
Try It Yourself

How It Works

Since jQuery 1.6, .find(jQueryObject) returns descendants that also appear in the passed collection. Useful when reusing a cached global selection inside a scoped subtree.

Example 4 — Official Demo: .find() with .end() Chain

Wrap words in spans, add hover on spans, then return to the paragraph and italicize words containing “t” — official Example 3 pattern.

jQuery
var newText = $( "p" ).text().split( " " ).join( " " );

newText = " " + newText + " ";

$( "p" )

  .html( newText )

  .find( "span" )

  .hover(function () {

    $( this ).addClass( "hilite" );

  }, function () {

    $( this ).removeClass( "hilite" );

  })

  .end()

  .find( ":contains('t')" )

  .css({ "font-style": "italic", "font-weight": "bolder" });
Try It Yourself

How It Works

.find("span") pushes the paragraph set onto jQuery’s internal stack. After hover setup, .end() pops back to the original p elements so the second .find(":contains('t')") runs on paragraphs again — not on the span subset.

Example 5 — .find() vs .children() on the Same List

See how one-level .children() differs from all-depth .find() on nested markup.

jQuery
$( "#children-demo li" ).children( "li" ).css( "color", "green" );

$( "#find-demo li" ).find( "li" ).css( "color", "red" );



// Same nested ul — different depth
Try It Yourself

How It Works

On item II, .children("li") stops at the first nested level. .find("li") keeps going through every nested ul until all descendant list items are collected.

🚀 Common Use Cases

  • Form fields inside a section$(".checkout").find("input, select").
  • Table cells in a row$("tr.selected").find("td.price").
  • Nested menu items$("li.active").find("a").
  • Widget internals$(".modal").find(".close-btn").
  • Scoped re-query$("div.panel").find("span.highlight") after dynamic HTML updates.
  • Return to container — chain .end() after .find() to style the parent again.

🧠 How .find() Searches Descendants

1

Start with parents

jQuery object holds container elements.

Input
2

Walk the subtree

Search every descendant level below each parent.

Descend
3

Test matches

Selector, element, or jQuery collection filter.

Match
4

Return & chain

New jQuery object of descendants — push stack for .end().

📝 Notes

  • Available since jQuery 1.0; jQuery object / DOM element form since 1.6.
  • Selector argument is required — use "*" for all descendant elements.
  • Starting elements are never included — descendants only.
  • Equivalent to scoped context: $("li.item-ii").find("li")$("li", "li.item-ii").
  • Pushes onto jQuery’s internal stack — pair with .end() to restore the parent set.
  • Empty find result returns an empty jQuery object — safe to chain.

Browser Support

.find() has been part of jQuery since 1.0+ (element/collection form since 1.6). It relies on DOM tree walking and selector matching with no browser-specific behavior.

jQuery 1.0+

jQuery .find()

Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers and IE with supported jQuery builds. Native equivalent: element.querySelectorAll scoped to each parent.

100% With jQuery loaded
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
.find() Universal

Bottom line: Safe in any jQuery project. Use .find() to search inside matched elements; use .children() when one level is enough.

Conclusion

The jQuery .find() method searches all descendants of each element in the current set and returns a new collection of matches. It is the go-to tool for drilling into containers without re-querying the whole document.

Remember the official nested list lesson: item II itself is never included — only A, B, 1, 2, 3, and C. Pair .find() with .end() when you need to return to the parent set, and choose .children() when one level down is enough.

💡 Best Practices

✅ Do

  • Use .find() to search inside an existing jQuery collection
  • Use .children() when you only need direct child elements
  • Call .end() after .find() when continuing on the parent set
  • Cache repeated selectors: var $spans = $("span") then .find($spans)
  • Scope searches to containers for performance on large pages

❌ Don’t

  • Use .find() when you need to subset the current set — use .filter()
  • Expect the starting element to appear in the result
  • Call .find() without a selector — pass "*" if you need all descendants
  • Confuse $("p span") timing with $("p").find("span") mid-chain scope
  • Use .find() when .children() suffices — it is faster for one level

Key Takeaways

Knowledge Unlocked

Five things to remember about .find()

Search inside matched elements.

5
Core concepts
02

Any depth

All levels

Scope
03

Not self

Descendants

Rule
1 04

.children()

One level

Compare
05

Stack

.end() back

Chain

❓ Frequently Asked Questions

.find() searches through all descendants of each element in the current jQuery set and returns a new jQuery object containing only the matching nodes. Unlike .filter(), it can return elements that were not in the original collection — it drills down the DOM tree.
.children() only travels one level down — direct child elements only. .find() searches at every depth — grandchildren, great-grandchildren, and deeper. Use .children() for immediate offspring; use .find() for the whole subtree.
.find() searches inside matched elements for descendants. .filter() narrows the current set — it only tests elements already in the collection and never adds new nodes from deeper in the tree.
Yes. Unlike some traversing methods, .find() requires a selector argument. Pass '*' to retrieve all descendant elements when you need every node at any depth.
No. Only descendants are considered. If $('li.item-ii').find('li') runs on item II, item II itself is not included — only li elements nested inside it (A, B, 1, 2, 3, C in the official nested list demo).
Yes, since jQuery 1.6. .find(jQueryCollection) or .find(domElement) keeps only descendants that match nodes in the provided collection or element. Useful when intersecting a global selection with a scoped subtree.
Did you know?

jQuery’s .find() implements selector context — $("li.item-ii").find("li") is equivalent to $("li", "li.item-ii"). That means you can start with a broad selection, narrow to a container, then search inside it without writing a long compound selector from the document root.

Back to jQuery Traversing

Explore more DOM traversal methods as the collection grows.

Traversing hub →

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.

6 people found this page helpful