现代 CSS

聊聊重置 CSS 那些事儿

特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)

重置CSS (Reset CSS) 最近因 @Elad 发布的最新版本而又热闹起来。加上我又热衷于 CSS,只要是有关于 CSS 最有趣、最新、最实用的方面,我都希望能第一时间在国内的社区呈现(分享)。那么问题来了,重置 CSS 已是很古老的话题了,在今天有啥好聊的呢?原本我也是这么想的,但 @Elad 最新版本的重置 CSS 项目,它还是非常有意思的,我觉得有必要拿出来和大家一起分享,或者说聊聊这里面有关于 CSS 方面的新特性。如果你对这方面的话题感兴趣(想一探究竟),那么接下来的内容值得你花点时间阅读。

重置 CSS 的发展进程

作为 Web 开发者(特别是CSSer)对于 重置 CSS (Reset CSS) 并不会感到陌生,而且在社区和团队都有着不同的版本的重置 CSS,最为粗暴的应该是下面这种样的:

* {
    margin: 0;
    padding: 0;
}

或者是:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

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

我想,在社区中有很多团队都是以这种粗暴方式来设置重置 CSS 的,但作为一名专业的 CSSer而言,是非常反感这种姿势的!

抛开这种粗暴的重置CSS不说,在整个社区(在 CSS 发展历程)中,最早的一份重置 CSS 样式表是由 @meyerweb 编写的,因此也常称为 Eric Meyer CSS Reset,也简称为 CSS Reset

随着 Web 技术不断的革新,Eric Meyer 的重置 CSS 也被冠上了“硬性” 的代名词,那是因为,他说在大多数情况下,我们不需要浏览器的基本样式,比如我们从 <h1><h6> 等元素得到的字号大小,或者<ul><ol>列表元素的默认样式。例如,我们使用列表只是为了语义,而且因为它在其他方面有助于 Web 的可访问性(A11Y)和 SEO。

因此,@Nicolas Gallagher 提出了一套更温和的重置 CSS,即 Normalize.css

他修复了不同浏览器中的实现差异。而且至今,它是很多 Web 项目必备的一个 CSS 样式表。而且很多优秀团队都在使用这个重置 CSS 样式表,比如说 Twitter、Github、Medium等,而且很多小团队也在使用该重置样式表(说不定你应该也还在使用,对吧)。

话又说回来了,为什么normalize.css 这么受欢迎呢?那是因为,它除了具备 “Eric Meyer CSS Reset” 特性之外,还重围了一些 DOM Shadown 相关的 CSS,比如 ::-moz-focus-inner::-webkit-file-upload-button等。

除此之外,你也有可能像我一样,两个重置 CSS 样式表都不使用,更喜欢根据自己团队或自己业务所需,定制一个更符合自己的重置 CSS。也有可能,你更喜欢所 Normalize.css 和 CSS Reset(Eric Meyer CSS Reset)结合使用。不过,这都不是最重要的,重要的是你有一个更符合自己的重置 CSS。

虽然说今天是 2021年(也马上就到2022年),但 Normalize.css 和 CSS Reset 都可以满足我们重置浏览器样式的需求。那么问题来了,为什么 @Elad重构一个新的重置CSS(被称为New CSS Reset)呢?

为了便于区分,我更喜欢把 @Elad 重构的重置 CSS 称为 Elad CSS Reset!

正如上图所示,Elad CSS Reset 中有很多新的 CSS 特性,这些新的 CSS 特性可以让我们创建一个更有效的重置CSS,同时也具备以往重置 CSS 相似的效果。

你可能和我一样,会对这里面使用到的一些新特性感到好奇,或者想一探究竟吧。如果是,那么花时间阅读后面的内容是非常值得的!

为什么需要重置 CSS

如果你是一位 Web 开发者,你应该听说过,有一个样式表叫客户端样式表(User Agent Stylesheet),而这个客户端指的是“浏览器”(对于Web开发者而言,客户端大多数情况之下指的是浏览器)。默认情况之下,不同的浏览器对 HTML 的默认样式的解析是有的差异的,比如说 <p> 元素,他在 Chrome 浏览器有这样一段默认的样式规则:

p {
    display: block;
    margin-block-start: 1em;
    margin-block-end: 1em;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
}

但这并不意味着,所有客户端(浏览器)对所有 HTML 元素的默认样式解析都是一样的。换句话说,在一个完美的世界中,每个浏览器都应该以完全相同的方式解析或应用所有的 CSS 规则。然而,在现实世界中并不是一个完美的世界,许多 HTML 的元素的 CSS 样式规则(默认样式规则)在不同的浏览器是解析是不一样的。

@Jens Oliver Meiert 整理了一份不同的浏览器的用户代理样式表的清单,如果你对此感兴趣的话,可以点击这里查阅

正基于这个原因,重置CSS孕育而生,它起着重要的作用:从页面元素中删除默认的样式,这样你就可以用你选择应用的属性“重新开始”。这很重要,有两个原因:

  • 将所有的浏览器放在一个公平的竞争环境中。不同的浏览器对元素应用不同的默认样式,所以你想让你的网站在所有不同的浏览器上看起来都一样,重置CSS就显得很重要
  • 它允许你在应用页面元素的marginpadding等属性时“向前思考”。在从元素中删除属性时,不必“逆向思考”,而只能将它们应用于你知道需要它们的元素

简而言之,重置CSS可以让所有浏览器对HTML的元素默认样式采用一样的解析!(当然,重置CSS会有遗漏,但大部分趋于一致,这也是重置CSS存在的目的)。

也就是说,使用一套精心设计的全局性的 重置CSS 样式,使设计者(Web 开发者)能够对浏览器的默认行为做出假设。这些假设极大地简化了只使用一套 CSS 规则来创建“普便”(能覆盖众多主流浏览器)一致的CSS设计的过程。这种过程的简化极大地节省了时间和金钱。许多业界的顶级设计师已(Web 开发者)经使用重置 CSS 多年,收获了不少成果。正如 @Jeff Starr 的《Killer Collection of CSS Resets》一文中所收集的全局重置 CSS 样式表。也从侧面说明了不同的场合,不同的团队使用了这些重置样式,并取得了一定的作用,甚至是你在此基础上构建出一个混合体,来满足自己开发所需。换句话说,这也是从侧面验证了重置 CSS 的必要性。

你可能不完全接受重置 CSS,但在一个团队中协同开发时,重置 CSS 还是有一定必要的。

聊聊 Elad 的重置CSS

@Elad 的重置 CSS 所起的作用和 Normalize.css 以及 Eric Meyer CSS Reset 是等同的,不同的是使用了一些新的 CSS 特性。别的不先说,先上代码吧:

/* 删除除 `display` 属性之外的客户端所有默认样式;symbol * 是为了解决 Firefox 浏览器中 SVG 雪碧图的 Bug */
*:where(:not(iframe, canvas, img, svg, video):not(svg *, symbol *)) {
    all: unset;
    display: revert;
}

/* box-sizing 的首选值*/
*,
*::before,
*::after {
    box-sizing: border-box;
}

/* 删除列表项默认标记符样式 */
ol, ul {
    list-style: none;
}

/* 让图片不超出容器宽度 */
img {
    max-width: 100%;
}

/* 删除表格单元格之间的间距 */
table {
    border-collapse: collapse;
}

/* 使用 revert 恢复 Safari 浏览器 textarea 元素的 white-space 属性值 */
textarea {
    white-space: revert;
}

上面的代码中有几个关键词,估计会令很多 Web 开发者感到陌生,比如 :where():not()allunsetrevert等。这些关键词是:

  • 全局性的 CSS 重置关键词 unsetrevert
  • 新的 CSS 属性 all 可以重置所有属性的组合
  • :where() 伪类选择器,消除 CSS 选择器权重
  • 带有多个参数的 :not()伪类选择器

从代码上来看,Elad 重置CSS想做的事情是 display 属性之外,我们不想使用任何客户端给HTML元素设置的默认样式。换句话说,这个重置CSS删除了我们在特定 HTML 元素(除<iframe><canvas><img><svg><video>这样的特殊元素)上得到的所有默认样式(display属性之外)。

如果你想恢复特定 HTML 元素的浏览器的默认样式,可以像下面代码这样来恢复:

input[type="checkbox"],
input[type="radio"] {
    all: revert;
}

即使用 all:revert可以恢复元素在浏览器中的默认样式。为什么呢?这都是后话(后面我们会提到)。

CSS 中的 all 属性

CSS 的 all 属性出自于 CSS Cascading and Inheritance Level 4,它可以重置除了directionunicode-bidi 之外的所有 CSS 属性。该属性的值为 initialinheritunsetrevert

  • initial:改变该元素或其父元素的所有属性的值为 initial
  • inherit:改变该元素或其父元素的所有属性的值至他们的父元素属性的值(继承父元素的属性值)
  • unset:如果该元素的属性的值是可继承的,则改变该元素或该元素的父元素的所有属性的值为他们的父元素的属性值,反之则改变为初始值
  • revert:指定依赖于声明所属的样式表原点的行为
    • “User-agent Origin”,相当于 unset
剩余80%内容付费后可查看
返回顶部