現代 CSS 指南 -- at-rule 規則掃盲

来源:https://www.cnblogs.com/coco1s/archive/2022/11/03/16853591.html
-Advertisement-
Play Games

大部分同學都用過 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, 聲明瞭一個 級聯層,同一層內的規則將級聯在一起,這給予了開發者對層疊機制的更多控制。

除去我們非常熟悉的 @mediakeyframes 以及 @font-face,像是 @supports@counter-style@property@layer 等都已經或將在未來 Web 應用中扮演舉足輕重的作用。

下麵,就跟隨本文,一起對它們一探究竟。你也可以跳過你已經掌握的,翻到對應你還不太瞭解的 @ 規則下,迅速瞭解它們。

@charset、@import、@namespace

這三個可以放在一起講解,他們的語法比較簡單,也相對好理解。其中:

  1. @charset:指定樣式表中使用的字元編碼。它必須是樣式表中的第一個元素,而前面不得有任何字元。

像是這樣:

// style.css
@charset "UTF-8";

註意,如果有多個 @charset @規則被聲明,只有第一個會被使用。

很多人會有疑惑,這個聲明到底有什麼用呢?

事實上,如果 CSS 文件中有任何非 ASCII 文本,例如字體名稱,偽元素的 content 屬性值、選擇器等中的非 ASCII 字元,都需要確保 CSS 解析器知道如何轉換位元組正確轉換為字元,以便它理解 CSS 代碼。

所以如果當你發現你的偽元素 content 中插入了一些內容,但是經過打包編譯後它亂碼了,很有可能是因為你忘了聲明這個字元集。

  1. @import:用於從其他樣式表導入樣式規則。這些規則必須先於所有其他類型的規則,@charset 規則除外

@import 有兩種語法:

  1. url() 內包含 style sheet 的 URI
  2. 直接寫 style sheet 的 URI 的字元串

還可以直接在後面定義媒體查詢規則,像是這樣:

@import 'custom.css';
@import url('landscape.css');
@import url('landscape.css') screen and (orientation:landscape);

合理的使用 @import 其實也是有好處的:

  1. 可以合理的控制 CSS 文件的大小
  2. 更好的分治與復用

很多人可能會經常看到,網路上會有各種抵制 @import的文章,不過既然設計了 @import,總有它的有用之處,不能過於絕對。使用 @import 影響頁面性能的地方主要體現在兩個方面:

  1. 影響瀏覽器的並行下載
  2. 優先順序問題,樣式互相覆蓋
  3. 導致頁面閃爍

這裡可以簡單解釋一下。首先我們得知道,載入頁面時,link 標簽引入的 CSS 被同時載入,而 @import 引入的 CSS 將在頁面載入完畢後被載入。

CSS 解析引擎在對一個 CSS 文件進行解析時,如在文件頂部遇到 @import 規則,將被替換為該 @import 導入的 CSS 文件中的全部樣式。而 @import 內的規則其後被載入,卻會在載入完畢後置於樣式表頂部,最終渲染時,如果存在同名同優先順序樣式,會被下麵的同名樣式層疊,導致所謂的優先順序衝突。

實際上,瀏覽器渲染的動作一般會執行多次的。最後一次渲染,一定是基於之前載入過的所有樣式整合後渲染樹進行繪製頁面的,
而由於 @import 內的規則的載入時機問題,會在頁面內容載入完後再載入。相當於把 CSS 放在了 body 底部,從而造成了頁面的閃爍。當網路較差時,閃爍體驗更為明顯。

  1. @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,我們將提供壓縮度更高,尺寸更小,消耗流量更少的圖片。

當然,上述代碼只是個示意,我們可以做的其實有更多。

不過,這是仍處於實驗室的功能,暫時沒有任何瀏覽器支持該媒體查詢~

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 操作mysql的命令 cmd命令行中查看mysql版本: mysql -V mysql --version 登陸mysql: mysql -uroot -pluis mysql -uroot -p 在mysql中查看資料庫版本: select version(); 查看所有資料庫: show dat ...
  • async與launch一樣都是開啟一個協程,但是async會返回一個Deferred對象,該Deferred也是一個job async函數類似於 launch函數.它啟動了一個單獨的協程,這是一個輕量級的線程並與其它所有的協程一起併發的工作.不同之處在於 launch 返回一個 Job 並且不附帶 ...
  • 隨著ACG文化(二次元文化)影響力的不斷提升,嗶哩嗶哩平臺上衍生品消費群體不斷擴大,手辦行業迅速崛起。2017年,B站推出ACG衍生品消費品牌bilibili會員購,涵蓋二次元手辦銷售等多項業務,拓展了IP內容的消費邊界,致力於滿足Z世代用戶的IP文化娛樂消費需求。 多年來,bilibili會員購高 ...
  • 在某些場景下(比如自動化打包等),我們需要從終端來讀取到iOS項目的數據,首先先上代碼 xcodebuild -showBuildSettings -target 項目target 但有時候我們需要將其轉為字元串的話,需要在兩邊加上這個符號` OUTPUT='xcodebuild -showBuil ...
  • 先說點廢話 最近在實際業務中,需要編寫一個方法根據數組中每一個對象的一個相同欄位,來將該欄位值相等的對象重新編入一個數組,返回一個嵌套的數組對象,特地來做個總結。 當然需要註意的是,在開發過程這種數組的處理函數,應當被編寫到項目的公共工具函數庫中全局調用 目標對象數組 let dataArr = [ ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一、概述 在我們開發中,經常要用到Vue.extend創建出Vue的子類來構造函數,通過new 得到子類的實例,然後通過$mount掛載到節點,如代碼: <div id="mount-point"></div> <!-- 創建構造器 -- ...
  • 1 yyg-cli 是什麼 yyg-cli 是優雅哥開發的快速創建 vue3 項目的腳手架。在 npm 上發佈了兩個月,11月1日進行了大升級,發佈 1.1.0 版本:支持創建 vue3 全家桶項目和 vue3 組件庫項目。具體如下: vue3 全家桶項目 使用 yyg-cli 創建的 vue3 全 ...
  • 邏輯導航 1.當在前端輸入用戶名和密碼之後,點擊登錄,後端校驗完畢返回前端 2.前端拿到需要首先做個判斷,判斷用戶是否輸入用戶名和密碼,未輸入則發出提示;輸入了則發送post請求給後端,校驗用戶名和密碼 3.校驗通過,前端拿到後端返回的token和用戶名等數據 4.登錄成功,則關閉登錄框,同時,在登 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...