現代 CSS 解決方案:Modern CSS Reset

語言: CN / TW / HK

在早年間(其實也不是很早),寫過幾篇關於 CSS Reset 的文章 - reset.css 知多少 [1]

詳細描述了當時業界比較常用的,兩個 CSS reset 方案:reset.css 與 Normalize.css。

以更為推薦的 Normalize.css 為例,它的核心思想是:

  1. 統一了一些元素在所有瀏覽器下的表現,保護有用的瀏覽器預設樣式而不是完全清零它們,讓它們在各個瀏覽器下表現一致;

  2. 為大部分元素提供一般化的表現;

  3. 修復了一些瀏覽器的 Bug ,並且讓它們在所有瀏覽器下保持一致性;

  4. 通過一些巧妙的細節提升了 CSS 的可用性;

  5. 提供了詳盡的文件讓開發者知道,不同元素在不同瀏覽器下的渲染規則;

如今,Normalize 已經出到了第八版 -- normalize.css V8.0.1 [2] ,而隨之而變的是瀏覽器市場環境的巨大變化。

IE 已經逐漸退出歷史舞臺,處理各個瀏覽器之間巨大差異、不同相容性問題的日子像是一去不復返了。雖然今天不同廠商在對待標準仍然存在差異,一些細節上仍舊有出入,但是我們已經不需要再像過去般大肆地對瀏覽器預設樣式進行重置。

到今天,我們更多聽到 現代 CSS 解決方案 一詞。它除去頁面樣式最基本的呈現外,同時也關注 使用者體驗可訪問性 。這也可能是過去,我們在寫 CSS 的時候比較容易忽略的環節。

Modern CSS Reset

我最近比較喜歡的一個 CSS Reset 方案,源自於 -- Modern-CSS-Reset [3]

它的核心觀點是:

  1. 重置合理的預設值

  2. 關注使用者體驗

  3. 關注可訪問性

整個 Reset 的原始碼比較簡單:

/* Box sizing rules */
*,
*::before,
*::after {
box-sizing: border-box;
}

/* Remove default margin */
body,
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd {
margin: 0;
}

/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
ul[role='list'],
ol[role='list'] {
list-style: none;
}

/* Set core root defaults */
html:focus-within {
scroll-behavior: smooth;
}

/* Set core body defaults */
body {
min-height: 100vh;
text-rendering: optimizeSpeed;
line-height: 1.5;
}

/* A elements that don't have a class get default styles */
a:not([class]) {
text-decoration-skip-ink: auto;
}

/* Make images easier to work with */
img,
picture {
max-width: 100%;
display: block;
}

/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
font: inherit;
}

/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */
@media (prefers-reduced-motion: reduce) {
html:focus-within {
scroll-behavior: auto;
}

*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}

其中一些比較有意思的點,單看盒子模型:

*,
*::before,
*::after {
box-sizing: border-box;
}

Normalize.css 是不推薦這麼做的,大部分元素的 box-sizing 其實都是 content-box ,但是,對於實際開發,全部元素都設定為 border-box 其實是更便於操作的一種方式。

再看看在 使用者體驗可訪問性 方面的一些做法:

html:focus-within {
scroll-behavior: smooth;
}

scroll-behavior: smooth 意為平滑滾動,當然這裡是設定給了 html:focus-within 偽類,而不是直接給 html 賦予平滑滾動,這樣做的目的是隻對使用鍵盤 tab 鍵切換焦點頁面時,讓頁面進行平滑滾動切換,帶來更好的使用體驗。

如果我們設定瞭如下 CSS:

html {
scroll-behavior: smooth;
}

可能會起到一起副作用,譬如,當我們在頁面查詢元素時候(使用 Ctrl + F、或者 Mac 的 Commond + F),這段 CSS 程式碼可能會嚴重延緩我們的查詢速度:

再看看這段程式碼:

@media (prefers-reduced-motion: reduce) {
html:focus-within {
scroll-behavior: auto;
}

*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}

我曾經在 使用 CSS prefers-* 規範,提升網站的可訪問性與健壯性 [4] 介紹過 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 時,就應該把這個動畫去掉。

而上述 Reset 中的那段程式碼,正是用於當用戶開啟對應選項後,減弱頁面上的所有動畫效果。屬於對可訪問性的考慮。

結合實際環境

當然,結合實際環境,目前國內整體不太注重可訪問性相關的內容。

而且,許多業務根本無法拋棄一些老舊瀏覽器,仍然需要相容 IE 系列。

因此,對於現階段的 Reset 方案,可以靈活搭配:

  1. 如果你的業務場景仍然需要考慮一些老舊瀏覽器,依舊需要相容 IE 系列,Normalize.css 的大部分功能都還是非常好的選擇

  2. 如果你的業務場景只專注於 Chrome 或者是 Chromium 核心,Normalize.css 內的許多內容其實可能是一些實際中根本不會遇到或者用上的相容適配,可以進行必要的精簡

  3. 如果你的業務是全球化,面向的使用者不僅僅在國內,你應該開始考慮更多 可訪問性 相關的內容,上述的 Modern CSS Reset 可以借鑑一下

因此,更應該的情況是,根據實際的業務需要,吸收多個業界比較常見/知名的 Reset 方案形成自己業務適用的。

這裡再羅列一些常見及現代 CSS Reset 方案:

Reset 方案 簡介 Github Stars 數
normalize.css [5] CSS Reset 的現代替代方案 47.1K
sanitize.css [6] 提供一致的、跨瀏覽器的 HTML 元素預設樣式以及有用的預設樣式 4.8K
reseter.css [7] Normalize.css 和 CSS Reset 的未來替代方案 981
Modern-CSS-Reset [8] 小而美,重置合理的預設值的現代 CSS Reset 方案 2.4K

你會看到,其實大家都號稱自己是現代 CSS Reset 解決方案,但其實其內部做的 Reset 工作很多是我們根本用不上的。 有人喜歡小而美,有人喜歡大而全 ,實際使用的時候需要具體取捨,魔改合併成適合自己的才是最好的。

最後

好了,本文到此結束,希望對你有幫助 :)

如果還有什麼疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。

參考資料

[1]

reset.css 知多少: https://github.com/chokcoco/iCSS/issues/5

[2]

normalize.css V8.0.1: https://github.com/necolas/normalize.css

[3]

Modern-CSS-Reset: https://github.com/hankchizljaw/modern-css-reset

[4]

使用 CSS prefers-* 規範,提升網站的可訪問性與健壯性: https://github.com/chokcoco/iCSS/issues/118

[5]

normalize.css: https://github.com/necolas/normalize.css

[6]

sanitize.css: https://github.com/csstools/sanitize.css

[7]

reseter.css: https://github.com/resetercss/reseter.css

[8]

Modern-CSS-Reset: https://github.com/hankchizljaw/modern-css-reset

[9]

Github -- iCSS: https://github.com/chokcoco/iCSS

iCSS,不止於 CSS,如果你也對各種新奇有趣的前端(CSS)知識感興趣,歡迎關注 。 同時如果你有任何想法疑問,或者也想入群參與大前端技術討論,圍觀答疑解惑,共同成長進步,可以關注公眾號 加我微信,拉你入群

因為微信公眾號修改規則,如果不標星或點在看,你可能會收不到我公眾號文章的推送,請大家將本 公眾號星標 ,看完文章後記得 點下贊 或者 在看 ,謝謝各位!