jQuery / Method / .children() - Select Direct Child Elements
jQuery's .children() returns a new jQuery object containing only the selected elements' immediate child elements. Pass a selector, as in .children(".hot"), to keep matching children. Distinguish it from .find() for deeper descendants and .contents() for direct child nodes including text and comments.
Move one level down and filter the candidates
The .children() documentation limits traversal to one level below each starting element. Without an argument, all immediate element children are returned regardless of tag. Neither the starting element itself nor grandchildren inside its children are automatically included.
The argument filters the direct candidates already found. .children(".hot") does not keep descending until it encounters that class. Multiple starting parents contribute their immediate children, so constrain the initial selection when working on one particular card.
| Expression | Scope | Initial result |
|---|---|---|
| $("#card").children() | All immediate element children | title, body, action |
| $("#card").children(".hot") | Immediate children with hot | title |
| $("#card").find(".hot") | Hot descendants at multiple depths | title, nested |
| $("#card").contents() | Immediate element, text and comment nodes | Includes text and comments |
Run the complete nested-card example
Save all the code as UTF-8 in children-demo.html and open it in a browser. No installation is needed, but an internet connection is required to load the official jQuery file from its Content Delivery Network (CDN). The code uses 4.0.0. Selection, filtering, insertion, reset and comparison snippets were executed with both 3.7.1 and 4.0.0.
card has three direct elements: p with ID title, div with ID body and button with ID action. nested is inside body, making it a grandchild of card. Intro text and a comment distinguish elements from other nodes. The hot class on card itself also does not put it in a child selection.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Direct children and deeper descendants</title>
<style>
body { font: 16px/1.6 sans-serif; margin: 24px; }
#card { border: 2px solid #aaa; padding: 16px; max-width: 600px; }
#card > * { display: block; padding: 8px; margin: 8px 0; border: 1px solid #ddd; }
#card .marked { outline: 3px solid #ba6900; background: #fff5d6; }
button { padding: 8px; margin: 4px; }
</style>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
<h1>Direct children and deeper descendants</h1>
<div id="card" class="hot">
Intro text
<!-- A comment is not an element. -->
<p id="title" class="hot">Direct paragraph</p>
<div id="body"><p id="nested" class="hot">Nested paragraph</p></div>
<button type="button" id="action">Direct button</button>
</div>
<button type="button" id="all">All direct children</button>
<button type="button" id="hot">Direct .hot children</button>
<button type="button" id="deep">All .hot descendants</button>
<button type="button" id="add">Add direct .hot paragraph</button>
<button type="button" id="reset">Reset</button>
<p id="result" aria-live="polite"></p>
<script>
$(function () {
function show($chosen) {
$("#card").find("*").removeClass("marked");
$chosen.addClass("marked");
const ids = $chosen.map((_, item) => item.id).get().join(", ");
$("#result").text(`${ids || "none"} | ${$chosen.length}`);
}
function direct() {
show($("#card").children());
}
$("#all").on("click", direct);
$("#hot").on("click", () => show($("#card").children(".hot")));
$("#deep").on("click", () => show($("#card").find(".hot")));
$("#add").on("click", function () {
if (!$("#extra").length) {
$("<p>").attr("id", "extra").addClass("hot").text("Added paragraph").appendTo("#card");
}
direct();
});
$("#reset").on("click", function () {
$("#extra").remove();
direct();
});
direct();
});
</script>
</body>
</html>
Initially, the three immediate elements are outlined. Highlighting body also puts its inner content over that background, but body is the selected element; nested is not separately selected.
title, body, action | 3
- All direct children displays
title, body, action | 3. - Direct .hot children keeps only matching immediate children:
title | 1. - All .hot descendants traverses deeper with .find():
title, nested | 2. The hot card itself remains excluded. - Add direct .hot paragraph appends a p to card and queries its direct children again:
title, body, action, extra | 4. Checking the extra ID prevents duplicates on repeated clicks. - After adding, Direct .hot children yields
title, extra | 2. Reset removes only extra and restores the original three-child selection.
show clears marked from previous descendants before highlighting the new set. Switching between direct and deeper selections therefore leaves no old highlights. Reset does not replace the original content or button.
Compare .find() and .contents()
After Reset, run this fragment in the developer console. Each line prints the selected element IDs.
const ids = $set => $set.map((_, item) => item.id).get().join(", ");
console.log(ids($("#card").children()));
console.log(ids($("#card").children(".hot")));
console.log(ids($("#card").find(".hot")));
title, body, action
title
title, nested
.find() searches descendants across levels, while .children() moves down once. For exactly two levels, you can use $("#card").children().children(".hot"). Here that returns only nested, but adding an intermediate wrapper changes the result.
.contents() gets direct nodes including text and comments. Nodes are the units of the Document Object Model (DOM), covering elements as well as text and comments. Element class and style operations do not apply identically to text or comment nodes, so do not treat every node as an element.
Check empty results, timing and structure
A missing starting element or one without element children produces an empty result. action contains only text, so .children() is empty; that does not mean its text disappeared. For missing matches, inspect intermediate wrappers such as div or ul and whether the class belongs to the parent, child or grandchild.
Selections do not update automatically. A saved set of three children retains its length after another p is added. Query again as direct does for current children. If nothing happens, check jQuery loading in Network and errors in Console. For asynchronous insertion, select after insertion completes.




