2022年CSS都有哪些更新?
大家好,我是 CUGGZ。
2022 年 CSS 新增了很多特性,例如容器查詢、父選擇器、子網(wǎng)格、級聯(lián)層、新視口單位等,多項期待已久的功能已集成到常青瀏覽器(自動升級到最新版本的瀏覽器,包括 Chrome、Edge、Firefox 和 Safari)中。下面就來看看 2022 年 CSS 新增的 10 個實用功能吧!
1、顏色相關(guān)
下面來看看和 CSS 顏色相關(guān)的一些更新。CSS 工作組有兩個新規(guī)范將改變我們在 Web 上使用顏色的方式:CSS Color Module Level 4(候選推薦)和 CSS Color Module Level 5(工作草案)。兩者仍處于實驗階段,截至 2022 年 12 月,只有 Safari 已實現(xiàn)。
(1)新顏色函數(shù)語法
CSS Color Module Level 4 引入了顏色函數(shù)的新語法,例如rgb()和hsl()。新語法省略了逗號,依靠空格來分隔顏色空間的每個通道。它還支持可選的 alpha 參數(shù),從而不再需要額外的顏色函數(shù),例如rgba()和hsla()。逗號分隔的形式現(xiàn)在被規(guī)范稱為“遺留語法”。
(2)新色彩空間
新的顏色規(guī)范為網(wǎng)絡(luò)添加了大量新的顏色空間:
- HWB:色調(diào)、白度、黑度
- LCH:亮度、色度、色調(diào)
- CIE L * a * b*
- Oklab
- Oklch
- Display P3
這只是新增的顏色空間的一部分,其中一些色彩空間,比如 Display P3,提供了比 sRGB 空間更寬的色域,這意味著我們將可以使用更多顏色,并且這些顏色將比一直使用的顏色更鮮艷。
(3)相對顏色語法
CSS Color Module Level 5 通過引入相對顏色語法進(jìn)一步增強(qiáng)了顏色函數(shù)。。此語法可以基于另一種顏色定義新顏色??梢酝ㄟ^首先使用 from 關(guān)鍵字定義原色,然后像往常一樣在顏色函數(shù)中指定新顏色的通道來使用它。
當(dāng)提供原始顏色時,可以訪問“通道關(guān)鍵字”,允許引用顏色空間中的每個通道。關(guān)鍵字根據(jù)使用的顏色函數(shù)而變化。對于 rgb(),有 r、g 和 b 通道關(guān)鍵字;對于 oklch(),將擁有 l、c 和 h 關(guān)鍵字。對于每個顏色函數(shù),還有一個 alpha 通道關(guān)鍵字,它是原始顏色的 alpha 通道。
可以在 calc() 表達(dá)式中使用這些通道關(guān)鍵字來修改原始顏色:
除此之外,還可以跨顏色空間定義相對顏色。當(dāng)使用一個空間中最初定義的顏色并使用不同的顏色空間定義新顏色時,瀏覽器將首先將原始顏色轉(zhuǎn)換為新的顏色空間。
下面使用 Oklch 通過將色調(diào)旋轉(zhuǎn) 120°(? 圈)來定義基于 sRGB 中定義的原色的二次色:
(4)color-mix()
CSS Color Module Level 5 規(guī)范還引入了一個 color-mix() 函數(shù),允許在不同的顏色空間中混合顏色。
上面代碼中,會產(chǎn)生 50-50 的紫色和紫紅色混合。
2、全新動態(tài)視口單位
新增的 CSS 視口單元用于處理帶有動態(tài)工具欄的移動視口。
要想調(diào)整與視口一樣大的尺寸,可以使用現(xiàn)有的視口單位 vw 和 vh:
- vw:視口大小寬度的 1%。
- vh:視口大小高度的 1%。
下面元素的寬度為 100vw,高度為 100vh,它將完全覆蓋整個視口:
除了 vh 和 vw,還有:
- vmin:vw或vh中的較小者。
- vmax:vw或vh中的較大者。
這些單位在瀏覽器中都得到了很好的支持。雖然這些單位在桌面瀏覽器上運行良好,但在移動瀏覽器上就會存在一些問題,視口大小受動態(tài)工具欄存在與否的影響。這些是用戶界面,例如地址欄和標(biāo)簽欄等。盡管視口大小可以更改,但 vw 和 vh 大小不會。因此,尺寸為 100vh 高的元素會從視口中溢出。
當(dāng)向下滾動時,這些動態(tài)工具欄將縮回。在這種狀態(tài)下,尺寸為 100vh 高的元素將覆蓋整個視口。
為了解決這個問題,CSS 工作組規(guī)定了視口的各種狀態(tài):
- 大視口:視口大小假設(shè)任何動態(tài)擴(kuò)展和縮回的 UA 接口被縮回。
- 小視口:視口大小假設(shè)任何動態(tài)擴(kuò)展和縮回的 UA 接口都可以擴(kuò)展。
新視口也有指定的單位:
- 大視口的單位帶有 lv 前綴,單位為 lvw、lvh、lvi、lvb、lvmin 和 lvmax。
- 小視口的單位帶有 sv 前綴,單位是 svw、svh、svi、svb、svmin 和 svmax。
除非調(diào)整視口本身的大小,否則這些視口百分比單位的大小是固定的。
除了大視口和小視口之外,還有一個動態(tài)視口,動態(tài)考慮了瀏覽器 UI:
- 當(dāng)動態(tài)工具欄展開時,動態(tài)視口等于小視口的大小。
- 當(dāng)動態(tài)工具欄縮回時,動態(tài)視口等于大視口的大小。
它的單位帶有 dv 前綴:dvw、dvh、dvi、dvb、dvmin 和 dvmax。它們的尺寸在對應(yīng)的 lv* 和 sv* 之間。
瀏覽器對這些單位的支持情況如下:
參考:https://web.dev/viewport-units/
3、@container:容器查詢
CSS 容器查詢是一種超越與視口相關(guān)的媒體查詢的方法,而可以根據(jù)元素所在的容器修改元素的行為,不僅是依賴視口大小來更改元素的樣式。
想要使用容器查詢,首先需要在容器上定義 container-type。
還可以使用 container-name 來命名容器,如果有多層容器,這將很有用,這樣就可以更明確地了解哪些查詢會影響元素。type 和 name 都可以使用簡寫的 container 屬性來定義,其中 name 在前,并通過正斜杠與 type 分隔。
然后就可以使用@container開始查詢了。一旦滿足該條件,CSS 將應(yīng)用于該容器內(nèi)的元素。
最后來看一個實際的應(yīng)用:
現(xiàn)在就可以設(shè)置一個容器查詢來更改文章樣式及其任何后代的樣式,這將基于 main 的寬度,因為它是容器元素。
這樣,當(dāng)文章的寬度小于 60ch 時,就會采用更小的 padding 和 font-size 值。
瀏覽器對容器查詢的支持情況如下:
4、@layer:級聯(lián)層
在 2022 年 2 月/3 月,所有現(xiàn)代瀏覽器都發(fā)布了 Cascade Layers(級聯(lián)層),可以用來控制選擇器如何交互,而不管它們的特殊性或代碼順序。下面來看一個例子:
@layer 聲明了一個_級聯(lián)層_,同一層內(nèi)的規(guī)則將級聯(lián)在一起,這給予了開發(fā)者對層疊機(jī)制的更多控制。
上面例子中定義了多個級聯(lián)層,當(dāng)一個聲明中具有多個級聯(lián)層時,后定義的級聯(lián)層具有更高的優(yōu)先級。因此上面例子中,state 層具有更高的優(yōu)先級,即使 theme 樣式中具有更高的特定性(權(quán)重)并且在代碼中出現(xiàn)得更晚。
我們還可以嵌套圖層:
層按照每個層名稱首次出現(xiàn)在代碼庫中的順序堆疊,后面的層名稱優(yōu)先于前面的層。這意味著可以允許它們隱式堆疊:
或者可以像上面例子一樣,按順序引入層名稱來明確定義層順序:
瀏覽器對級聯(lián)層的支持情況如下:
可以看到,目前主流瀏覽器都支持 CSS 級聯(lián)層功能。
5、:has:父選擇器
:has()選擇器可以檢查父元素中是否存在特定的元素。例如,如果一個卡片組件中有圖片,就給它添加一個display:flex。這以前在 CSS 中是無法實現(xiàn)的,但是新的 :has() 選擇器就可以幫助我們選擇包含特定元素的父元素。
在CSS中,我們無法根據(jù)元素中是否存在特定的元素來設(shè)置父元素的樣式,要想實現(xiàn)這一點,就必須創(chuàng)建CSS類,并根據(jù)需要進(jìn)行類的切換。來看下面的例子:
這里我們有兩種卡片:包含圖片和不包含圖片。在CSS中需要這樣做:
這里創(chuàng)建了一個類card-plain,專門用于沒有圖片的卡片,在沒有圖片時就不需要flex布局。如果使用 CSS 中的父選擇器 :has 就不需要再寫這個類,只需要使用它來檢查卡片中是否包含.card-image即可:
根據(jù) CSS 規(guī)范,:has() 選擇器可以檢查父元素是否包含至少一個元素,或者一個條件,例如輸入是否獲取到焦點。
:has() 選擇器不僅可以檢查父元素是否包含特定的子元素,還可以檢查一個元素后面是否跟有另一個元素:
這將檢查 <h2> 元素是否直接跟在 <p> 元素之后。
我們也可以將它與表單元素一起使用來檢查輸入是否獲取到了焦點:
瀏覽器對 :has() 的支持情況如下:
可以看到,最新版的 Chrome、Edge、Safari 都已經(jīng)支持了 :has() 選擇器,而 Firfox 目前還不支持
6、:focus-visible
:focus-visible 是一個現(xiàn)代CSS 焦點選擇器。今年 3 月,Safari 15.4 發(fā)布了 :focus-visible 偽類,不久之后,它成為常青瀏覽器中使用的默認(rèn)元素焦點行為。
當(dāng)元素匹配:focus偽類并且客戶端的啟發(fā)式引擎決定焦點應(yīng)當(dāng)可見 (在這種情況下很多瀏覽器默認(rèn)顯示“焦點框”。) 時,:focus-visible 偽類將生效。
注意:Firefox 需要通過較舊的前綴偽類 :-moz-focusring 來支持類似的功能。
下面來看一個例子,:focus-visible 選擇器利用客戶端的行為決定是否匹配。當(dāng)使用鼠標(biāo)點擊控件和用鍵盤 tab 切換控件時會有所不同。
效果如下:
這段代碼的表現(xiàn)如下:
- 默認(rèn)樣式:使用鍵盤控制時,input和button的邊框都是細(xì)藍(lán)色的;使用鼠標(biāo)控制時,input的邊框是細(xì)藍(lán)色的,button的邊框是細(xì)黑色的。
- :focus:無論使用鼠標(biāo)控制還是鍵盤控制,input和button的邊框都是粗黑色的。
- :focus-visible:使用鍵盤控制時,input和button的邊框都是粗橙色的;使用鼠標(biāo)控制時,input的邊框是粗橙色的,button的邊框是細(xì)黑色的。
使用這個偽類,就可以有效地根據(jù)用戶的輸入方式 (鼠標(biāo) or 鍵盤) 來展示不同形式的焦點。
瀏覽器對 :focus-visible 的支持情況如下:
可以看到,目前主流瀏覽器都已經(jīng)支持 :focus-visible。
7、color-scheme
color-scheme 是一個 CSS 屬性,當(dāng)用戶選擇系統(tǒng)配色方案時(系統(tǒng)配色方案的常見選擇是“深色模式”和“淺色模式”),操作系統(tǒng)會對用戶界面進(jìn)行調(diào)整。這包括表單控件、滾動條和 CSS 系統(tǒng)顏色的使用值。
當(dāng)把上面的代碼復(fù)制到樣式表中,頁面就會根據(jù)操作系統(tǒng)的設(shè)置的暗/亮模式來顯示不同的樣式:
可以看到,當(dāng)切換系統(tǒng)配色模式時,文字顏色,背景顏色,以及表單(滾動條、選擇下拉框、單選框、復(fù)選框、輸入框等)樣式都發(fā)生了變化,這樣就省去了我們很多兩種模式下的樣式定義工作。
通常,屬性的值是以下幾種:
其中:
- normal:表示元素未指定任何配色方案,因此應(yīng)使用瀏覽器的默認(rèn)配色方案呈現(xiàn)。
- light:表示可以使用操作系統(tǒng)亮色配色方案渲染元素。
- dark:表示可以使用操作系統(tǒng)深色配色方案渲染元素。
需要注意,當(dāng)light和right都有時,需要light在前,right在后。要想將整個頁面配置為用戶的配色方案首選項,就可以像上面一樣,在 :root 元素上指定 color-scheme。
我們甚至可以僅在 HTML 中就可以獲得深色模式:
瀏覽器對 color-scheme 的支持情況如下:
8.accent-color
accent-color 屬性可以在不改變?yōu)g覽器默認(rèn)表單組件基本樣式的前提下重置組件的顏色。該屬性目前支持以下 HTML 控件元素:
- 復(fù)選框:<input type=”checkbox”>
- 單選框:<input type=”radio”>
- 范圍選擇框:<input type=”range”>
- 進(jìn)度條:<progress>
下面來看一個例子:
效果如下:可以看到,這些表單元素都變成我們定義的顏色。
需要注意,如果給表單元素設(shè)置了自定義樣式,那 accent-color 就可能會失效。例如,將進(jìn)度條的 border 設(shè)置為藍(lán)色:
樣式會是下面這樣,其并不符合預(yù)期(進(jìn)度條邊框為藍(lán)色),出現(xiàn)了意料之外的效果。所以,如果使用了 accent-color 定義表單樣式,就要盡量避免再給表單元素自定義其他樣式:
瀏覽器對 accent-color 的支持情況如下:
9、scale、rotate、translate
2022 年 8 月,Chromium 完成了使用單個 rotate, scale, translate 屬性來對 CSS 變換進(jìn)行更細(xì)粒度的控制。
要想在 CSS 中使用變換,需要使用 transform 屬性,該屬性接受一個或多個 <transform-function>:
在上面的代碼中,目標(biāo)元素會在 X 軸上平移 50%,旋轉(zhuǎn) 30 度,最后放大到 120%。雖然這樣 transform 屬性可以正常工作,但當(dāng)想要單獨更改這些值中的任何一個時,就會比較麻煩。
比如,想要在鼠標(biāo)懸浮時更改 scale 的大小,就需要將 transform 屬性中的所有函數(shù)都復(fù)制一遍,即使它們的值保持不變。
而在 Chrome 104 中,就可以使用rotate, scale, translate 屬性來單獨定義變換的這些部分。使用這些屬性來重寫前面的變換示例:
這樣,如果想在某些情況下單獨修改每個屬性時,就不需要再復(fù)制其他沒有變化的屬性。
原始的 CSS 變換屬性和新屬性之間的一個主要區(qū)別是應(yīng)用聲明的變換順序:
- 使用transform 時,變換函數(shù)會按照它們編寫的順序,從左到右。
- 使用單獨的變換屬性時,順序不是聲明的順序。而始終是:首先平移,然后旋轉(zhuǎn),最后縮放。
這意味著以下兩端代碼的執(zhí)行結(jié)果是一樣的:
在這兩種情況下,目標(biāo)元素都會首先在 X 軸上平移 50%,然后旋轉(zhuǎn) 30 度,最后縮放 1.2。
如果其中一個單獨的變換屬性與 transform 屬性一起聲明,則首先應(yīng)用單獨的變換(rotate, scale, translate),最后應(yīng)用 transform。
瀏覽器對 rotate, scale, translate 的支持情況如下:
10、subgrid:子網(wǎng)格
subgrid 允許元素在行軸或列軸上繼承其父元素的網(wǎng)格,主要解決當(dāng)網(wǎng)格嵌套網(wǎng)格時,子網(wǎng)格的位置和軌道不能和父網(wǎng)格對齊的問題。使用子網(wǎng)格時,需要讓 grid-template-columns 和 grid-template-rows 屬性的值使用 subgrid 關(guān)鍵字。
- grid-template-rows:基于網(wǎng)格行維度,定義網(wǎng)格線的名稱和網(wǎng)格軌道的尺寸大小。
- grid-template-columns:基于網(wǎng)格列維度,定義網(wǎng)格線的名稱和網(wǎng)格軌道的尺寸大小。
下面來看一個例子,有一個嵌套網(wǎng)格,它正在為行和列創(chuàng)建自己的軌道。這些軌道是獨立的,因此不會與父網(wǎng)格上的軌道對齊。
上面代碼的效果如下:
下面將 grid-template-columns 的軌道列表替換為 subgrid 關(guān)鍵字。嵌套網(wǎng)格的列軌道現(xiàn)在與父級上的列軌道對齊。
更改完之后的效果如下:
只要父級本身就是一個網(wǎng)格,就可以繼續(xù)將子網(wǎng)格繼承到子級中。以下示例顯示了三個網(wǎng)格,每個網(wǎng)格都嵌套在另一個網(wǎng)格中,并繼承了其父級的軌道。子項指示哪個網(wǎng)格是它們的父項。
使用 Firefox DevTools 突出顯示每個網(wǎng)格,突出顯示外部網(wǎng)格顯示子網(wǎng)格和網(wǎng)格項如何與該網(wǎng)格對齊:
瀏覽器對子網(wǎng)格的支持情況如下: