Use the :is() or :where() pseudo-class to make the scoped style still match globally

Original link: https://www.zhangxinxu.com/wordpress/2022/09/css-is-where-scoped-style/

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10535 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.

Bear and Rabbit, cover image

I. Introduction

In front-end frameworks such as Vue or React, in order to ensure the uniqueness of the style, that is, to have its own independent CSS scope, the component module will use the syntax of <style scoped> . The scoped attribute is an attribute supported by the Chrome browser for a short time. , which can achieve CSS scope effects, and was later abandoned.

Now used by frameworks to indicate that this piece of CSS is private within a module.

Browsers do not support this property, so how does the framework implement the CSS scope function?

The method is to add a random attribute selector to the CSS selector in the <style> element with the scoped attribute set, and then add the attribute name of the same name to the template HTML in the module, so it can be matched.

As shown in the figure below:

Random attributes and corresponding attribute selectors

In most cases, there is no problem with this operation.

But sometimes, the DOM elements in the page are not ready-made, but dynamically generated. At this time, the framework cannot add random attributes.

This scenario mostly occurs in third-party components, or in development scenarios that require direct DOM processing.

For example, if you have the following requirements, you want to reset the color of the radio button of a third-party component to various status colors:

Colored radio buttons

We open the console to view the corresponding HTML structure, and we will find that the element that draws the border does not have any random attributes, it is clean and original HTML content:

clean DOM structure

If you want to reset the style of this .ant-radio-inner element, writing it in the scoped scope has no effect.

 <style scoped> /* cannot reset */ .status-normal .ant-radio-inner {   --color: var(--blue6); } </style>

Because the framework will add an attribute selector to the class name .ant-radio-inner after compiling, which makes it unable to match the elements in the DOM.

Added attribute selectors without matching

In our daily development, we encounter similar problems with dynamically inserted HTML or 1v1 DOM operations that bypass the framework.

At present, the common practice is to write these CSS codes in the global CSS context.

For example, the style.css file common to the whole site, or still in this component file, but written in the <style> element without the scoped attribute, for example:

 <style> /* can be reset */ .status-normal .ant-radio-inner {   --color: var(--blue6); } </style>

But this approach is not perfect, because the CSS code blocks that should be together are forced to be separated into two places, which brings many changes to future maintenance.

Is there any way, that is, it is written in the scoped environment without adding attribute selectors, so that it can match the DOM structure of third-party components?

stand to make money

Have!

Try using the :is() or :where() pseudo-classes.

2. Quickly understand the :is and :where pseudo-classes

The :is() pseudo-class can be regarded as a kind of CSS writing syntactic sugar, which can simplify the writing of complex and repetitive selectors, for example:

 .active > .class-a, .active > .class-b, .active > .class-c {   display: block; }

Can be simplified to:

 active > :is(.class-a, .class-b, .class-c) {   display: block; }

The syntax and function of the :where() pseudo-class and the :is() pseudo-class are exactly the same, the difference lies in the priority of the selector.

The priority of the :where() pseudo-class is 0, no matter how high the priority of the selector in its parameter is, it is one of the few features in the entire CSS world that can reduce the priority of the selector (the other is the @layer rule, for details See ” Explaining the CSS @layer rule that will be used on a large scale in the future ” article).

The priority of the :is() pseudo-class is determined by the priority of the selector in the parentheses. From this point of view, the :where() pseudo-class may be more useful.

Pull away.

If we just look at the role of the :is() pseudo-class, it doesn’t seem to excite us. After all, the selector is simplified…well…it’s not a strong demand. Some people may like to write separately: Look, it’s splendid, the whole family Neat, not very good!

But what would you think if I told you that using the :is() pseudo-class in a framework like Vue, the selector would no longer add random property selectors?

Going back to the above example, also in the scoped style, now, we wrap the class name selector that needs to be reset with :is(), as shown below:

 <style scoped> /* can be reset */ .status-normal :is(.ant-radio-inner) {   --color: var(--blue6); } </style>

Something magical happened!

The style of the third-party component is successfully reset, and the compiled CSS selector looks like this:

Say goodbye to random pickers

You can reset the CSS of third-party components!

eyes shine

Our code no longer needs to be separated from flesh and blood, written in two places!

compatibility

The official support of the :is() pseudo-class started in Chrome 88, which is January 21, and it has been almost 2 years now. Those projects that do not require high compatibility can be used with confidence. If you have to be compatible with outdated browsers, You can use the :-webkit-any() pseudo-class for compatibility, except that the priority of the selector is different (the priority of the :any() pseudo-class is always the class selector priority, ignoring the parameters inside), other effects are the same, for example:

 <style scoped> /* can also be reset */ .status-normal :-webkit-any(.ant-radio-inner) {   --color: var(--blue6); } </style>

The screenshots are as follows:

-webkit-any role

//zxx: If you see this text, it means that you are visiting the original site. A better reading experience is here: https://ift.tt/tJDnhrO (by Zhang Xinxu)

The compatibility is as follows, as you can see :any() pseudo-class has been supported very early:

:any() compatibility

3. It is also a logical pseudo-class: what about not?

From a technical point of view, the :not() pseudo-class can also protect the base selector from adding dynamic attribute selectors, but the operation is not so simple, because the meaning of the :not() pseudo-class is negative, and the :is() Pseudo-classes that act purely syntactically are different.

Wouldn’t it be possible to use a double negation?

E.g:

 <style scoped> .status-normal :not(:not(.ant-radio-inner)) {   --color: var(--blue6); } </style>

Yes, functionally speaking, it can be matched!

However, the parameter support of the :not() pseudo-class is also supported by Chrome 88, just like the :is() pseudo-class, so there is absolutely no reason to use the is() pseudo-class.

Fourth, say something

I reckon that any CSS function that takes a selector as a parameter will do what this article needs.

Therefore, the :has() pseudo-class is certainly possible.

Now, the four major logic pseudo-classes of CSS are all here. It just so happened that last week, I recorded a 7-minute video introducing CSS logic pseudo-classes at station B. If you are interested, you can click to see it. I haven’t followed my account at station B yet. You can also pay attention to your friends, and will release front-end technical videos from time to time.

In addition, to say that sometimes, we may need the entire CSS selector without adding dynamic attribute selectors, so we can use wildcard processing, for example:

 <style scoped> * > :is(.status-normal) :is(.ant-radio-inner) {   --color: var(--blue6); } </style>

At this time, the random attribute value will be loaded on the wildcard, which naturally not only guarantees local privateness, but also does not worry that it cannot be reset.

Well, the above is the whole content of this article. In today’s popular framework development, the tips in this article must be very useful!

1f60f.svg

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.

Address of this article: https://www.zhangxinxu.com/wordpress/?p=10535

(End of this article)

This article is reprinted from: https://www.zhangxinxu.com/wordpress/2022/09/css-is-where-scoped-style/
This site is for inclusion only, and the copyright belongs to the original author.