The all selector — written as "*" — matches every element in the search context. This tutorial covers official jQuery API demos, scoped searches with .find(), counting with .length, performance pitfalls, and safer alternatives for real projects.
01
Syntax
$("*")
02
Scope
.find("*")
03
Count
.length
04
Global
Document root
05
Body only
body *
06
Since 1.0
Core selector
Fundamentals
Introduction
jQuery revolutionized DOM scripting partly because of its selector engine. Instead of verbose document.getElementsByTagName calls, you write concise CSS-like strings inside $(). The simplest selector of all is the asterisk — the universal or all selector.
Available since jQuery 1.0, "*" means “give me every element.” That sounds convenient, but it comes with a serious caveat from the official documentation: the all selector is extremely slow on large pages unless you keep the context small. In this guide you will learn when it helps, when to avoid it, and how to scope it safely.
Concept
Understanding the All Selector
Passing "*" to $() tells jQuery to collect every element node in the current search context. On a fresh page load that context is usually the entire document — so html, head, body, and every nested tag become part of the result set.
The returned value is a jQuery object (a collection), not a single element. You can chain any jQuery method — .css(), .hide(), .each() — and they run on every matched node. To count matches without iterating, read .length.
⚠
Performance Warning
Browser extensions that inject extra DOM nodes (hidden divs, iframes) can inflate $("*").length. Always treat global counts as approximate on pages you do not fully control.
Foundation
📝 Syntax
Official jQuery API form (since 1.0):
jQuery
jQuery( "*" )
// shorthand:
$( "*" )
Parameters
"*" — the universal selector string; no other arguments required.
Return value
A jQuery object containing every matched element in the context.
Use .length to get the count as a number.
Common patterns
$( "*" ).length — count all nodes (demo / diagnostics).
$( "#box" ).find( "*" ) — all descendants inside #box.
$( "body *" ) — skip head but still match many body nodes.
$( "form *" ).filter( "input" ) — prefer filtering over bare * when you know the tag.
Cheat Sheet
⚡ Quick Reference
Goal
Code
Every element in document
$("*")
Elements inside a container
$("#test").find("*")
Skip head-only nodes
$("body *")
Count matches
$("*").length
Chain styling
$("*").css("border", "1px solid red")
Production-friendly
Use class, ID, or tag selectors instead
Compare
📋 Global $("*") vs Scoped .find("*")
Same asterisk, different roots — scoped searches are faster and exclude unrelated parts of the page.
Document
$("*")
Includes head, body, all tags
Body
$("body *")
Skips head-only nodes
Container
$("#test").find("*")
Official demo pattern
Better
$(".item")
Specific beats universal
Hands-On
Examples Gallery
Examples 1–2 follow the official jQuery API documentation. Examples 3–5 add counting, comparison, and production-minded alternatives. Open DevTools or use the Try-it links.
📚 Official jQuery Demos
Match every element globally or inside a container, then style and count.
Example 1 — Find Every Element in the Document
Official demo: add a red border to every element and prepend a count to body. Note that browser extensions injecting extra nodes can increase the count.
Every visible element gets a 3px red border
<h3>N elements found</h3> prepended to body (N varies by page size)
How It Works
$("*") builds a collection of every element. Chaining .css() applies the border to each one. .length returns how many nodes were matched — jQuery counts after the style is applied but does not change the count.
Example 2 — Find All Elements Inside #test
Official demo variant: exclude head, script, and other page chrome by scoping with .find("*") on a container.
Skipping .css() avoids unnecessary style recalculations. Comparing two counts shows how much scoping reduces the matched set.
Example 4 — $("*") vs $("body *")
Limiting to body descendants excludes head-only tags but still matches many nodes.
jQuery
console.log( "All nodes:", $( "*" ).length );
console.log( "Body descendants:", $( "body *" ).length );
// body * does NOT include <body> itself — only its children and below
All nodes: slightly higher (includes html, head, meta, title, etc.)
Body descendants: lower by a few head-only elements
How It Works
$("*") starts at the document element. $("body *") uses a descendant combinator — only nodes inside body match. Neither includes text nodes; jQuery selectors target elements only.
Example 5 — Prefer a Specific Selector Over *
When you know the tag or class you need, skip the universal selector entirely.
jQuery
// Slow intent: "every input somewhere on the page"
// $( "*" ).filter( "input" )
// Fast intent: target inputs directly
$( "#test input, #test button" ).css( "outline", "2px dashed green" );
// Or with a class when markup allows it:
// $( ".form-control" ).addClass( "highlight" );
Button inside #test gets green dashed outline
Other elements unchanged — no full-document scan
How It Works
.filter() after $("*") still pays the cost of collecting every element first. A direct selector like $("#test button") lets the browser skip unrelated nodes entirely.
Applications
🚀 Common Use Cases
DOM size diagnostics — log $("*").length during performance audits.
Teaching demos — visually highlight every node in a small example page.
Scoped resets — $("#widget").find("*").removeClass("active") inside a component shell.
Test fixtures — count children in unit-test HTML snippets with predictable markup.
Legacy migrations — temporary blanket selectors while refactoring to IDs and classes.
Print styles — rare cases where every element in a printable region needs a class before export.
🧠 How jQuery Resolves "*"
1
Parse selector
Sizzle (jQuery’s engine) sees * as “match any element type.”
Selector
2
Walk the DOM
Every element in the context is visited and added to the result set.
Traverse
3
Wrap nodes
Matched elements become a jQuery object ready for chaining.
Collection
4
*
Chain methods
Call .css(), .each(), or read .length on the collection.
Important
📝 Notes
Available since jQuery 1.0 — one of the original core selectors.
Official caution: extremely slow except when used by itself on small trees.
$("*") matches element nodes only — not text or comment nodes.
Browser extensions may inject extra elements and inflate global counts.
Chaining .filter() after * still collects every element first.
Modern alternative for counts: document.querySelectorAll("*").length — same breadth, no jQuery dependency.
Compatibility
Browser Support
The all selector "*" is part of CSS1 and jQuery 1.0+. Any browser that runs your jQuery version supports it — performance, not compatibility, is the main concern.
✓ jQuery 1.0+ · CSS1
jQuery All Selector ("*")
Supported everywhere jQuery runs — IE with legacy builds, all modern browsers, and current jQuery 3.x. Native equivalent: document.querySelectorAll('*').
100%Selector compatibility
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
"*" selectorUniversal
Bottom line: Compatibility is not the issue — scope your searches and prefer specific selectors in production. Use $('*') for small demos, diagnostics, or inside a narrow container.
Wrap Up
Conclusion
The jQuery all selector "*" matches every element in the search context. It mirrors the CSS universal selector and powers official demos that count or highlight entire DOM subtrees.
Treat global $("*") as a learning and debugging tool — not your default in production. Scope with .find("*"), compare counts with .length, and reach for IDs, classes, and tag selectors whenever you know what you are looking for.
Scope with $("#container").find("*") when you need every descendant
Use .length for counts without styling every node
Prefer $(".class") or $("#id") in production code
Keep demo pages small when illustrating *
Combine with .not() to exclude known nodes when necessary
❌ Don’t
Run $("*").css(...) on large live sites in production
Assume .filter() after * is as fast as a direct selector
Trust exact global counts on pages with third-party scripts or extensions
Use * when a tag selector like input would suffice
Forget that $("*") includes head and html
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about the all selector
Universal matching — use with intention.
5
Core concepts
*01
Syntax
$("*")
API
🔎02
Scope
.find("*")
Container
#03
Count
.length
Number
⚠04
Slow
Large DOM cost
Caution
🎯05
Prefer
ID / class / tag
Production
❓ Frequently Asked Questions
The all selector matches every element node in the search context. When you call $("*") at the document root, jQuery collects html, head, body, and every descendant — then returns a jQuery object you can chain with methods like .css() or .hide().
Yes. jQuery uses the same selector engine as modern browsers (Sizzle). The asterisk is the CSS universal selector — it matches any element type.
jQuery must visit every node in the context. On a large SPA or content-heavy page that can mean thousands of DOM lookups and object wrappers. The official docs warn it is extremely slow except when used alone on small trees.
Start from a container: $("#sidebar").find("*") or $("div.panel *"). Only descendants of that root are matched — fewer nodes, faster execution, clearer intent.
Yes when searching from the document root. $("body *") skips head-only nodes like title and link, but still includes script tags inside body.
Read the .length property on the jQuery object: var n = $("#test").find("*").length. It returns a number, not a collection.
Did you know?
jQuery’s official all-selector demo prepends the element count to body so you see the result immediately. The same pattern works with scoped $("#test").find("*").length — often a more useful number on real pages.