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