Select Elements by Child Tag Using jQuery :has()

The jQuery :has() selector allows developers to filter and select parent elements based on whether they contain specific descendant HTML tags. This guide explains the core syntax of the :has() selector, demonstrates practical code examples for selecting parent containers, and highlights the difference between the :has() pseudo-class selector and the .has() traversal method.

Understanding the :has() Selector Syntax

The :has() selector targets elements that contain at least one element matching the selector provided inside the parentheses.

The basic syntax is:

$("parentElement:has(childSelector)")
  • parentElement: The element or elements you want to select.
  • childSelector: The tag, class, ID, or attribute that must be nested inside the parent element.

Basic Example: Selecting Containers with a Specific Tag

Suppose you have multiple <div> elements, but you only want to style or manipulate the ones containing an <a> (anchor) tag.

HTML Structure

<div class="box">
  <p>This box only has text.</p>
</div>

<div class="box">
  <p>This box has a <a href="#">link</a>.</p>
</div>

<div class="box">
  <span>No links here either.</span>
</div>

jQuery Implementation

To target only the .box that contains an <a> tag, use:

$(".box:has(a)").css("border", "2px solid green");

This code searches all elements with the class .box, checks for any nested <a> elements at any depth, and applies the green border only to the matching parent <div>.

Selecting by Multiple or Nested Descendant Tags

You can use standard CSS selector rules inside the :has() parameter:

  • Direct Child Tag: To ensure the tag is an immediate child rather than deeply nested, use the child combinator (>):
    $("ul:has(> li.active)").addClass("highlight");
  • Multiple Tag Options: To select elements containing either an <h1> or an <h2> tag:
    $("section:has(h1, h2)").addClass("has-heading");

The :has() Selector vs. the .has() Method

jQuery provides two ways to achieve this functionality: the :has() selector and the .has() filtering method.

1. Pseudo-Class Selector

$("div:has(p)").hide();

2. Method Chaining

$("div").has("p").hide();

While both yield the exact same result, using the .has() method is generally faster in performance because it allows the initial selector ($("div")) to leverage native browser querySelectorAll implementation before jQuery applies the filter.