Here, here, CSS :has() pseudo-class here she comes

Original link:

by zhangxinxu from Xin Space-Xin Life

This article welcomes sharing and aggregation. It is not necessary to reprint the full text. The copyright is respected. The circle is so big. If you need it urgently, you can contact for authorization.

cloud and ladder

1. Background and summary of the story

The :has() pseudo-class is a very powerful pseudo-class, because it can implement functions like “parent selector” and “previous sibling selector”, which will have a subversive impact on CSS development.

The specification for the :has() pseudo-class was made early, but it has never been supported.

The main reason is that browser manufacturers are concerned about the impact of performance. You must know that the rendering of the DOM is from top to bottom, from the inside out.

The characteristic of the :has() pseudo-class is that child elements affect ancestor elements, and the preceding sibling elements affect the following sibling elements. If you want to render successfully, you must load the child element or the rear element, which will inevitably affect the The rendering speed of the web page.

Therefore, at the beginning :has() pseudo-class makes it clear that this pseudo-class cannot be used in CSS styles, but can only be used in DOM methods like document.querySelector() .

In 1998, when the CSS2 specification was formulated, it brought a CSS selector such as a>b , which can match child elements, which is very practical. There was a lot of discussion at that time. When can a selector that matches the parent element appear, because Once this capability is supported, many interactions that would otherwise be handled by JS code can be omitted.

As a result, the first wait is 24 years, that is, in 2022, as the Safari browser began to support the :has() pseudo-class, the CSS world opened the curtain to implement a function similar to the parent selector.

Why did you suddenly support it?

Then I have to mention a well-known private consulting firm called Igalia, known for its contribution and commitment to open source and open standards.

For example, generators in JavaScript, async/await, temporal, grid layout in CSS, and even MathML in Chrome browser are all gnawed by this company under the sponsorship of other companies.

The :has() pseudo-class is another masterpiece of this company, which solves performance problems that browsers have been unable to solve for decades.

So, what else can be said, praise, and cheers for the arrival of the :has() pseudo-class era.

As I write this, Safari 15.4 and Chrome 105 have completed support for the :has() pseudo-class.

Compatibility of the :has pseudo-class

With the current browser version update speed, within a year, the :has() pseudo-class can be used in actual projects. This is a CSS pseudo-class that must be learned, which can reduce development costs in many occasions.

Second, the syntax and role of the :has() pseudo-class

The syntax of the :has() pseudo-class is relatively simple, and it is easy to learn, because its semantics are very clear and consistent with the rendering performance, which means that if a certain element matches a certain selector, it will match.

As a simple example, the following CSS code indicates that an <a> element will match if an <img> element is inside an <a> element.

 a:has(img) { display: block; }

We can use this selector to easily distinguish between text links and image links and set different CSS styles.

The :has() pseudo-class supports all CSS selectors, for example:

 a:has(> img) { display: block; }

<a> elements that indicate that the matching child element is an <img> element will be matched, and further descendant elements will not be considered.

Note that the parameter of the :has pseudo-class in the above code, the selector > is written directly at the front of the parameter, not a:has(a > img) .

You can understand that there is an invisible :scope pseudo-class at the front of the parameter of the :has() pseudo-class, so it is illegal to write a:has(a > img) .

Similarly, we can also use selectors such as + or ~ to achieve the effect of “front sibling selector”, that is, select the preceding element according to the following sibling elements. E.g:

 h5:has(+ p) { font-size: 1rem; }

Indicates to match an <h5> element followed by a <p> element.

The :has() pseudo-class also supports complex selectors and selector lists, such as:

 article:has(h5, p) { background-color: #f0f3f9; }

Indicates that it only needs to have an <h5> element or a <p> element in the <article> element to match, it is an OR relationship, not an AND. If you want the relationship with and, that is, the <h5> element and the <p> element are matched at the same time, you can try the following writing method:

 article:has(h5):has(p) { background-color: #f0f3f9; }

The :has() pseudo-class can also be mixed with other pseudo-classes, such as :checked , :enabled , etc., and even with other logic pseudo-classes, such as:

 section:not(:has(h5)) {   border: skyblue solid; } section:has(:not(h5)) {   color: deepskyblue; }

Note that the meanings of the two selectors above are different.

The former selector indicates that <section> elements that do not contain <h5> elements have a sky blue border, while the latter indicates that <section> elements that contain elements that are not <h5> elements have a dark sky blue color.

Let’s say we now have HTML code that looks like this:

 <section>   <p>Only the p element</p> </section> <section>   <h5>Not only h5 elements</h5>   <p>There is also a p element</p> </section>

At this time, only the <section> element above will have a border, because only this <section> element does not contain an <h5> element, and the color change will occur in two <section> elements at the same time, because these two <section> elements There are elements that are not descendants of <h5> .

The rendering effect at this time is shown in the following figure.

:not :has render

As for the actual application scenarios of the :has() pseudo-class, there are too many, such as interaction matching, boundary scene judgment, etc., because there are too many examples in web development that need to generate linkage responses based on changes in certain elements.

With the :has() pseudo-class, theoretically any DOM changes in the page can be sensed by other DOM elements, for example:

 body:has(.eleA-active) .eleB {   background-color: var(--primary-color);   color: #fff; }

Do you understand right away?

Three, welcome to forward, welcome to share

At present, Firefox can also experience the :has() pseudo-class with experimental support, which means that all modern browsers support the :has() pseudo-class is a sure thing.

:has under Firefox browser

So, please be patient, last night at this time next year, you can rest assured to use it in internal projects or experimental projects. At that time, our development costs will be further reduced.

So excited and looking forward to it.

However, I am still vaguely worried about whether there will be performance problems if it is used on a large scale.

Let’s see this in practice in the future.

Okay, enough to say.

Welcome to forward, welcome to share.


This article is an original article, welcome to share, do not reprint in full text, if you really like it, you can collect it, it will never expire, and will update knowledge points and correct errors in time, and the reading experience will be better.

The address of this article:

(End of this article)

This article is reprinted from:
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment