現(xiàn)代 CSS 解決方案:Modern CSS Reset
在早年間(其實(shí)也不是很早),寫過幾篇關(guān)于 CSS Reset 的文章 - reset.css 知多少[1]。
詳細(xì)描述了當(dāng)時(shí)業(yè)界比較常用的,兩個(gè) CSS reset 方案:reset.css 與 Normalize.css。
以更為推薦的 Normalize.css 為例,它的核心思想是:
統(tǒng)一了一些元素在所有瀏覽器下的表現(xiàn),保護(hù)有用的瀏覽器默認(rèn)樣式而不是完全清零它們,讓它們在各個(gè)瀏覽器下表現(xiàn)一致; 為大部分元素提供一般化的表現(xiàn); 修復(fù)了一些瀏覽器的 Bug ,并且讓它們在所有瀏覽器下保持一致性; 通過一些巧妙的細(xì)節(jié)提升了 CSS 的可用性; 提供了詳盡的文檔讓開發(fā)者知道,不同元素在不同瀏覽器下的渲染規(guī)則;
如今,Normalize 已經(jīng)出到了第八版 -- normalize.css V8.0.1[2],而隨之而變的是瀏覽器市場環(huán)境的巨大變化。
IE 已經(jīng)逐漸退出歷史舞臺,處理各個(gè)瀏覽器之間巨大差異、不同兼容性問題的日子像是一去不復(fù)返了。雖然今天不同廠商在對待標(biāo)準(zhǔn)仍然存在差異,一些細(xì)節(jié)上仍舊有出入,但是我們已經(jīng)不需要再像過去般大肆地對瀏覽器默認(rèn)樣式進(jìn)行重置。
到今天,我們更多聽到現(xiàn)代 CSS 解決方案一詞。它除去頁面樣式最基本的呈現(xiàn)外,同時(shí)也關(guān)注用戶體驗(yàn)與可訪問性。這也可能是過去,我們在寫 CSS 的時(shí)候比較容易忽略的環(huán)節(jié)。
Modern CSS Reset
我最近比較喜歡的一個(gè) CSS Reset 方案,源自于 -- Modern-CSS-Reset[3]。
它的核心觀點(diǎn)是:
重置合理的默認(rèn)值 關(guān)注用戶體驗(yàn) 關(guān)注可訪問性
整個(gè) 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;
??}
}
其中一些比較有意思的點(diǎn),單看盒子模型:
*,
*::before,
*::after?{
??box-sizing:?border-box;
}
Normalize.css 是不推薦這么做的,大部分元素的 box-sizing 其實(shí)都是 content-box,但是,對于實(shí)際開發(fā),全部元素都設(shè)置為 border-box 其實(shí)是更便于操作的一種方式。
再看看在用戶體驗(yàn)及可訪問性方面的一些做法:
html:focus-within?{
??scroll-behavior:?smooth;
}
scroll-behavior: smooth 意為平滑滾動,當(dāng)然這里是設(shè)置給了 html:focus-within 偽類,而不是直接給 html 賦予平滑滾動,這樣做的目的是只對使用鍵盤 tab 鍵切換焦點(diǎn)頁面時(shí),讓頁面進(jìn)行平滑滾動切換,帶來更好的使用體驗(yàn)。
如果我們設(shè)置了如下 CSS:
html?{
??scroll-behavior:?smooth;
}
可能會起到一起副作用,譬如,當(dāng)我們在頁面查找元素時(shí)候(使用 Ctrl + F、或者 Mac 的 Commond + F),這段 CSS 代碼可能會嚴(yán)重延緩我們的查找速度:

再看看這段代碼:
@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;
??}
}
我曾經(jīng)在 使用 CSS prefers-* 規(guī)范,提升網(wǎng)站的可訪問性與健壯性[4] 介紹過 prefers-reduced-motion。
prefers-reduced-motion 規(guī)則查詢用于減弱動畫效果,除了默認(rèn)規(guī)則,只有一種語法取值 prefers-reduced-motion: reduce,開啟了該規(guī)則后,相當(dāng)于告訴用戶代理,希望他看到的頁面,可以刪除或替換掉一些會讓部分視覺運(yùn)動障礙者不適的動畫類型。
規(guī)范原文: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 是一種視覺運(yùn)動障礙患者,翻譯出來是前庭運(yùn)動障礙,是一種會導(dǎo)致眩暈的一類病癥,譬如一個(gè)動畫一秒閃爍多次,就會導(dǎo)致患者的不適。
使用方法,還是上面那段代碼:
.ele?{
????animation:?aniName?5s?infinite?linear;
}
@media?(prefers-reduced-motion:?reduce)?{
????.ele?{
????????animation:?none;
????}
}
如果我們有一些類似這樣的動畫:

在用戶開啟了 prefers-reduced-motion: reduce 時(shí),就應(yīng)該把這個(gè)動畫去掉。
而上述 Reset 中的那段代碼,正是用于當(dāng)用戶開啟對應(yīng)選項(xiàng)后,減弱頁面上的所有動畫效果。屬于對可訪問性的考慮。
結(jié)合實(shí)際環(huán)境
當(dāng)然,結(jié)合實(shí)際環(huán)境,目前國內(nèi)整體不太注重可訪問性相關(guān)的內(nèi)容。
而且,許多業(yè)務(wù)根本無法拋棄一些老舊瀏覽器,仍然需要兼容 IE 系列。
因此,對于現(xiàn)階段的 Reset 方案,可以靈活搭配:
如果你的業(yè)務(wù)場景仍然需要考慮一些老舊瀏覽器,依舊需要兼容 IE 系列,Normalize.css 的大部分功能都還是非常好的選擇 如果你的業(yè)務(wù)場景只專注于 Chrome 或者是 Chromium 內(nèi)核,Normalize.css 內(nèi)的許多內(nèi)容其實(shí)可能是一些實(shí)際中根本不會遇到或者用上的兼容適配,可以進(jìn)行必要的精簡 如果你的業(yè)務(wù)是全球化,面向的用戶不僅僅在國內(nèi),你應(yīng)該開始考慮更多可訪問性相關(guān)的內(nèi)容,上述的 Modern CSS Reset 可以借鑒一下
因此,更應(yīng)該的情況是,根據(jù)實(shí)際的業(yè)務(wù)需要,吸收多個(gè)業(yè)界比較常見/知名的 Reset 方案形成自己業(yè)務(wù)適用的。
這里再羅列一些常見及現(xiàn)代 CSS Reset 方案:
| Reset 方案 | 簡介 | Github Stars 數(shù) |
|---|---|---|
| normalize.css[5] | CSS Reset 的現(xiàn)代替代方案 | 47.1K |
| sanitize.css[6] | 提供一致的、跨瀏覽器的 HTML 元素默認(rèn)樣式以及有用的默認(rèn)樣式 | 4.8K |
| reseter.css[7] | Normalize.css 和 CSS Reset 的未來替代方案 | 981 |
| Modern-CSS-Reset[8] | 小而美,重置合理的默認(rèn)值的現(xiàn)代 CSS Reset 方案 | 2.4K |
你會看到,其實(shí)大家都號稱自己是現(xiàn)代 CSS Reset 解決方案,但其實(shí)其內(nèi)部做的 Reset 工作很多是我們根本用不上的。有人喜歡小而美,有人喜歡大而全,實(shí)際使用的時(shí)候需要具體取舍,魔改合并成適合自己的才是最好的。
最后
好了,本文到此結(jié)束,希望對你有幫助 :)
如果還有什么疑問或者建議,可以多多交流,原創(chuàng)文章,文筆有限,才疏學(xué)淺,文中若有不正之處,萬望告知。
參考資料
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-* 規(guī)范,提升網(wǎng)站的可訪問性與健壯性: 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
