正文從這里開(kāi)始。 大部分的時(shí)候,作為前端,我們?cè)趯?xiě) CSS 樣式之前,都知道需要添加一份 reset.css ,但是有深究過(guò) reset.css 每一句的人恐怕不多,其實(shí)其中也是有很多學(xué)問(wèn)的,知己知彼,真正理清它,對(duì)提高 CSS 大有裨益
reset.css
先來(lái)看看早先 YUI 的一個(gè)版本的 reset.css,這是一份歷史比較悠久的 RESET 方案:
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, p, blockquote, th, td {
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
fieldset, img {
border: 0;
}
address, caption, cite, code, dfn, em, strong, th, var {
font-style: normal;
font-weight: normal;
}
ol, ul {
list-style: none;
}
caption, th {
text-align: left;
}
h1, h2, h3, h4, h5, h6 {
font-size: 100%;
font-weight: normal;
}
q:before, q:after {
content: '';
}
abbr, acronym {
border: 0;
}
首先,我們要知道 CSS RESET 的目的是什么?是為了消除不同的瀏覽器在默認(rèn)樣式上不同表現(xiàn),但是到今天,現(xiàn)代瀏覽器在這方面的差異已經(jīng)小了很多。
reset.css 存在的問(wèn)題
看看第一段:
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, p, blockquote, th, td {
margin: 0;
padding: 0;
}
這一條樣式的目的是在于,清除元素的默認(rèn) margin 和 padding 。
但是這一段代碼是充滿(mǎn)問(wèn)題的。
- 諸如 div 、dt、li 、th、td 等標(biāo)簽是沒(méi)有默認(rèn) padding 和 margin 的;
- 如果我現(xiàn)在問(wèn)你 fieldset 是什么標(biāo)簽,可能沒(méi)幾個(gè)人知道,相似的還有如 blockquote 、acronym 這種很生僻的標(biāo)簽,在 html 代碼中基本不會(huì)出現(xiàn)的,其實(shí)沒(méi)太大必要 RESET ,只會(huì)給每個(gè)項(xiàng)目徒增冗余代碼;
上面的意思是,這一段代碼其實(shí)做了很多無(wú)用功!
要知道,CSS RESET 的作用域是全局的。我們都知道在腳本代碼中應(yīng)該盡量避免濫用全局變量,但是在 CSS 上卻總是會(huì)忘記這一點(diǎn),大量的全局變量會(huì)導(dǎo)致項(xiàng)目大了之后維護(hù)起來(lái)非常的棘手。
再看看這一段:
h1, h2, h3, h4, h5, h6 {
font-size: 100%;
font-weight: normal;
}
ol, ul {
list-style: none;
}
這一段代碼,目的是統(tǒng)一了 h1~h6 的表現(xiàn),取消了標(biāo)題的粗體展示,取消了列表元素的項(xiàng)目點(diǎn)。
好像沒(méi)什么問(wèn)題,但是諸如 h1~h6、ol、ul 這些擁有具體語(yǔ)義化的元素,一旦去掉了它們本身的特性,而又沒(méi)有賦予它們本身語(yǔ)義化該有的樣式(經(jīng)常沒(méi)有),導(dǎo)致越來(lái)越多人弄不清它們的語(yǔ)義,側(cè)面來(lái)說(shuō),這也是現(xiàn)在越來(lái)越多的頁(yè)面上 div 滿(mǎn)天飛,缺乏語(yǔ)義化標(biāo)簽的一個(gè)重要原因。
YUI 版本的 reset 不管高矮胖瘦,一刀切的方式,看似將所有元素統(tǒng)一在同一起跑線上,實(shí)則是多了很多冗余代碼,得不償失。
所以,YUI 的 reset.css 的諸多問(wèn)題,催生出了另一個(gè)版本的 reset.css ,名為 Normalize.css。
Normalize.css
Normalize.css 有著詳盡的注釋?zhuān)捎谄L(zhǎng),可以點(diǎn)開(kāi)網(wǎng)址看看,本文不貼出全部代碼。
Normalize.css 與 reset.css 的風(fēng)格恰好相反,沒(méi)有不管三七二一的一刀切,而是注重通用的方案,重置掉該重置的樣式(例如body的默認(rèn)margin),保留該保留的 user agent 樣式,同時(shí)進(jìn)行一些 bug 的修復(fù),這點(diǎn)是 reset 所缺乏的。
Normalize.css 做了什么
- 統(tǒng)一了一些元素在所有瀏覽器下的表現(xiàn),保護(hù)有用的瀏覽器默認(rèn)樣式而不是完全清零它們,讓它們?cè)诟鱾€(gè)瀏覽器下表現(xiàn)一致;
- 為大部分元素提供一般化的表現(xiàn);
- 修復(fù)了一些瀏覽器的 Bug ,并且讓它們?cè)谒袨g覽器下保持一致性;
- 通過(guò)一些巧妙的細(xì)節(jié)提升了 CSS 的可用性;
- 提供了詳盡的文檔讓開(kāi)發(fā)者知道,不同元素在不同瀏覽器下的渲染規(guī)則;
真心建議各位抽時(shí)間讀一讀 Normalize.css 的源碼,加上注釋一共就 460 行,多了解了解各個(gè)瀏覽器歷史遺留的一些坑。
關(guān)于取舍
那么,最后再討論下取舍問(wèn)題。是否 Normalize.css 就真的比 reset.css 好呢?
也不見(jiàn)得,Normalize.css 中重置修復(fù)的很多 bug ,其實(shí)在我們的項(xiàng)目中十個(gè)項(xiàng)目不見(jiàn)得有一個(gè)會(huì)用得上,那么這些重置或者修復(fù),某種意義上而言也是所謂的冗余代碼。
我覺(jué)得最重要的是,拒絕拿來(lái)主義,不要人云亦云,看見(jiàn)別人說(shuō)這個(gè) reset.css 好用,也不了解一下,拿來(lái)就上到項(xiàng)目中。又或者說(shuō)寫(xiě)代碼幾年了,知道每次都引用一個(gè) reset ,卻從沒(méi)有去細(xì)致了解其中每一句的含義。
關(guān)于維護(hù)
當(dāng)團(tuán)隊(duì)根據(jù)項(xiàng)目需要(可能混合部分了 reset 或者 normalize )編寫(xiě)了一份適合團(tuán)隊(duì)項(xiàng)目的 reset 之后,隨著不斷的迭代或者說(shuō)是復(fù)用,很有可能這個(gè)版本的 reset.css 會(huì)逐漸添加許多其他的全局性的樣式,從而又重新陷入上面說(shuō)的那些問(wèn)題。
所以我覺(jué)得,reset.css 也是需要維護(hù)的,關(guān)于最佳的 reset.css ,沒(méi)有一勞永逸的方案,根據(jù)項(xiàng)目靈活配置,做出取舍微調(diào),適量裁剪和修改后再使用。