原文链接:
https://elad.medium.com/normalize-css-or-css-reset-9d75175c5d1e
本文已同步归纳在 Github。
更新
[2021-2-22]
- Initial release
[2021-2-26]
Added
- 完成剩余章节的翻译
概述
通常情况下,我们希望某个 HTML 元素在不同浏览器上具有相同的展示效果。但是遗憾的是,每个浏览器处理 HTML 展示的方式都不同。
那么到底是使用 Normalize CSS 还是 CSS Reset 来消除不同浏览器的样式差异,目前还是存在争议的。
在深入讲解我推荐的使用方式之前,我首先要向大家解释一下几个你们可能不太熟悉的术语。
CSS 的 User-Agent 样式
在渲染 HTML 页面的时候,浏览器会在应用你自己编写的样式之前,首先应用其自身的基础样式表。举个例子,从 <h1>
到 <h6>
的 HTML 标签在所有的浏览器里面的展示效果都和其它普通文本不同:一般情况下,诸如 <h1>
这类标签的文字会大一些、字体会粗一些(font-weight: bold
),并且会有向上 & 向下两个方向的外边距。
虽然所有浏览器都应用了它们自己的默认样式表,但是每个浏览器的默认样式表彼此之前也存在差异,所以会产生一些问题,这也就是本文所探讨的。
有两种方式可以解决不同浏览器的样式不一致的问题:Normalize CSS 和 CSS Reset。你可以把 Normalize CSS 想象为一个温和的小绵羊;把 CSS Reset 想象为一个粗鲁的大怪兽。下面,让我来举例讲解。
Normalize CSS
Normalize.css
是一个小型的 CSS 文件,使得 HTML 元素的默认样式提供了跨浏览器的一致性。
这就意味着如果我们在 W3C 上查阅浏览器所应用的样式的规范的时候,不同浏览器的规范是不一样的,而 normalize.css
会修复不同浏览器产生的样式差异。
但是对于 IE 和 EDGE 这样的浏览器,normalize.css
并不能按照规范来抹平差异,因此 normalize.css
会把 IE 和 EDGE 中特定的样式应用到其它浏览器中。
举个实际的例子:对于类似 <article>
/ <aside>
/ <nav>
/ <section>
标签内部的 <h1>
标签,Chrome、Safari 和 Firefox 渲染得到的最终 font-size 会小于单独的 <h1>
标签,并且 margin 大小也有所不同。<article>
/ <aside>
/ <nav>
/ <section>
标签内部的 <h1>
标签在 Chrome、Safari、Firefox 的默认样式表(User-Agent-Stylesheet)里的样式如下:
1 | :-webkit-any(article,aside,nav,section) h1 { |
而 IE 和 EDGE 则很少出现上述这种情况,所以理论上我们可以把同样的样式直接复用到 IE 和 EDGE 浏览器上,但是由于 IE/EDGE 并没有 “any” 选择器,所以直接复用是不可取的。因此,Normalize CSS 索性直接把 IE/EDGE 中的 <h1>
样式作为基准样式。
示例代码如下:
1 | /* |
Normalize.css 是 Nicolas Gallagher 在 Github 上开源的一款项目:
https://github.com/necolas/normalize.css/blob/master/normalize.css
Reset CSS
使用 Reset CSS 就意味着我们不再需要浏览器的默认样式。“CSS Reset” 会把浏览器的 user-agent 样式全部重置掉,这样我们在写项目的时候就可以按需定义 CSS 样式。
上个章节的示例中使用 Reset CSS 也是可以正常工作的,对于 <h1>
到 <h6>
这些标签的默认样式:更多情况下我们并不想要浏览器提供的默认的 font-size
和 margin
。
CSS Reset 分很多种,如下是从 Eric Meyer 编写的 CSS Reset 样式文件中摘取的一小部分:
1 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { |
解释一下上面的代码:我们给所有 HTML 元素定义了无内边距、无外边距、无边框、相同的字体大小以及相同的对齐方式。
上面的代码虽然已经重置了 <h1>
到 <h6>
以及 <ul>
和 <li>
等标签的样式,但事实上看起来很臃肿,原因如下:
- 充斥了大量的选择器
- 大量无意义的样式覆盖
- 很难调试
如何同时使用 Normalize CSS & CSS Reset
我的建议是使用 Normalize CSS,但是你可以在其中掺杂一些 CSS Reset。
在我自己的项目里面,我深切地体会到了 Normalize CSS 和 CSS Reset 带来的好处:一方面是 Normalize CSS;而另一方面是 CSS Reset 可以避免冗长的 CSS 选择器链条。
编写你自己的 CSS Reset
在我这 13 年的工作生涯里,对于一些频繁的需要重置样式的 HTML 标签,比如:链接的颜色、按钮的默认样式和列表的默认样式等等,我颇有见解。
除了使用 normalize.css
之外,我还编写了自己的样式覆盖文件——reset.local.css
。与传统的 CSS Reset 不同的是:我在其中只重置了一小部分 HTML 标签的样式,而不是全部的。
下面的例子教你怎么自定义 CSS Reset:
我的 CSS Reset——reset.local.css
1 | /****** Elad Shechter's RESET *******/ |
上面的样式看起来更加具有可读性。
基本布局
在我的项目中除了使用 normalize.css
和 local.reset.css
之外,还有其它的基本布局文件。这个文件和 normalize CSS、CSS reset没啥关系,是网站排版的基础样式,包含:direction
、font-family
、font-size
、line-height
、文字颜色等属性。
typography.css
1 | html{ |
结合使用
得益于 SASS 预处理器的强大功能,我创建了一个 _reset.scss
文件,包括三个部分:
- Normalize.css —— Github 上最新版本的 CSS Normalize
- 我自己的 CSS Reset
- 一份基本布局文件
_resets.scss 文件如下:
1 | @import "resets/normalize.scss"; |
总结
本文主要向大家介绍了 Normalizing & Resetting 样式,同时这也是我的 CSS 系列文章的第一篇,接下来的几周,我将陆续撰写其它的相关文章。
如果你对这个专题感兴趣的话,欢迎订阅我的 twitter 或 medium。