What is the difference between the Descendant selector and the :has selector?
From the documentation:
Descendant selector
Description: Selects all elements that are descendants of a given ancestor.
A descendant of an element could be a child, grandchild, great-grandchild, and so on, of that element.
:has
Description: Selects elements which contain at least one element that matches the specified selector.
The expression $('div:has(p)')
matches a <div>
if a <p>
exists anywhere among its descendants, not just as a direct child.
Even after reading the explanation, the difference is not clear to me. Can someone help me understand?
The descendant selector in div p
selects the p
descendants of the div
.
The :has()
selector in div:has(p)
selects the div
if it contains any p
elements.
The bold parts are all you need to know. The rest can be seen as mere conditions as to which elements of those types are selected.
In CSS selector terms, the key selector is the right-most outer simple selector. The kind of elements that get picked up by jQuery (or by a browser's CSS parser) is the one in the key selector.
In the first selector, the key is p
, because it's the right-most one, occurring after the descendant combinator (the space). This means a collection of p
elements will be returned.
In the case of :has()
, which is a pseudo-class, the p
is an "inner" simple selector that is part of the :has()
pseudo-class, not part of the entire "outer" selector. The key in that selector is therefore div
, not p
. This means a collection of div
elements will be returned, rather than p
elements in the first selector.
The descendants
-selector will select the actual descendants, while the :has
-selector will select the parent element(s) that contain the element within the has().