大部分同學都用過 CSS 的屏幕寬度媒體查詢,像是這樣: @media screen and (min-width: 900px) { div { padding: 1rem 3rem; } } 這裡表示的是與屏幕寬度相關的樣式設置,上面的代碼表示當屏幕寬度大於 900px 時,內部的樣式代碼塊才能 ...
大部分同學都用過 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
,@styleset
and@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
,我們將提供壓縮度更高,尺寸更小,消耗流量更少的圖片。
當然,上述代碼只是個示意,我們可以做的其實有更多。
不過,這是仍處於實驗室的功能,暫時沒有任何瀏覽器支持該媒體查詢~