:has() - CSS Selector

:has()

Summary of characteristics of the :has() selector

Quick description
Pseudo-class targeting an element of which at least one of the children corresponds to one of the selectors passed as an argument.
Status
Standard
W3C Module
Selectors
Document status: WD (Working Draft)

Description of the :has() pseudo-class..

The pseudo-class :has() targets elements based on their child(ren).
For example, the selector td:has(img) targets table cells that contain at least one image.

Several selectors can be listed in the parentheses of :has(). This list is tolerant, which means that if the syntax of some of the listed selectors is incorrect, it doesn’t invalidate the whole expression: :has() will process the rest of the list while ignoring the faulty selectors.
It’s enough for at least one of the selectors provided in the parameters of :has() to be true.

:has() thus allows you to target an element based on its content. Don't confuse the following two syntaxes:
td img targets images contained within a cell,
td:has(img) targets cells that contain an image.

The selector :has() can't be nested inside another selector :has(). Similarly, pseudo-elements can't appear in the list of selectors. In fact, several pseudo-elements target elements based on their parents, and including them in :has()'s parameters can create endless loops.

Performance.

The selector :has() still has a drawback: it's not very efficient because it forces the browser to re-explore the DOM tree a second time, at least partially. However, browsers have now taken this issue into account, and the performance is barely affected by using :has().

Specificity of the selector :has().

Even though it's a pseudo-class, the specificity of :has() isn't fixed: it depends on its list of selectors. :has() actually takes the specificity of the most specific selector among the ones given to it.

td:has(img) {...} Specificity = 2 td:has(.class) {...} Specificity = 11 td:has(#id, .class) {...} Specificity = 101

Example of use of the pseudo-class :has().

Target the cells of a table except the last one in each row.

The CSS code used for this example targets cells that are followed by another cell, in other words all cells except the last one in each row.

A1B1C1D1E1
A2B2C2D2E2

Target forms that have a password entry.

The goal of this example is to add a message (here in red) to forms that include a password entry, that is, an input type="password" tag.
The selector is a bit tricky because it also involves the pseudo-element ::after.

In a form, target an area other than the one being tested.

Check the box in the form below: the input field "Type of permit" turns blue. So we were able to act on a different area than the one being tested. :has() is the only way to do this.

Driver's license
 

Browser compatibility with :has().

Support for the pseudo-class :has() is now well handled by most major browsers.

Column 1
Browser support for the :has() pseudo-class selector, which targets elements based on their children.
1
:has()
pseudo-class
Estimated overall support.
94%

Browsers on computers :

Mobile browsers :

Outdated or marginal browsers :

Internet Explorer

UC Browser pour Androïd

Opéra Mobile

QQ Browser

Baidu Browser

Safari

Samsung Internet

Opéra

Safari sur IOS

Firefox

Firefox pour Androïd

Chrome

Edge

Androïd Brower

Chrome pour Androïd

KaiOS Browser

Opéra mini

Historic of the :has() pseudo-class.

  • Selectors Level 4

    This specification module defines new selectors that can be used in CSS.

    Regarding :has() Introduction of the :has() pseudo-class in the level 4 selectors specification.
    WD
    September 29, 2011
    Working Draft.
    CR
    PR
    REC

Other conditional pseudo-classes.

⚠
:any()
Obsolete pseudo-class, replaced by the new pseudo-class :is().
:defined
Pseudo-class targeting defined elements (variable concept depending on the language).
:has()
Pseudo-class targeting an element of which at least one of the children corresponds to one of the selectors passed as an argument.
:is()
Pseudo-class allowing complex syntaxes involving several selectors to be simplified.
⚠
:matches()
Obsolete pseudo-class, replaced by the new pseudo-classe :is().
:not()
Pseudo-class to reverse the action of a selector.
:where()
Pseudo-class allowing you to group selectors (equivalent to logical OR).