大部分同學都用過 CSS 的螢屏寬度媒體查詢,像是這樣:
@media screen and (min-width: 900px) {
div {
padding: 1rem 3rem;
}
}
這里表示的是與螢屏寬度相關的樣式設定,上面的代碼表示當螢屏寬度大于 900px 時,內部的樣式代碼塊才能生效,
其實不僅僅是上面的螢屏寬度媒體查詢,在 CSS 中,存在大量的以 @ 符號開頭的規則,稱之為 @規則(at-rule),本文就將介紹一下除去媒體查詢之外,其他有意思的且在未來會越來越重要的 @規則 規則,
at-rule @規則
OK,什么是 @規則(at-rule )呢?
一個 at-rule 是一個 CSS 陳述句,以 at 符號開頭, '@' (U+0040 COMMERCIAL AT), 后跟一個識別符號,并包括直到下一個分號的所有內容, ';' (U+003B SEMICOLON), 或下一個 CSS 塊,以先到者為準,
除去我們最為熟悉的 @media 之外,CSS 還有哪些 @規則 呢?
下面是一些 @規則,由它們的標示符指定,每種規則都有不同的語法:
@charset, 定義樣式表使用的字符集,@import, 告訴 CSS 引擎引入一個外部樣式表,@namespace, 告訴 CSS 引擎必須考慮 XML 命名空間,
下面是一些嵌套 @ 規則,是嵌套陳述句的子集,不僅可以作為樣式表里的一個陳述句,也可以用在條件規則組里:
-
@media,如果滿足媒介查詢的條件則條件規則組里的規則生效, -
@page,描述列印檔案時布局的變化, -
@font-face,描述將下載的外部的字體, -
@keyframes,描述 CSS 影片的中間步驟, -
@supports, 如果滿足給定條件則條件規則組里的規則生效, -
@document,如果檔案樣式表滿足給定條件則條件規則組里的規則生效, (推延至 CSS Level 4 規范) -
@viewport(已廢棄),規則讓我們可以對檔案的大小進行設定,這個特性主要被用于移動設備,但是也可以用在支持類似“固定到邊緣”等特性的桌面瀏覽器,如微軟的 Edge, -
@counter-style— 一個@counter-style規則定義了如何把一個計數器的值轉化為字串表示, -
@font-feature-values(plus@swash,@ornaments,@annotation,@stylistic,@stylesetand@character-variant), 允許作者在font-variant-alternates 中使用通用名稱,用于在 OpenType 中以不同方式激活功能,它允許在使用幾種字體時簡化 CSS, -
@property(實驗性),是CSS Houdini API 的一部分,它允許開發者顯式地定義他們的css 自定義屬性, 允許進行屬性型別檢查、設定默認值以及定義該自定義屬性是否可以被繼承, -
@layer, 宣告了一個 級聯層,同一層內的規則將級聯在一起,這給予了開發者對層疊機制的更多控制,
除去我們非常熟悉的 @media、keyframes 以及 @font-face,像是 @supports、@counter-style、@property、@layer 等都已經或將在未來 Web 應用中扮演舉足輕重的作用,
下面,就跟隨本文,一起對它們一探究竟,你也可以跳過你已經掌握的,翻到對應你還不太了解的 @ 規則下,迅速了解它們,
@charset、@import、@namespace
這三個可以放在一起講解,他們的語法比較簡單,也相對好理解,其中:
@charset:指定樣式表中使用的字符編碼,它必須是樣式表中的第一個元素,而前面不得有任何字符,
像是這樣:
// style.css
@charset "UTF-8";
注意,如果有多個 @charset @規則被宣告,只有第一個會被使用,
很多人會有疑惑,這個宣告到底有什么用呢?
事實上,如果 CSS 檔案中有任何非 ASCII 文本,例如字體名稱,偽元素的 content 屬性值、選擇器等中的非 ASCII 字符,都需要確保 CSS 決議器知道如何轉換位元組正確轉換為字符,以便它理解 CSS 代碼,
所以如果當你發現你的偽元素 content 中插入了一些內容,但是經過打包編譯后它亂碼了,很有可能是因為你忘了宣告這個字符集,
@import:用于從其他樣式表匯入樣式規則,這些規則必須先于所有其他型別的規則,@charset規則除外
@import 有兩種語法:
- url() 內包含 style sheet 的 URI
- 直接寫 style sheet 的 URI 的字串
還可以直接在后面定義媒體查詢規則,像是這樣:
@import 'custom.css';
@import url('landscape.css');
@import url('landscape.css') screen and (orientation:landscape);
合理的使用 @import 其實也是有好處的:
- 可以合理的控制 CSS 檔案的大小
- 更好的分治與復用
很多人可能會經常看到,網路上會有各種抵制 @import的文章,不過既然設計了 @import,總有它的有用之處,不能過于絕對,使用 @import 影響頁面性能的地方主要體現在兩個方面:
- 影響瀏覽器的并行下載
- 優先級問題,樣式互相覆寫
- 導致頁面閃爍
這里可以簡單解釋一下,首先我們得知道,加載頁面時,link 標簽引入的 CSS 被同時加載,而 @import 引入的 CSS 將在頁面加載完畢后被加載,
CSS 決議引擎在對一個 CSS 檔案進行決議時,如在檔案頂部遇到 @import 規則,將被替換為該 @import 匯入的 CSS 檔案中的全部樣式,而 @import 內的規則其后被加載,卻會在加載完畢后置于樣式表頂部,最終渲染時,如果存在同名同優先級樣式,會被下面的同名樣式層疊,導致所謂的優先級沖突,
實際上,瀏覽器渲染的動作一般會執行多次的,最后一次渲染,一定是基于之前加載過的所有樣式整合后渲染樹進行繪制頁面的,
而由于 @import 內的規則的加載時機問題,會在頁面內容加載完后再加載,相當于把 CSS 放在了 body 底部,從而造成了頁面的閃爍,當網路較差時,閃爍體驗更為明顯,
@namespace:@namespace是用來定義使用在 CSS 樣式表中的 XML 命名空間的 @規則,定義的命名空間可以把通配、元素和屬性選擇器限制在指定命名空間里的元素,
并且,任何 @namespace 規則都必須在所有的 @charset 和 @import規則之后,并且在樣式表中,位于其他任何樣式宣告之前,
總的來說,@namespace 在現如今的 CSS 生態中,屬于非常冷門的一個規則,基本上我從業這么久,沒怎么見過這個屬性的具體使用,
如果你對它確實感興趣,可以看看這篇詳解 -- spacing-out-on-css-namespaces.
@media、@keyframes、@font-face
這三個 @ 規則,大家應該非常熟悉,
@media:如果滿足媒介查詢的條件則條件規則組里的規則生效@keyframes:定義 CSS 影片的中間步驟@font-face:描述將下載的外部的字體
@keyframes 和 @font-face 這兩個大家肯定非常熟悉,
但是 @media 其實內有乾坤!除了螢屏寬度媒體查詢外,其實還存在非常多不同功能的媒體查詢!
下面我會列出一些在未來,我認為會越來越被提及使用到的 @media 規則,
prefers-reduced-motion 減弱影片效果
prefers-reduced-motion 規則查詢用于減弱影片效果,除了默認規則,只有一種語法取值 prefers-reduced-motion: reduce,開啟了該規則后,相當于告訴用戶代理,希望他看到的頁面,可以洗掉或替換掉一些會讓部分視覺運動障礙者不適的影片型別,
規范原文:Indicates that user has notified the system that they prefer an interface that removes or replaces the types of motion-based animation that trigger discomfort for those with vestibular motion disorders.
vestibular motion disorders 是一種視覺運動障礙患者,中文我只能谷歌翻譯,翻譯出來是前庭運動障礙,我感覺不太對,谷歌了一下是一種會導致眩暈的一類病癥,譬如一個影片一秒閃爍多次,就會導致患者的不適,
使用方法,還是上面那段代碼:
.ele {
animation: aniName 5s infinite linear;
}
@media (prefers-reduced-motion: reduce) {
.ele {
animation: none;
}
}
如果我們有一些類似這樣的影片:
在用戶開啟了 prefers-reduced-motion: reduce 時,就應該把它去掉,那么該如何開啟這個選項呢?MDN -- prefers-reduced-motion 給出的是:
- 在 GTK/Gnome 中,可以通過 GNOME Tweaks (在“通用”或“外觀”選單中,取決于具體版本) 的配置,設定 gtk-enable-animations 的值為 false
- 可以在 GTK 3 的組態檔中的 [Settings] 模塊下設定 gtk-enable-animations = false
- 在 Windows 10 中:設定 > 輕松獲取 > 顯示 > 在 Windows 中顯示影片
- 在 Windows 7 中:控制面板 > 輕松獲取 > ?是計算機更易于查看 > 關閉不必要影片
- 在 MacOS 中:系統偏好 > 輔助使用 > 顯示 > 減少運動
- 在 iOS 上:設定 > 通用 > 輔助性 > 減少運動
- 在 Android 9+ 上:設定 > 輔助性 > 移除影片
prefers-color-scheme 適配明暗主題
prefers-color-scheme 還是非常好理解的,它用于匹配用戶通過作業系統設定的明亮或夜間(暗)模式,它有兩個不同的取值:
prefers-color-scheme: light: 明亮模式prefers-color-scheme: dark: 夜間(暗)模式
語法如下,如果我們默認的是明亮模式,只需要適配夜間模式即可:
body {
background: white;
color: black;
}
@media (prefers-color-scheme: dark) {
body {
background: black;
color: white;
}
}
當然,上述只是 CSS 代碼示意,要做到兩套主題的切換肯定不是這么簡單,方法也很多,本文不贅述,讀者可以自行了解各種實作主題切換,或者是明暗切換的方案,
prefers-contrast 調整內容色彩對比度
prefers-contrast 該 CSS 媒體功能是用來檢測用戶是否要求將網頁內容以更高或者更低的對比度進行呈現,其中:
prefers-contrast: no-preference:默認值,不作任何變化prefers-contrast: less:希望使用對比度更低的界面prefers-contrast: more:希望使用對比度更高的界面
以 prefers-contrast: less 為例子,語法如下:
body {
background: #fff; // 文字與背景對比度為 5.74
color: #666;
}
// 提升對比度
@media (prefers-contrast: more) {
body {
background: #fff; // 文字與背景對比度為 21
color: #000;
}
}
上面只是偽 CSS 代碼,具體可能需要對具體的一些元素進行處理,或者使用 filter: contrast() 全域統一處理,當開啟配置時,用于實作類似這樣的功能:
什么是色彩對比度
是否曾關心過頁面內容的展示,使用的顏色是否恰當?色弱、色盲用戶能否正常看清內容?良好的色彩使用,在任何時候都是有益的,而且不僅僅局限于對于色弱、色盲用戶,在戶外用手機、陽光很強看不清,符合無障礙標準的高清晰度、高對比度文字就更容易閱讀,
這里就有一個概念 -- 顏色對比度,簡單地說,描述就是兩種顏色在亮度(Brightness)上的差別,運用到我們的頁面上,大多數的情況就是背景色(background-color)與內容顏色(color)的對比差異,
最權威的互聯網無障礙規范 —— WCAG AA規范規定,所有重要內容的色彩對比度需要達到 4.5:1 或以上(字號大于18號時達到 3:1 或以上),才算擁有較好的可讀性,
prefers-reduced-transparency 減少透明元素
prefers-reduced-transparency 該 CSS 媒體功能是用來檢測用戶是否要求減少網頁中的透明元素:
prefers-contrast: no-preference:默認值,不作任何變化prefers-contrast: reduce:希望界面元素存在盡可能少的透明元素
以 prefers-contrast: reduce 為例子,語法如下:
.ele {
opacity: 0.5;
}
// 減少透明元素
@media (prefers-contrast: reduce) {
.ele {
opacity: 1;
}
}
我在上一次,介紹這個功能的時候,它還是一片紅色,但是短短半年,整個兼容性已經有了很大的提升!
prefers-reduced-data 減少資料傳輸
對于部分網速較差的地區,或者流量很貴的情況,用戶會希望減少頁面中的流量請求,基于此有了 prefers-reduced-data,
prefers-reduced-data 該 CSS 媒體查詢功能是用于告知用戶代理,希望減少頁面的流量請求,
prefers-reduced-data: no-preference:默認值,不作任何變化prefers-reduced-data: reduce:希望界面元素消耗更少的互聯網流量
以 prefers-reduced-data: reduce 為例子,語法如下:
.ele {
background-image: url(image-1800w.jpg);
}
// 降低圖片質量
@media (prefers-reduced-data: reduce) {
.ele {
background-image: url(image-600w.jpg);
}
}
當檢測到用戶開啟了 prefers-reduced-data: reduce,我們將提供壓縮度更高,尺寸更小,消耗流量更少的圖片,
當然,上述代碼只是個示意,我們可以做的其實有更多,
不過,這是仍處于實驗室的功能,暫時沒有任何瀏覽器支持該媒體查詢~ ??
當然,從 Chrome 85+ 開始,可以通過開啟 #enable-experimental-web-platform-features 實驗室選項開啟該功能!
@supports 特性檢測
好,介紹完一些后續會非常重要從 @media 規則后,我們來看看 @supports,
傳統的 CSS 特性檢測都是通過 javascript 實作的,但是如今,原生 CSS 即可實作特性檢測的功能,
CSS @supports 通過 CSS 語法來實作特性檢測,并在內部 CSS 區塊中寫入如果特性檢測通過希望實作的 CSS 陳述句,
語法:
@supports <supports_condition> {
/* specific rules */
}
舉個例子:
div {
position: fixed;
}
@supports (position:sticky) {
div {
position:sticky;
}
}
上面的例子中,position: sticky 是 position 的一個比較新的屬性,用于實作黏性布局,可以輕松實作一些以往需要 Javascript 才能實作的布局,但是不一定在一些低端機型上兼容,
上面的寫法,首先定義了 div 的 position: fixed ,緊接著下面一句 @supports (position:sticky) 則是特性檢測括號內的內容,如果當前瀏覽器支持 @supports 語法,并且支持 position:sticky 語法,那么 div 的 則會被設定為 position:sticky ,
我們可以看到,@supports 語法的核心就在于這一句:@supports (...) { } ,括號內是一個 CSS 運算式,如果瀏覽器判斷括號內的運算式合法,那么接下來就會去渲染括號內的 CSS 運算式,除了這種最常規的用法,還可以配合其他幾個關鍵字:
@supports not && @supports and && @supports or
@supports not -- 非
not 運算子可以放在任何運算式的前面來產生一個新的運算式,新的運算式為原運算式的值的否定,看個例子:
.container {
translate: 50% 10%;
rotate: 80deg;
scale: 1.5;
}
// 如果不支持上述的語法,則 supports 內的語法生效
@supports not (scale: 1) {
.container {
transform: translate(50%, 10%) rotate(80deg) scale(1.5);
}
}
因為添加了 not 關鍵字,所以與上面第一個例子相反,這里如果檢測到瀏覽器不支持 transform 這種分開單獨的寫法 -- scale: 1 ,則將 .container 的 transform 屬性合在一起寫,寫成 transform: translate(50%, 10%) rotate(80deg) scale(1.5),
關于 transform 的分開寫法,如果你還不太了解,可以戳:解放生產力!transform 支持單獨賦值改變
@supports and -- 與
這個也好理解,多重判斷,類似 javascript 的 && 運算子符,用 and 運算子連接兩個原始的運算式,只有兩個原始運算式的值都為真,生成的運算式才為真,反之為假,
當然,and 可以連接任意多個運算式看個例子:
p {
overflow: hidden;
text-overflow: ellipsis;
}
@supports (display:-webkit-box) and (-webkit-line-clamp:2) and (-webkit-box-orient:vertical) {
p {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
}
上面同時,檢測 @supports (display:-webkit-box) and (-webkit-line-clamp:2) and (-webkit-box-orient:vertical) 了三個語法,如果同時支持,則設定三個 CSS 規則,這三個語法必須同時得到瀏覽器的支持,如果運算式為真,則可以用于實作多行省略效果:
CodePen Demo - @supportAnd
@supports or -- 或
理解了 @supports and,就很好理解 @supports or 了,與 javascript 的 || 運算子類似,運算式中只要有一個為真,則生成運算式運算式為真,
看例子:
@supports (background:-webkit-linear-gradient(0deg, yellow, red)) or (background:linear-gradient(90deg, yellow, red)){
div {
background:-webkit-linear-gradient(0deg, yellow, red);
background:linear-gradient(90deg, yellow, red)
}
}
上面的例子中,只有檢測到瀏覽器支持 background:-webkit-linear-gradient(0deg, yellow, red) 或者(or) background:linear-gradient(90deg, yellow, red) 其中一個,則給 div 元素添加漸變,
CodePen Demo -- @supports or
當然,關鍵字 not 還可以和 and 或者 or 混合使用,感興趣的可以嘗試一下,
Can i use?
兼容性來看,先看看 Can i use(更新至 2022/10/13) 吧:
大部分瀏覽器都已經支持了,我們已經可以開始使用起來了,使用 @supports 實作漸進增強的效果,
@counter-style CSS 計數器
@counter-style:是一個 CSS at-rule,它讓開發者可以自定義 counter 的樣式,一個 @counter-style 規則定義了如何把一個計數器的值轉化為字串表示,
利用 @counter-style,我們可以構建自定義的計數器樣式,
當然,在 @counter-style 之前,CSS 還有一種實作簡單計數器的規范,它由如下幾個屬性共同構成:
counter-reset: 初始化計數器的值counter-increment:在初始化之后,計數器的值就可以使用 counter-increment 來指定其為遞增或遞減counter():計數器的值可以使用 counter() 或 counters() 函式以在 CSS 偽元素的 content 屬性中顯示
我們來看最簡單的一個例子,我們想實作一個 ul 布局,其中的 li 個數不定,但是均分每行的空間,并且能夠自動帶上序號,像是這樣:
使用 counter-reset、counter-increment、counter() 這一套,非常的簡單就能實作,像是這樣:
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul>
// ... <li> 個數不定
</ul>
<ul>
// ... <li> 個數不定
</ul>
給每個 li 元素標序號這個事情就可以交給 CSS 計數器:
ul {
display: flex;
justify-content: space-around;
counter-reset: stepCount;
}
li {
position: relative;
}
li::before {
position: absolute;
counter-increment: stepCount 1;
content: counter(stepCount);
}
簡單解釋一下:
- 在
ul的樣式中,每次都會初始化一個 CSS 計數器stepCount,默認值為 0 - 在
li::before中的counter-increment: stepCount 1表示每次呼叫到這里,stepCount 的值加 1 - 最后通過
counter(stepCount)將當前具體的計數值通過偽元素的 content 顯現出來
OK,那么為什么有了上述的 CSS 計數器規范后,又新增了 @counter-style CSS 計數器規范呢?
@counter-style 的意義
這是因為,上述的 counter-reset、counter-increment、counter() 這一套更多的生成的數字型別的計數器,
但是,數字型別的計數器無法滿足當前全球化的排版的訴求,基于此,@counter-style 規則用一種開放的方式彌補了這一缺點,在預定義的樣式不能滿足需求時,它可以使開發者自定義他們自己的計數器樣式,
舉個例子,我們使用 MDN 上的例子作為示例:
<ul>
<li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </li>
<li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </li>
<li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </li>
<li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </li>
</ul>
@counter-style circled-alpha {
system: fixed;
symbols: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?;
suffix: " ";
}
li {
list-style: circled-alpha;
}
這樣,我們就可以得到自定義的計數前綴:
有了這個,我們就可以將上述的 symbols 替換成其他我們喜歡我計數圖形,譬如 emoji 圖形:
@counter-style circled-alpha {
system: fixed;
symbols: ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??;
suffix: " ";
}
li {
list-style: circled-alpha;
}
看看效果:
CodePen Demo -- @counter-style
當然,實際使用程序中,@counter-style 的語法會有一點點復雜,可選的屬性也有很多,更為具體的可以仔細學習下檔案 -- MDN -- @counter-style
@property CSS 自定義屬性
@property CSS at-rule 是 CSS Houdini API 的一部分, 它允許開發者顯式地定義他們的 CSS 自定義屬性,允許進行屬性型別檢查、設定默認值以及定義該自定義屬性是否可以被繼承,
正常而言,我們定義和使用一個 CSS 自定義屬性的方法是這樣的:
:root {
--whiteColor: #fff;
}
p {
color: (--whiteColor);
}
而有了 @property 規則之后,我們還可以像下述代碼這樣去定義個 CSS 自定義屬性:
<style>
@property --property-name {
syntax: '<color>';
inherits: false;
initial-value: #fff;
}
p {
color: var(--property-name);
}
</style>
簡單解讀下:
@property --property-name中的--property-name就是自定義屬性的名稱,定義后可在 CSS 中通過var(--property-name)進行參考- syntax:該自定義屬性的語法規則,也可以理解為表示定義的自定義屬性的型別
- inherits:是否允許繼承
- initial-value:初始值
其中,@property 規則中的 syntax 和 inherits 描述符是必需的,
當然,在 JavaScript 內定義的寫法也很簡單,順便一提:
<script>
CSS.registerProperty({
name: "--property-name",
syntax: "<color>",
inherits: false,
initialValue: "#c0ffee"
});
</script>
CSS @property 的優勢
為什么要使用這么麻煩的語法定義 CSS 自定義屬性呢?CSS Houdini 定義的自定義變數的優勢在哪里?
我們來看這樣一個例子,我們有這樣一個漸變的圖案:
<div></div>
div {
background: linear-gradient(45deg, #fff, #000);
}
我們改造下上述代碼,改為使用 CSS 自定義屬性:
:root {
--colorA: #fff;
--colorB: #000;
}
div {
background: linear-gradient(45deg, var(--colorA), var(--colorB));
}
得到的還是同樣的一個漸變圖:
我們再加上一個過渡效果:
:root {
--colorA: #fff;
--colorB: #000;
}
div {
background: linear-gradient(45deg, var(--colorA), var(--colorB));
transition: 1s background;
&:hover {
--colorA: yellowgreen;
--colorB: deeppink;
}
}
看看滑鼠 Hover 的時候,會發生什么:
雖然我們設定了 1s 的過渡影片 transition: 1s background,但是很可惜,CSS 是不支持背景漸變色的直接過渡變化的,我們得到的只是兩幀之間的直接變化,
使用 CSS @property 進行改造
OK,接下來我們就使用本文的主角,使用 Houdini API 中的 CSS 自定義屬性替換原本的 CSS 自定義屬性,
簡單進行改造一下,使用 color syntax 語法型別:
@property --houdini-colorA {
syntax: '<color>';
inherits: false;
initial-value: #fff;
}
@property --houdini-colorB {
syntax: '<color>';
inherits: false;
initial-value: #000;
}
.property {
background: linear-gradient(45deg, var(--houdini-colorA), var(--houdini-colorB));
transition: 1s --houdini-colorA, 1s --houdini-colorB;
&:hover {
--houdini-colorA: yellowgreen;
--houdini-colorB: deeppink;
}
}
我們使用了 @property 語法,定義了兩個 CSS Houdini 自定義變數 --houdini-colorA 和 --houdini-colorB,在 hover 變化的時候,改變這兩個顏色,
需要關注的是,我們設定的過渡陳述句 transition: 1s --houdini-colorA, 1s --houdini-colorB,在這里,我們是針對 CSS Houdini 自定義變數設定過渡,而不是針對 background 設定過渡影片,再看看這次的效果:
Wow,成功了,漸變色的變化從兩幀的逐幀影片變成了補間影片,實作了從一個漸變色過渡到另外一個漸變色的效果!而這,都得益于 CSS Houdini 自定義變數的強大能力!
CodePen Demo -- CSS Houdini 自定義變數實作漸變色過渡影片
CSS @property 規則的強大之處在于,很多以往無法使用 CSS 進行影片的效果,如今,借助它都可以實作!
更多 CSS @property 的用法,你可以戳 CSS @property,讓不可能變可能
@layer
@layer 可謂是 CSS 圈 2022 年最受矚目的新特性,
它的出現,目的在于讓大型專案中的 CSS 檔案及內容,可以得到更好的控制和管理,
CSS @layer 從 CSS Cascading and Inheritance Level 5 被規范定義,
何為 CSS @layer?簡單而言,CSS @規則 中的@layer宣告了一個 級聯層, 同一層內的規則將級聯在一起, 這給予了開發者對層疊機制的更多控制,
語法也非常簡單,看這樣一個例子:
@layer utilities {
/* 創建一個名為 utilities 的級聯層 */
}
這樣,我們就創建一個名為 utilities 的 @layer 級聯層,
@layer 級聯層如何使用呢?
通過 @layer 級聯層管理樣式優先級
@layer 級聯層最大的功能,就是用于控制不同樣式之間的優先級,
看下面這樣一個例子,我們定義了兩個 @layer 級聯層 A 和 B:
<div></div>
div {
width: 200px;
height: 200px;
}
@layer A {
div {
background: blue;
}
}
@layer B {
div {
background: green;
}
}
由于 @layer B 的順序排在 @layer A 之后,所以 @layer B 內的所有樣式優先級都會比 @layer A 高,最終 div 的顏色為 green:
當然,如果頁面內的 @layer 太多,可能不太好記住所有 @layer 的順序,因此,還有這樣一種寫法,
我們可以同時命名多個 @layer 層,其后再補充其中的樣式規則,
<div></div>
@layer B, C, A;
div {
width: 200px;
height: 200px;
}
@layer A {
div {
background: blue;
}
}
@layer B {
div {
background: green;
}
}
@layer C {
div {
background: orange;
}
}
上述代碼,我們首先定義了 @layer B, C, A 三個 @layer 級聯層,而后再后面的 CSS 代碼中補充了每個級聯層的 CSS 代碼,但是樣式的優先級為:
A > C > B
因此,最終的 div 的顏色值為 @layer A 中定義的顏色,為 blue:
到這里,CSS @layer 的作用可以清晰的被窺見,
利用 CSS @layer,我們可以將 CSS 不同模塊劃入不同的 @layer 中,利用先后順序,非常好的去控制全域的樣式優先級,
CSS @layer 的誕生,讓我們有能力更好的劃分頁面的樣式層級,更好的處理內部樣式與外部參考樣式的優先級順序,屬于比較重大的一次革新,
這里只是非常簡單的介紹了 @layer 規則,更詳細的,你可以戳這里:2022 年最受矚目的新特性 CSS @layer 到底是個啥?
@container 容器查詢
@container:提供了一種,基于容器的可用寬度來改變布局的方式,
容器查詢也是一個非常新且重要的特性,彌補了過往媒體查詢的不足,
在之前,回應式有這么個掣肘,同一 DOM 的不同布局形態如果想要變化,需要依賴諸如媒體查詢來實作,
像是這樣:
通過瀏覽器視窗大小的變化,借助媒體查詢,實作不一樣的布局,
但是,在現如今,大部分 PC 端頁面使用的是基于 Flex/Grid 的彈性布局,
很多時候,當內容數不確定的時候,即便是相同的瀏覽器視窗寬度下,元素的布局及寬度可能也是不一致的,
考慮下面這種情況:
<!-- 情況一 -->
<ul >
<li></li>
<li></li>
<li></li>
</ul>
<!-- 情況二 -->
<ul >
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
.wrap {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
li {
width: 190px;
height: 100px;
flex-grow: 1;
flex-shrink: 0;
}
這種情況下,如果需要在不同寬度下對最后一個元素做一下處理,傳統方式還是比較麻煩的,
在這種情況下,容器查詢(CSS Container Queries)就應運而生了!
容器查詢的能力
容器查詢它給予了 CSS,在不改變瀏覽器視口寬度的前提下,只是根據容器的寬度變化,對布局做成調整的能力,
還是上面的例子,簡單的代碼示意:
<div >
<div >
<div >Title</div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus vel eligendi, esse illum similique sint!!</p>
</div>
</div>
.wrap {
width: 500px;
resize: horizontal;
overflow: auto;
}
.g-container {
display: flex;
flex-wrap: nowrap;
}
.wrap {
/* CSS CONTAINER */
container-name: wrap;
container-type: inline-size;
}
@container wrap (max-width: 400px) {
.g-container {
flex-wrap: wrap;
flex-direction: column;
}
}
像是這樣,我們通過 resize: horizontal 來模擬單個容器的寬度變化,在這種情況下,容器查詢能夠做到在不同寬度下,改變容器內部的布局,
這樣,就簡單實作了一個容器查詢功能:
注意,仔細和上面的例子作對比,這里,瀏覽器的視口寬度是沒有變化的,變化的只是容器的寬度!
媒體查詢與容器查詢的異同,通過一張簡單的圖看看,核心的點在于容器的寬度發生變化時,視口的寬度不一定會發生變化:
我們簡單拆解下上述的代碼,非常好理解,
- 在
.warp的樣式中,通過container-name: wrap注冊一個容器 - 注冊完容器之后,便可以通過
@container wrap ()容器查詢語法,在內部寫入不同情況下的另外一套樣式 - 這里
@container wrap (max-width: 400px) {}的意思便是,當.wrap容器的寬度小于 400 px 時,采用內部定義的樣式,否則,使用外部默認的樣式
關于容器查詢更為具體的語法,我建議還是上 MDN 或者規范詳細看看 -- MDN -- CSS Container Queries
@scroll-timeline
在之前,我介紹了 CSS 最新的特性 @scroll-timeline,譬如這兩篇文章:
- 革命性創新,影片殺手锏 @scroll-timeline
- 超酷炫的轉場影片?CSS 輕松拿下!
@scroll-timeline 能夠設定一個影片的開始和結束由滾動容器內的滾動進度決定,而不是由時間決定,
意思是,我們可以定義一個影片效果,該影片的開始和結束可以通過容器的滾動來進行控制,
利用它,我們可以使用純 CSS 實作頁面滾動與 CSS 影片的結合,像是這樣:
遺憾的是,這個如此好的特性,最近已經被規范廢棄,已經不再推薦使用了:
意思是,即便目前有一些瀏覽器已經支持了 @scroll-timeline,但是它很快又將要退出歷史舞臺,不再建議再使用這個 at-rule 規則,
這里,
@scroll-timeline雖然被廢棄了,但是 CSS 將會換一種實作方式卷土重來,
總結一下
到這里,其實還有幾個非常冷門且不太實用的 at-rule 規則,譬如:
@color-profile:允許定義并命名一個顏色組態檔@font-feature-values:主要是相對字體功能的拓展
能夠搜集到資料太少,檔案也相對簡陋,目前實用的場景太少,就不詳細展開,
綜上,可以看到,整個 at-rule 家族還是非常強大的,引入了非常多新的特性及功能,讓 CSS 生態愈發強大,讓 CSS 可以做到的事情越來越多,我們也有理由期待未來 CSS 會在 Web 領域扮演愈發重要的角色,
好了,本文到此結束,希望本文對你有所幫助 ??
如果還有什么疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/526899.html
標籤:Html/Css
上一篇:CGCS2000坐標系和WGS84坐標系的區別與聯系
下一篇:JS防抖與節流
