現(xiàn)代 CSS 解決方案:Modern CSS Reset
在早年間(其實(shí)也不是很早),寫過(guò)幾篇關(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)樣式而不是完全清零它們,讓它們?cè)诟鱾€(gè)瀏覽器下表現(xiàn)一致。
- 為大部分元素提供一般化的表現(xiàn)。
- 修復(fù)了一些瀏覽器的 Bug ,并且讓它們?cè)谒袨g覽器下保持一致性。
- 通過(guò)一些巧妙的細(xì)節(jié)提升了 CSS 的可用性。
- 提供了詳盡的文檔讓開發(fā)者知道,不同元素在不同瀏覽器下的渲染規(guī)則。
如今,Normalize 已經(jīng)出到了第八版 -- normalize.css V8.0.1[2],而隨之而變的是瀏覽器市場(chǎng)環(huán)境的巨大變化。
IE 已經(jīng)逐漸退出歷史舞臺(tái),處理各個(gè)瀏覽器之間巨大差異、不同兼容性問題的日子像是一去不復(fù)返了。雖然今天不同廠商在對(duì)待標(biāo)準(zhǔn)仍然存在差異,一些細(xì)節(jié)上仍舊有出入,但是我們已經(jīng)不需要再像過(guò)去般大肆地對(duì)瀏覽器默認(rèn)樣式進(jìn)行重置。
到今天,我們更多聽到現(xiàn)代 CSS 解決方案一詞。它除去頁(yè)面樣式最基本的呈現(xiàn)外,同時(shí)也關(guān)注用戶體驗(yàn)與可訪問性。這也可能是過(guò)去,我們?cè)趯?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 的源碼比較簡(jiǎn)單:
/* 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,但是,對(duì)于實(shí)際開發(fā),全部元素都設(shè)置為 border-box 其實(shí)是更便于操作的一種方式。
再看看在用戶體驗(yàn)及可訪問性方面的一些做法:
html:focus-within {
scroll-behavior: smooth;
}
scroll-behavior: smooth 意為平滑滾動(dòng),當(dāng)然這里是設(shè)置給了 html:focus-within 偽類,而不是直接給 html 賦予平滑滾動(dòng),這樣做的目的是只對(duì)使用鍵盤 tab 鍵切換焦點(diǎn)頁(yè)面時(shí),讓頁(yè)面進(jìn)行平滑滾動(dòng)切換,帶來(lái)更好的使用體驗(yàn)。
如果我們?cè)O(shè)置了如下 CSS:
html {
scroll-behavior: smooth;
}
可能會(huì)起到一起副作用,譬如,當(dāng)我們?cè)陧?yè)面查找元素時(shí)候(使用 Ctrl + F、或者 Mac 的 Commond + F),這段 CSS 代碼可能會(huì)嚴(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] 介紹過(guò) prefers-reduced-motion。
prefers-reduced-motion 規(guī)則查詢用于減弱動(dòng)畫效果,除了默認(rèn)規(guī)則,只有一種語(yǔ)法取值 prefers-reduced-motion: reduce,開啟了該規(guī)則后,相當(dāng)于告訴用戶代理,希望他看到的頁(yè)面,可以刪除或替換掉一些會(huì)讓部分視覺運(yùn)動(dòng)障礙者不適的動(dòng)畫類型。
規(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)動(dòng)障礙患者,翻譯出來(lái)是前庭運(yùn)動(dòng)障礙,是一種會(huì)導(dǎo)致眩暈的一類病癥,譬如一個(gè)動(dòng)畫一秒閃爍多次,就會(huì)導(dǎo)致患者的不適。
使用方法,還是上面那段代碼:
.ele {
animation: aniName 5s infinite linear;
}
@media (prefers-reduced-motion: reduce) {
.ele {
animation: none;
}
}
如果我們有一些類似這樣的動(dòng)畫:
在用戶開啟了 prefers-reduced-motion: reduce 時(shí),就應(yīng)該把這個(gè)動(dòng)畫去掉。
而上述 Reset 中的那段代碼,正是用于當(dāng)用戶開啟對(duì)應(yīng)選項(xiàng)后,減弱頁(yè)面上的所有動(dòng)畫效果。屬于對(duì)可訪問性的考慮。
結(jié)合實(shí)際環(huán)境
當(dāng)然,結(jié)合實(shí)際環(huán)境,目前國(guó)內(nèi)整體不太注重可訪問性相關(guān)的內(nèi)容。
而且,許多業(yè)務(wù)根本無(wú)法拋棄一些老舊瀏覽器,仍然需要兼容 IE 系列。
因此,對(duì)于現(xiàn)階段的 Reset 方案,可以靈活搭配:
- 如果你的業(yè)務(wù)場(chǎng)景仍然需要考慮一些老舊瀏覽器,依舊需要兼容 IE 系列,Normalize.css 的大部分功能都還是非常好的選擇。
- 如果你的業(yè)務(wù)場(chǎng)景只專注于 Chrome 或者是 Chromium 內(nèi)核,Normalize.css 內(nèi)的許多內(nèi)容其實(shí)可能是一些實(shí)際中根本不會(huì)遇到或者用上的兼容適配,可以進(jìn)行必要的精簡(jiǎn)。
- 如果你的業(yè)務(wù)是全球化,面向的用戶不僅僅在國(guó)內(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 方案:
你會(huì)看到,其實(shí)大家都號(hào)稱自己是現(xiàn)代 CSS Reset 解決方案,但其實(shí)其內(nèi)部做的 Reset 工作很多是我們根本用不上的。有人喜歡小而美,有人喜歡大而全,實(shí)際使用的時(shí)候需要具體取舍,魔改合并成適合自己的才是最好的。
最后
好了,本文到此結(jié)束,希望對(duì)你有幫助 :)
參考資料
[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-* 規(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。