Himanshu SharmaSoftware engineer
Let’s talk

jQuery · Lesson 5 of 45

Selecting elements with jQuery

Find elements with jQuery using CSS selectors by id, class, tag, attribute and pseudo-class, plus jQuery-only selectors such as :visible and :has().

14 minSelecting elementsUpdated 23 October 2026

By the end of this lessonWrite selectors that match exactly the elements you want, and use a context or .find() to search inside part of the page.

Any CSS selector works

$() hands your selector to the browser's own selector engine, so anything you can write in a stylesheet works. Here are the everyday ones:

html
<div id="shop">
  <h2 class="title">Fruit</h2>
  <ul>
    <li class="fruit" data-price="40">Apple</li>
    <li class="fruit sale" data-price="10">Banana</li>
    <li class="fruit" data-price="90">Mango</li>
  </ul>
  <a href="https://example.com">Supplier</a>
  <a href="/about/">About</a>
</div>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  console.log("#shop        ", $("#shop").length);
  console.log(".fruit       ", $(".fruit").length);
  console.log("li           ", $("li").length);
  console.log(".fruit.sale  ", $(".fruit.sale").text());
  console.log("#shop li     ", $("#shop li").length);
  console.log("ul > li      ", $("ul > li").length);
  console.log("[data-price] ", $("[data-price]").length);
  console.log("[data-price='90']", $("[data-price='90']").text());
  console.log("a[href^=http]", $("a[href^='http']").text());
</script>
result
#shop         1
.fruit        3
li            3
.fruit.sale   Banana
#shop li      3
ul > li       3
[data-price]  3
[data-price='90'] Mango
a[href^=http] Supplier

A quick reminder of what each does:

  • #shop selects by id; ids should be unique, so this finds at most one.
  • .fruit selects by class. .fruit.sale (no space) means elements with both classes.
  • li selects by tag name.
  • #shop li (a space) means li elements anywhere inside #shop: descendants.
  • ul > li means li elements that are direct children of a ul.
  • [data-price] selects elements that have that attribute; [data-price='90'] requires that value.
  • a[href^='http'] matches links whose href starts with http. Use $= for "ends with" and *= for "contains".

Selecting several groups

A comma combines selectors, exactly as in CSS:

html
<h1>Heading</h1>
<h2>Sub heading</h2>
<p class="lead">Intro</p>
<p>Body</p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("h1, h2, .lead").css("color", "teal");
  console.log($("h1, h2, .lead").length, "elements coloured");
</script>
result
3 elements coloured

The result is one jQuery object with the elements in document order, not the order you listed the selectors.

Pseudo-classes

Standard CSS pseudo-classes are very useful for forms and lists:

html
<ul id="steps">
  <li>One</li><li>Two</li><li>Three</li><li>Four</li><li>Five</li>
</ul>
<label><input type="checkbox" checked> Email me</label>
<label><input type="checkbox"> Text me</label>
<input type="text" disabled value="locked">

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  console.log("first-child :", $("#steps li:first-child").text());
  console.log("last-child  :", $("#steps li:last-child").text());
  console.log("nth-child(2n):", $("#steps li:nth-child(2n)").text());
  console.log("not(:first-child):", $("#steps li:not(:first-child)").length);
  console.log("checked     :", $("input:checked").length);
  console.log("disabled    :", $("input:disabled").val());
</script>
result
first-child : One
last-child  : Five
nth-child(2n): TwoFour
not(:first-child): 4
checked     : 1
disabled    : locked

:nth-child(2n) picks every second item (the even positions, counting from 1). :not() removes matches. :checked and :disabled reflect the current state of form controls, so they are perfect for reading forms.

jQuery's own selectors

jQuery also understands a few selectors that are not part of CSS. You will see them in older code:

html
<p>Visible text</p>
<p style="display:none">Hidden text</p>
<div class="card"><img src="" alt=""></div>
<div class="card">No image</div>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  console.log(":visible   ", $("p:visible").length);
  console.log(":hidden    ", $("p:hidden").text());
  console.log(":contains  ", $("p:contains('Visible')").length);
  console.log(":has(img)  ", $(".card:has(img)").length);
</script>
result
:visible    1
:hidden     Hidden text
:contains   1
:has(img)   1
  • :visible and :hidden check whether an element takes up space on the page.
  • :contains('text') matches elements whose text includes that string (case-sensitive).
  • :has(img) matches elements that contain an img. Modern browsers now support :has() in CSS too.

These work, but because jQuery has to check them in JavaScript, they are slower than standard selectors, especially on large pages. A good habit is to select with a fast CSS selector first and then filter, which the next lesson shows. You may also see :first, :last, :eq(2), :even and :odd in old code. They still work in jQuery 4 but have been deprecated since jQuery 3.4; use the methods .first(), .last(), .eq(), .even() and .odd() instead.

Searching inside an element

Often you want to find things inside one part of the page, such as the form the user is working in. Use .find():

html
<form id="login"><input name="email"><input name="password" type="password"></form>
<form id="search"><input name="q"></form>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  const $login = $("#login");
  console.log("inputs in #login:", $login.find("input").length);
  console.log("same with context:", $("input", $login).length);
  console.log("all inputs:", $("input").length);
</script>
result
inputs in #login: 2
same with context: 2
all inputs: 3

$("input", $login) passes a context as the second argument; it does the same as $login.find("input"). Most people find .find() easier to read.

Special characters in ids and classes

If an id contains characters that mean something in CSS, such as a dot or a colon, escape them or the selector breaks. $.escapeSelector() does it for you:

html
<p id="price.total">250</p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  console.log("unescaped:", $("#price.total").length);
  console.log("escaped:", $("#" + $.escapeSelector("price.total")).text());
</script>
result
unescaped: 0
escaped: 250

Without escaping, #price.total means "id price with class total", which does not exist.

Common mistakes

  • Forgetting the # or .: $("cart") looks for a <cart> element.
  • Adding a space by accident: .fruit .sale (descendant) is not .fruit.sale (both classes).
  • Using duplicate ids. $("#x") returns only the first; use a class for repeated elements.
  • Relying on slow jQuery-only selectors in loops on large pages.

Exercise

Using the shop example from the start of this lesson, log the names of all fruits whose data-price is not 90, using one selector.

Show one possible answer
javascript
console.log($(".fruit:not([data-price='90'])").text());

The output is AppleBanana. :not() accepts any selector, including attribute selectors.

Key points

  • $() accepts any CSS selector the browser understands: #id, .class, tag, [attribute], descendants, :nth-child() and more.
  • Combine selectors with a comma to select several groups at once.
  • jQuery adds a few extra selectors, such as :visible, :hidden, :contains() and :has(), but they are slower than plain CSS selectors.
  • To search inside one element, use $(parent).find("selector") rather than repeating a long selector.

Check yourself

1. Which selector finds the element with id="cart"?
2. What does $("input[type=checkbox]:checked") select?
3. What does $("nav a, footer a") select?
4. Which is a jQuery extension, not a standard CSS selector?