Almost every line of jQuery starts by selecting something: “find the menu”, “find every price”, “find the checked boxes”. jQuery selectors use the same syntax as CSS, so if you know CSS Selectors you already know most of this lesson. Here you will practise the common patterns, learn how to check whether anything matched, and see the modern way to pick one element out of many.
CSS selectors work as they are
Pass any valid CSS selector string to $(). jQuery hands most of them to the browser’s own fast querySelectorAll() and wraps the result.
| Selector | Selects |
|---|---|
$('#cart') | The element with id="cart" |
$('.price') | Every element with the class price |
$('li') | Every <li> element |
$('#menu a') | Links anywhere inside #menu (descendants) |
$('ul > li') | Only direct <li> children of a list |
$('h2, h3') | All <h2> and <h3> elements (a group) |
$('input[type="email"]') | Inputs whose type attribute is email |
$('a[href^="https"]') | Links whose href starts with https |
$('input:checked') | Ticked checkboxes and selected radio buttons |
$('li:not(.sold-out)') | List items without the class sold-out |
Try these jQuery selectors in the playground below. Each button runs a different selector and highlights what it found, along with the count.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Selector playground</title>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
li { padding: 2px 6px; }
.hit { background: #ffe58a; outline: 2px solid #e0a800; }
button { margin: 2px; }
</style>
</head>
<body>
<ul id="cities">
<li class="south" data-state="TN">Chennai</li>
<li class="south" data-state="KA">Bengaluru</li>
<li class="north" data-state="DL">Delhi</li>
<li class="south capital" data-state="KL">Thiruvananthapuram</li>
<li class="west" data-state="MH">Mumbai</li>
</ul>
<p>
<button type="button" data-sel="li">li</button>
<button type="button" data-sel=".south">.south</button>
<button type="button" data-sel=".south.capital">.south.capital</button>
<button type="button" data-sel="li:not(.south)">li:not(.south)</button>
<button type="button" data-sel='[data-state="KA"]'>[data-state="KA"]</button>
<button type="button" data-sel=".east">.east</button>
</p>
<p id="result">Click a selector.</p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$('button[data-sel]').on('click', (event) => {
const selector = $(event.currentTarget).attr('data-sel');
$('#cities li').removeClass('hit'); // clear old highlights
const $found = $('#cities').find(selector).addClass('hit');
$('#result').text(`$('${selector}') matched ${$found.length} element(s).`);
});
</script>
</body>
</html>Try .east: nothing matches, the count is 0, and there is no error. That is handy, but it can also hide typos. When something “does nothing”, check .length first.
Checking whether jQuery selectors matched
Because a jQuery object always exists, if ($('#banner')) is always true – an empty object is still an object. Test the length instead:
if ($('#banner').length) {
// the banner exists on this page, so it is safe to set it up
$('#banner').addClass('ready');
}
// Plain JavaScript equivalent
const banner = document.querySelector('#banner');
if (banner) {
banner.classList.add('ready');
}Picking one element from many
Older tutorials use jQuery-only pseudo-selectors such as :first, :last, :eq(2), :even and :odd. These were deprecated in jQuery 3.4 because the browser cannot run them natively. Use the matching methods instead, which work on any set:
.first()and.last()– the first or last element of the set..eq(index)– the element at a zero-based position;.eq(-1)counts from the end..even()and.odd()– elements at even or odd indexes (added in jQuery 3.5)..filter(selector)– keep only the elements that also match another selector.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Rows with .even(), .eq() and .filter()</title>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
table { border-collapse: collapse; }
td, th { border: 1px solid #ccc; padding: 6px 10px; }
.zebra { background: #eef4ff; }
.top { font-weight: bold; color: #0a7a3d; }
</style>
</head>
<body>
<table>
<thead><tr><th>Item</th><th>Price (₹)</th></tr></thead>
<tbody>
<tr><td>Filter coffee</td><td>30</td></tr>
<tr><td>Medu vada</td><td>40</td></tr>
<tr><td>Rava dosa</td><td>90</td></tr>
<tr><td>Lemon rice</td><td>70</td></tr>
</tbody>
</table>
<button id="stripe" type="button">Check prices</button>
<p id="note"></p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$('#stripe').on('click', () => {
const $rows = $('tbody tr');
// Index 0, 2, … → the 1st and 3rd rows on screen
$rows.even().addClass('zebra');
// Third row (index 2)
$rows.eq(2).find('td').first().append(' ⭐');
// Rows whose price cell is above 50
const $costly = $rows.filter((i, row) => Number($(row).find('td').last().text()) > 50);
$costly.addClass('top');
$('#note').text(`${$costly.length} items cost more than ₹50.`);
});
</script>
</body>
</html>Watch out: Indexes start at 0. So .even() selects the 1st, 3rd and 5th rows you see – which humans would call “odd” rows. CSS :nth-child(odd) counts from 1 and selects the same rows. Mixing the two systems is a classic source of off-by-one bugs.
Searching inside an element
To search only inside one part of the page, select the container and call .find() (more in jQuery Traversing): $('#cart').find('.price'). You may also see the two-argument form $('.price', '#cart'), which does the same thing. Searching inside a container is clearer and avoids touching similar elements elsewhere on the page.
If you will use a selection several times, store it in a variable instead of asking jQuery to search again. Many developers start such names with $, as in const $menu = $('#menu');, as a reminder that it holds a jQuery object, not a plain element.
jQuery-only selectors
A few jQuery selectors are not part of CSS, such as :visible, :hidden and :input. They are useful – :visible finds elements that currently take up space on the page – but the browser cannot run them natively, so jQuery must check each element itself. That is slower on large pages and means the selector would fail in plain querySelectorAll().
The recommended pattern is to select with a normal CSS selector first, then narrow the set: write $('.panel').filter(':visible') rather than $('.panel:visible'). The result is the same, but the first step stays fast.
Ids with special characters
CSS gives special meaning to characters such as ., : and #. If an id contains one – for example id="order.42" – the selector $('#order.42') looks for an element with id order and class 42. Use $.escapeSelector() to escape such values, especially when they come from data: $('#' + $.escapeSelector('order.42')).
Tip: You can also wrap elements you already have: $(element) turns a DOM element (for example event.currentTarget) into a jQuery object. To go the other way, $menu[0] or $menu.get(0) gives you the plain DOM element.
