How does the :has() selector choose its matching elements?
Quick answer
:has() matches an element when a selector inside its parentheses matches in the relationship described from that element. For example, article:has(img) selects an article with a matching descendant image, while article:has(> img) requires a direct child. Combinators such as + can describe sibling relationships. To debug an unexpected match, identify the candidate element, its anchor, and the relationship each selector requires. [S1][S2]
The question, the details, the next step.
A practical checklist
Identify the element type or selector before
:has(); these are the candidates being tested.Treat each candidate as the anchor, then trace the relationship inside the parentheses from that anchor.
Check whether the condition means any descendant, a direct child (
>), or a sibling such as the next adjacent sibling (+).Look for an omitted leading combinator: without one, the relative selector implies a descendant relationship.
Check every selector in a selector list for syntax errors, which can affect a non-forgiving list.
Compare the expected matches with the actual DOM structure, not only the visual layout.
A few more useful answers
Does `:has(img)` mean the image must be a direct child?
No. Without a leading combinator, the relative selector implies a descendant relationship, so nested images can qualify. Use :has(> img) when the image must be a direct child. [S2]
Can `:has()` test a sibling instead of a descendant?
What does this explanation establish about browser support?
The cited extracts explain how relative matching and relationships work; they do not establish browser support for a specific browser, version, or project environment.
Sources
References used for this guide.
- [S1] Pseudo-classes — CSS reference — MDN developer.mozilla.org · Checked
- [S2] CSS selector structure — MDN developer.mozilla.org · Checked
