自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Chrome 99新特性:@layers 規(guī)則淺析

開發(fā) 后端
背景中的兩個(gè)問題,都是因?yàn)檫x擇器權(quán)重導(dǎo)致的(比如問題 1,由定義順序?qū)е?問題 2,由隱式權(quán)重導(dǎo)致)。

背景CSS 寫多了,就會(huì)覺得它不太好用,經(jīng)常會(huì)遇到各種問題... 比如:

「引入順序?qū)е碌臉邮礁?jìng)爭(zhēng)問題」

用過 ant design 等組件庫(kù) + 發(fā)布在 npm 上的業(yè)務(wù)組件 的同學(xué),可能會(huì)經(jīng)常遇到自定義樣式不生效的問題,比如像這樣...

/* main.module.css */
.green {
color: green;
}
// main.tsx
import { Button } from antd ;
import antd/dist/antd.css ;

// @ts-ignore
import styles from ./main.module.css ;

import Nothing from packed-bad-component ;

export default function Component() {
const { green } = styles;
return (
<>
<Button className={green}>我是什么顏色?</Button>
<Nothing />
</>
);
}


// bad-component.tsx, published as packed-bad-component
import { Button } from antd ;
import antd/dist/antd.css?uncached ;

export default function Nothing() {
return null;
}

按鈕中的文字是什么顏色? 可以點(diǎn)擊這里試試:https://codesandbox.io/embed/bad-case-css-priority-xs3ds?fontsize=14&hidenavigation=1&theme=dark

這是因?yàn)?,如果發(fā)布的組件引入了 ant design 的樣式,就會(huì)被打包??,導(dǎo)致最終在我們的項(xiàng)目中,樣式被重復(fù)引入。而由組件引入的樣式優(yōu)先級(jí)有可能高于我們自定義的樣式,因此顯示為黑色。

導(dǎo)致問題變得更糟的是,如果此時(shí)觸發(fā)了 hot-reload,因?yàn)榇虬鼧邮綗o需重復(fù)插入,而我們的樣式有可能被更新,就會(huì)導(dǎo)致字變成綠色,進(jìn)而導(dǎo)致一些樣式問題在開發(fā)階段難以被發(fā)現(xiàn)。

「組件嵌套導(dǎo)致的樣式競(jìng)爭(zhēng)問題」

有時(shí)候,尤其是在組件中,我們可能不會(huì)隨機(jī)命名樣式,而是將一些類型的元素固定為同一個(gè)名稱,比如 .link,以方便用戶在使用我們的組件時(shí)覆蓋這些樣式。當(dāng)引入樣式較多時(shí),容易發(fā)生混亂。

┌──────────────┐
POST.post

a.link

┌─────┐
.card
a.link
└─────┘

└──────────────┘

倘若這兩個(gè)組件有以下樣式

.post a.link { /* b = 2, c = 1 */
color: red;
}

.card .link { /* b = 2, c = 0 */
color: green;
}

這樣就會(huì)出現(xiàn) .card 中的 link 樣式被 .post 中的 link 樣式覆蓋的問題,不符合預(yù)期

目前可能會(huì)比較常見使用 BEM(Block, Element, Modifier) 的方式通過避免名稱沖突,來解決這些問題,例如這樣...

有沒有什么更好的辦法來解決我們的問題呢?

前置

在繼續(xù)之前,我們先復(fù)習(xí)一下 CSS 的樣式優(yōu)先級(jí)。

Cascading SpecificityCSS 根據(jù)定義來源不同分為 3 種:

  • 用戶代理定義(user-agent declarations)
  • 網(wǎng)頁作者定義(author declarations)
  • 用戶定義(user declarations)

以及 2 種特殊的來源:

  • 過渡定義(transition declarations)
  • 動(dòng)畫定義(animation declarations)

并根據(jù)特定的順序進(jìn)行層疊,以計(jì)算出元素最終樣式。根據(jù)來源的優(yōu)先級(jí)如下(優(yōu)先級(jí)高優(yōu)先):

Selector Specificity

如果定義來源相同,則考慮選擇器權(quán)重:

特殊例子:

「:is(div, #root)」 的權(quán)重是 (a = 1, b = 0, c = 0),因?yàn)槠渲袡?quán)重最高的是 #root (1, 0, 0)

「.link:where(a, #root)」 的權(quán)重是 (a = 0, b = 1, c = 0),因?yàn)?where 中的權(quán)重是 0

「:nth-child(even of li, .item)」 的權(quán)重是 (a = 0, b = 2, c = 0),因?yàn)?:nth-child 其中權(quán)重最高的是 .item (0, 1, 0),:nth-child 本身是 (0, 1, 0),共 (0, 2, 0)

比較的時(shí)候,先是否為內(nèi)聯(lián)樣式,然后 A,然后 B,然后 C。權(quán)重還相同的樣式,則后定義的優(yōu)先級(jí)更高。

?? Web 標(biāo)準(zhǔn)似乎是不支持權(quán)重進(jìn)位的,因此,再具體的 class selector 都沒有 id selector 優(yōu)先,真實(shí)的瀏覽器實(shí)現(xiàn)是否如此呢?

@layer

背景中的兩個(gè)問題,都是因?yàn)檫x擇器權(quán)重導(dǎo)致的(比如問題 1,由定義順序?qū)е?問題 2,由隱式權(quán)重導(dǎo)致)。而層疊樣式中的用戶代理、用戶、網(wǎng)頁作者什么什么的,我好像都沒聽說過,它們沒有被充分利用起來。那么,是不是可以在計(jì)算選擇器權(quán)重前,增加點(diǎn)什么,讓它比選擇器權(quán)重更優(yōu)先計(jì)算,從而解決選擇器權(quán)重導(dǎo)致的問題呢?

即將推出的 CSS Cascading and Inheritance: Cascade Layers 致力于通過將 CSS 分層的方式避免預(yù)期外的樣式覆蓋,并提供更好的 CSS 組織結(jié)構(gòu)。通過分層,我們可以更顯式地聲明每一層的選擇器權(quán)重,確保不會(huì)出現(xiàn)默認(rèn)權(quán)重導(dǎo)致的跨層樣式覆蓋。

一句話概括 Layer 的特點(diǎn):「對(duì)于處在不同層中的樣式,無視樣式本身的權(quán)重,后聲明的層中的樣式優(yōu)先級(jí)更高,不在層中的樣式優(yōu)先級(jí)最高」。

不使用 layer 的樣式假如我們的樣式有 3 個(gè)來源,base,typography 和 utilities,它們分別設(shè)置了不同的樣式如圖。那么根據(jù)我們的選擇器權(quán)重理論:

  • 第一行,命中 2 個(gè),顏色沖突,特異性相同,后聲明樣式優(yōu)先,加粗綠色
  • 第二行,命中 3 個(gè),顏色沖突,.link 特異性高優(yōu)先,加粗藍(lán)色
  • 第二行,命中 4 個(gè),顏色沖突,.link, .pink 特異性高優(yōu)先,.pink 后聲明優(yōu)先,加粗粉色

添加 layer 后的樣式如果我們按照不同的來源將樣式分層,會(huì)發(fā)現(xiàn) .link 變?yōu)榱司G色...

  • 第一行,命中 2 個(gè),顏色屬性有沖突,后聲明的 Layer 「typography」 優(yōu)先,加粗綠色
  • 第二行,命中 3 個(gè),顏色屬性有沖突,后聲明的 Layer 「typography」 優(yōu)先,加粗綠色
  • 第二行,命中 4 個(gè),顏色屬性有沖突,后聲明的 Layer 「utilities」 優(yōu)先,加粗粉色

即,不管樣式選擇器的特異性(權(quán)重)如何,總是后聲明的 Layer 中的樣式更優(yōu)先一些

調(diào)整 layer 的順序假如我們對(duì)這些樣式的優(yōu)先級(jí)不滿意,想要稍做修改,只需要在前面加上聲明... 現(xiàn)在 base 的樣式優(yōu)先級(jí)更高,因此前兩行的顏色都發(fā)生了變化。

可以在這里實(shí)踐一下:https://codesandbox.io/s/chrome-99-css-cascade-layers-krgo6\ 注意瀏覽器是否支持這一特性,可以在下方 「可用性」 中對(duì)照。

其他用法

「擴(kuò)展已有的層」:

同名的 Layer 會(huì)自動(dòng)擴(kuò)展,類似 TypeScript 的 Interface,如

@layer base;
@layer base {}
@layer base {
a {
font-weight: 800;
color: red; /* ignored */
}
}
@layer base {
.link {
color: blue; /* ignored */
}
}

「組織通過 @import 導(dǎo)入的 CSS」:

我們可以將層的聲明寫在文件最上方,然后將不同功能的 css 引入并放入對(duì)應(yīng)層中,防止互相干擾。* @import 的性能遠(yuǎn)不如 ,但 link 導(dǎo)入的樣式表暫不支持 layer,web 正在尋求解決方案。

@layer base, theme, layouts, components, utilities;

/* Base */
@import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
@import '../styles/base/base.css' layer(base); /* body and base styles */
@import '../styles/base/theme.css' layer(theme); /* theme variables */
@import '../styles/base/typography.css' layer(theme); /* theme typography */
@import '../styles/base/utilities.css' layer(utilities); /* base utilities */

/* Layouts */
@import '../styles/components/post.css' layer(layouts); /* post layout */

/* Components */
@import '../styles/components/cards.css' layer(components); /* imports card */
@import '../styles/components/footer.css' layer(components); /* footer component */

「聲明嵌套或匿名的層」:

層也可以被嵌套,嵌套的層也可以通過 . 來擴(kuò)展。匿名層無法擴(kuò)展。

@layer framework {
@layer layout {

}
}
@layer framework.layout {
p {
margin-block: 1rem;
}
}

@layer {
p {
margin-block: 1rem;
}
}

優(yōu)先級(jí)

如果層中包含嵌套層,則對(duì)每一個(gè)嵌套層

注意, !important 是反著來的,和其他層疊權(quán)重一樣

解決問題

「問題 1:引入組件順序?qū)е碌膯栴}」

因?yàn)閷又械臉邮絻?yōu)先級(jí)總是更低,因此將 antd 的樣式放入 antd 層中即可,無論以何順序引入都不會(huì)覆蓋我們不在層中的樣式。

「問題 2,組件嵌套導(dǎo)致的問題」

給來自不同組件的樣式分配不同的層,通過組織層的順序,即可避免這一問題。

注意事項(xiàng)

不是創(chuàng)建作用域的手段它只是一個(gè)組織 CSS、避免選擇器權(quán)重導(dǎo)致問題的方式,不是創(chuàng)建 CSS 作用域的方式。如果需要限制 CSS 的作用域,還是得添加更具體的樣式,如 .card:

.card a {
/* ... */
}

層疊層中的 CSS 優(yōu)先級(jí)低于不在層中的 CSS

層疊層中的 CSS 優(yōu)先級(jí)更低,是考慮到這樣在已有的代碼中引入層疊層,會(huì)更容易一些,不太會(huì)帶來很大的問題。

!important 的層疊權(quán)重相反如果存在 !important,則

  • 先聲明的層中的樣式優(yōu)先級(jí)高
  • 層中的樣式優(yōu)先級(jí)高
  • 不在層中的樣式優(yōu)先級(jí)低

這樣和原有的層疊權(quán)重比較一致。

明確插入

點(diǎn)層疊層的層疊權(quán)重與對(duì)應(yīng)層疊層在代碼中第一次出現(xiàn)的順序有關(guān)系,因此,最好把可能用到的層放在最頂點(diǎn),可以很清晰地看到層疊層的順序。

注意權(quán)重

引入了層疊層之后,可能會(huì)出現(xiàn)選擇器權(quán)重更高,卻被權(quán)重更低的樣式覆蓋的情況,提高權(quán)重又不能解決這個(gè)問題。當(dāng)出現(xiàn)這種情況時(shí),就要考慮是不是因?yàn)閷盈B層導(dǎo)致的... 后聲明的層疊層,層疊權(quán)重更高,可以無視選擇器權(quán)重覆蓋其他樣式。

引入層后,權(quán)重發(fā)生了一些變化,但一定要注意,只有同一等級(jí)才能對(duì)比,因此不要搞錯(cuò)了比較順序...

參考

  • 「Chrome Blog」: https://developer.chrome.com/blog/cascade-layers/
  • 「@layer 作者的想法」: https://css.oddbird.net/layers/explainer/
  • 「MDN」: https://developer.mozilla.org/en-US/docs/Web/CSS/
  • 「@layerW3 中的文檔」: https://w3.org/TR/css-cascade-5/#layering
責(zé)任編輯:姜華 來源: Tecvan
相關(guān)推薦

2017-02-22 14:30:44

Chrome BetGoogle(Android

2017-09-16 15:55:54

ChromeJavaScriptAndroid

2009-05-26 09:28:22

C# 4.0dynamic動(dòng)態(tài)類型

2020-11-23 09:50:44

Chrome前端Web

2021-04-02 17:05:43

Chrome瀏覽器Incognito

2011-07-22 09:42:52

谷歌ChromeLion

2021-11-17 10:45:58

Chrome 95新特性前端

2018-02-27 08:29:57

Opera Chrome Windows

2009-07-15 11:02:32

Swing組件

2009-03-23 10:53:00

PHP5.3新特性PHP5.3PHP5

2024-07-19 08:13:00

2009-07-24 17:30:37

Javascript閉

2018-08-28 10:32:23

Chrome瀏覽器語言

2009-06-03 16:10:34

OpenSolaris

2014-07-15 14:48:26

Java8

2024-09-11 09:30:58

IDEA工具編程

2021-02-22 11:51:15

Java開發(fā)代碼

2009-09-18 09:59:39

C# CLR

2009-07-09 18:36:50

MyEclipse 6

2009-09-18 15:53:37

C# 3.0新語言特性
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)