從:is()説起,開啟CSS偽類第二集

語言: CN / TW / HK

theme: condensed-night-purple highlight: atelier-dune-light


持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第10天,點擊查看活動詳情

前情提要

為了豐富自己是知識體系(為了日更薅羊毛),我最近頻繁翻閲MDN的文檔,果然MDN文檔常看常新。

最近翻到CSS部分,然後打開了偽類這一欄,好傢伙,快60個了(包括實驗中的)。

跳過常用的,還是很多。分批分期研究的話,我想三期應該是能夠收官。

今天開啟第二篇:《看着簡單卻有大用處的CSS偽類》。

偽類們

:is()

:is() 偽類可以匹配入參的選擇器列表中,任意一個選擇器可以選擇的元素

:is() 偽類大有用途,我對它的評價是「短小精悍」。

實例:簡化選擇器

我要設置不同元素下的a元素和span元素樣式,使用:is() 偽類之前的樣式代碼:

ol li, ul li, li a { color: red; } p a, p span { color: blue; }

使用:is() 偽類之後的樣式代碼:

:is(ol, ul) :is(li, a, span) { color: red; } :is(p) :is(a, span) { color: blue; }

展示效果

| | | ------------------------------------------------------------------------------------------------------------- |

實例:框架中全局匹配

這個很實用,日常開發中會使用第三方UI組件,這個時候需要重置樣式一般採用下面的方案:

Vue框架中使用 :deep() 偽類函數,React使用 :global()

其實:is()也可以實現。

當然這個應用場景不是我總結,是我看張鑫旭大佬的文章《巧用:is()或:where()偽類讓scoped的style依然全局匹配》學到的。詳細的方案和總結,可以看這篇文章。

:where()

:where()偽類接受選擇器列表作為它的參數,將會選擇所有能被該選擇器列表中任何一條規則選中的元素。

看這個介紹是不是跟:is() 偽類很像。沒錯,兩個偽類的語法和作用十分相似,區別就在於選擇器的優先級。

:where() 的優先級總是為 0,但是 :is() 的優先級是由它的選擇器列表中優先級最高的選擇器決定的。

實例::where() 和 :is()對比

  • 兩組div和p元素,內層都是span元素,根據class名進行區分,分別設置了:where() 和 :is()偽類。
  • 另外單獨設置了p元素下span元素的顏色值與前面的偽類不同。

``` :is(div.is-div, p.is-p) span { color: red; } :where(div.where-div, p.where-p) span { color: blue; } p span { color: gray; } ......

:is()偽類值div元素下的span元素

:is()偽類值p元素下的span元素

:where()偽類值div元素下的span元素

:where()偽類值p元素下的span元素

```

展示效果

通過展示效果可以發現,單獨設置的樣式覆蓋了:where()偽類的樣式,沒有覆蓋:is()偽類的樣式。原因就是前面提到的:where() 的優先級總是為 0,所以樣式可以被覆蓋。

| | | ------------------------------------------------------------------------------------------------------------- |

:not()

如果想對某個結構元素設置樣式,但是想排除這個結構元素下面的子元素應用該樣式,可以使用:not() 偽類。

:not() 偽類的參數可以是一個或多個選擇器。多個選擇器以逗號分隔。同時選擇器中不得包含另一個否定選擇器或偽元素。

MDN中有一行提示引起我的注意:

:not() 偽類有許多怪異、技巧和意料之外的結果,你在使用它之前應該意識到這些。

都有哪些需要特別注意📢,且看我下面的實例。

實例:提高規則的優先級

.foo:not(.bar) 和 .foo會匹配相同的元素,但是具有兩個class的選擇器具有更高的優先級。

所以第一行的文字顏色是紅色而不是藍色。第二行文字是藍色

``` .foo:not(.bar) { color: red; } .foo { color: blue; } ......

foo
foo和bar

```

展示效果

| | | ------------------------------------------------------------------------------------------------------------- |

實例:同時否定多個選擇器

:not(.foo, .bar)會否定樣式為.foo或.bar的元素。

  • 將樣式為.foo或.bar的元素設置文字顏色是藍色;
  • :not(.foo, .bar)設置的文字顏色是紅色。

``` .foo, .bar { color: blue; } :not(.foo, .bar) { color: red; } ......

無樣式設置
foo樣式
bar樣式
foo和bar樣式

```

展示效果

| | | ------------------------------------------------------------------------------------------------------------- |

實例:可以匹配html和body元素

  • body元素上設置文字顏色是藍色;
  • :not(.foo, .bar)設置的文字顏色是紅色。

但是看展示效果,文字顏色都是紅色,因為:not(.foo) 將匹配任何非 .foo 的元素,包括 html元素 和 body元素。且前面提到,:not偽類會提升優先級,所以最終頁面的文字顏色均為紅色。

``` body { padding: 0; margin: 0; background: #fff; color: blue; } :not(.foo) { color: red; } ......

無樣式設置
foo樣式
bar樣式

```

展示效果

未完待續

第二集的偽類分享就到這裏了,這期主要介紹了:is()、:where()、:not(),每個偽類的使用實例也都嘗試了一遍。雖然數量少,但是每個下面的內容不少,且都有大用處。

最大的收穫就是,CSS能玩出花的技能又增加了。

我喜歡創作,每一幅作品都是我將想象用一隻叫做“代碼”的畫筆,繪製而成。

當我尋找新的技術的時候,不是創意枯竭,而是我需要新的色彩。

而這個循序漸進的學習過程,雖然緩慢,但是積少成多、聚沙成塔。