jQuery Selectors

This section documents jQuery 3.x (the current major line — no specific patch version is pinned). This content was generated with the assistance of AI and should be verified against the official jQuery API reference before being relied on in production, since API details and deprecations continue to change between releases.

jQuery is legacy-leaning: modern browsers implement native equivalents for almost everything it does (querySelectorAll, classList, fetch, addEventListener, append/prepend/remove, the Web Animations API), and most current stacks — Bootstrap 5 included — have dropped it. Prefer the native APIs for new work; this reference is aimed at reading, maintaining, or incrementally migrating code that already uses jQuery. Every page ends with a Modern equivalent note pointing at the native replacement.

This section’s bibliography lists the reference material consulted while preparing these pages.

$(selector) runs the string through jQuery’s selector engine and returns the matched elements as a wrapped set. Anything the browser’s own querySelectorAll understands works unchanged; jQuery then adds a layer of extra pseudo-selectors of its own. Check a selection worked with .length.

Basic and hierarchy selectors

These are standard CSS — jQuery hands them straight to the native engine, so they are the fast path.

$('p')                 // type: every <p>
$('#main')             // id: the element with id="main"
$('.card')             // class: every element with class "card"
$('*')                 // every element (rarely useful)
$('h1, h2, .lead')     // grouping: union of all three

$('nav a')             // descendant: <a> anywhere inside <nav>
$('ul > li')           // child: <li> that is a direct child of <ul>
$('h2 + p')            // adjacent sibling: <p> immediately after an <h2>
$('h2 ~ p')            // general sibling: every <p> after an <h2>, same parent

Attribute selectors

Also standard CSS:

$('input[required]')          // has the attribute at all
$('a[target="_blank"]')       // exact value
$('a[href^="https://"]')      // value starts with
$('img[src$=".png"]')         // value ends with
$('div[class*="col-"]')       // value contains substring
$('[lang~="en"]')             // value is one of a space-separated list

jQuery filter and pseudo-selectors

The selectors in this section marked (jQuery extension) are not valid CSS. querySelectorAll cannot parse them, so jQuery falls back to its own JavaScript engine and filters in script — measurably slower on large documents. Prefer a standard selector plus a traversal method (.first(), .eq(), .filter()) where one exists.

Positional and content filters

$('li:first')          // (jQuery extension) first <li> in the whole matched set
$('li:last')           // (jQuery extension) last one
$('li:eq(2)')          // (jQuery extension) the element at index 2 (0-based)
$('li:gt(1)')          // (jQuery extension) index greater than 1
$('li:lt(3)')          // (jQuery extension) index less than 3
$('tr:even')           // (jQuery extension) even indexes (0, 2, 4, ...)
$('tr:odd')            // (jQuery extension) odd indexes (1, 3, 5, ...)
$('p:not(.intro)')     // :not() IS standard CSS; jQuery also accepts complex args
$('ul:has(li.active)') // (jQuery extension) <ul> that contains a matching <li>
$('li:contains("Buy")')// (jQuery extension) element whose text contains the string
$(':header')           // (jQuery extension) any <h1>..<h6>
$('div:animated')      // (jQuery extension) elements with an animation in progress

The standard-CSS replacements: li:first$('li').first(), li:eq(2)$('li').eq(2), p:not(.intro) → works natively too.

Form and state pseudo-selectors

$(':input')            // (jQuery extension) <input>, <textarea>, <select>, <button>
$(':checkbox')         // (jQuery extension) shorthand for input[type="checkbox"]
$(':radio')            // (jQuery extension) shorthand for input[type="radio"]
$('option:selected')   // :selected -- selected <option> elements
$(':checked')          // checked checkboxes / radios (standard CSS)
$(':disabled')         // disabled form controls (standard CSS)
$(':enabled')          // enabled form controls (standard CSS)
$('div:visible')       // (jQuery extension) takes up space in the layout
$('div:hidden')        // (jQuery extension) display:none, or zero width/height

:visible / :hidden judge rendered layout (an element with visibility:hidden still counts as visible because it occupies space); they are jQuery-specific and have no native selector equivalent — use el.offsetParent !== null or getComputedStyle checks instead.

Verifying a selection

const $rows = $('#report tbody tr');
if ($rows.length === 0) {
  console.warn('selector matched nothing -- check the markup or timing');
}

An empty set is not an error in jQuery: every method silently does nothing. That is convenient but hides typos, so assert .length when a selection is expected to match.

Modern equivalent

document.querySelectorAll(cssSelector) covers every standard selector above and returns a static NodeList you can iterate with for…​of or spread into an array. The jQuery extensions (:eq(), :contains(), :visible, and the rest) have no native selector counterpart — express those as a standard selector followed by an Array.prototype.filter. The one exception is :has(), which is now standard CSS and supported by current browsers. See Web programming basics and Selectors & Specificity.