CSS Reset 的来龙去脉
目录
- 浏览器的默认样式
- 三种样式重置方法
- 硬重置
- 软重置
- 个性化重置
- Normalize.css 源码解析
- 总结
- 参考
浏览器的默认样式
作为一名 Web 开发者,我们都知道 Google 开发者工具的 Styles 面板,其中在 Styles 面板它的最右侧表明了此 CSS 的样式来源,比如下面这个,表示 user agent stylesheet
表示此样式来源浏览器默认样式。
元素有默认样式是没问题的,关键在于浏览器支持和理解的 CSS 规范不同,导致渲染页面时效果不一致,会出现很多兼容性问题,比如说老旧 IE 浏览器不支持 HTML5+ 标签,不同浏览器对 CSS 行为也不统一。
这就会导致两个问题:
- 处理浏览器的兼容性。
- 跨浏览器样式表现统一。
三种样式重置方法
为了解决上面两个问题,出现了 CSS Reaet 想法,根据对默认样式的改写的轻重程度,还可以进一步分为三类:
- 完全重置——硬重置。
- 规范化重置——软重置。
- 个性化重置。
硬重置
硬重置是一种非常激进的方法,它会清除浏览器默认样式,使所有的 HTML 标签行为都表现一致,即没有填充、没有边距、没有边框、相同的字体大小和相同的对齐方式等等。
这里以 YUI 的 CSS Reset 为例子演示下,HTML 代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>YUI CSS RESET</title>
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.18.1/build/cssreset/cssreset-min.css">
<style type="text/css"></style>
</head>
<body>
<h1>我是 h1 标签</h1>
<h6>我是 h6 标签</h6>
<a>我是 a 标签</a>
</body>
</html>
浏览器运行,你会看到,样式标签的是那么的统一:
cssreset-min.css这种世纪古董,项目中是严禁使用的,因为它会导致许多不必要的覆盖和放弃了浏览器原生支持的特性(比如 a 标签可以通过 Tab 访问高亮,在重视体验的二十一世纪,这怎么能够)。
我们明白了什么事硬重置,现在来了解下它出现的历史背景。
早期,浏览器支持和对 CSS 规范理解的不同,导致页面渲染行为不一致,出现了 CSS Reset。
传说最早的一份 CSS Reset来自 Tantek 的 undohtml.css,这个版本的样式重置很简单,简单的五条:
/* http://tantek.com/log/2004/undohtml.css */
/* undohtml.css */
/* (CC) 2004 Tantek Celik. Some Rights Reserved. */
/* http://creativecommons.org/licenses/by/2.0 */
/* This style sheet is licensed under a Creative Commons License. */
/* Purpose: undo some of the default styling of common (X)HTML browsers */
/* link underlines tend to make hypertext less readable,
because underlines obscure the shapes of the lower halves of words */
:link,:visited { text-decoration:none }
/* no list-markers by default, since lists are used more often for semantics */
ul,ol { list-style:none }
/* avoid browser default inconsistent heading font-sizes */
/* and pre/code too */
h1,h2,h3,h4,h5,h6,pre,code { font-size:1em; }
/* remove the inconsistent (among browsers) default ul,ol padding or margin */
/* the default spacing on headings does not match nor align with
normal interline spacing at all, so let's get rid of it. */
/* zero out the spacing around pre, form, body, html, p, blockquote as well */
/* form elements are oddly inconsistent, and not quite CSS emulatable. */
/* nonetheless strip their margin and padding as well */
ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,fieldset,input
{ margin:0; padding:0 }
/* whoever thought blue linked image borders were a good idea? */
a img,:link img,:visited img { border:none }
/* de-italicize address */
address { font-style:normal }
/* more varnish stripping as necessary... */
正因它太简陋了,所以后来继续出现了 Eric A. Meyer 版本的 CSS Reset,这里不贴源码了,相对于 Tantek 版本,多了对低版本浏览器 HTML5 的兼容考虑和一些样式风格的统一。
Eric A. Meyer 版本的 CSS Reset 还是简陋,后来出现了一个更全的,就是 YUI 出品的 CSS Reset 和 CSS Base。
npm 社区发展起来,还有像 Minireset.css 这种更加便于安装的现代 CSS Reset。
上面的 CSS Reset 都大同小异,本质就是一个硬重置样式,后来就出现一个更生猛也更能反应硬重置本质的 CSS 代码,即:
* { margin:0; padding:0; }
软重置
鉴于硬重置会导致许多不必要的覆盖和放弃了浏览器原生支持的特性,这两大不能忍受的缺点,后来人们就想到了一个折中办法,一种既可以保留部分浏览器的基础样式和特性,又可以统一浏览器的表现。
从而达到,当一个元素在不同的浏览器中具有不同的默认样式时,去尽可能使这些样式保持一致并符合现代标准。
软重置中的翘楚就是 Normalize.css,基于 HTML5 面现代浏览器的 CSS 重置方案:
A modern, HTML5-ready alternative to CSS resetsNormalize.css 规范了各种元素的样式,纠正了错误和常见的浏览器不一致,通过细微的修改提高了可用性,并使用详细的注释,解释了代码的作用。
如果说硬重置是对浏览器的无脑清零,那么软重置就是对浏览器有思考的增强。
Normalize.css 源代码里面有详细的注释,代码基本上都是在做关于浏览器兼容的处理的,所以你只需要打开不同的浏览器写下示例代码运行下就能明白了,但是其中有两条理解有点难度,我挑出来讲下。
先把源码复制过来:
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}
-
line-height
为什么是 1.15 呢?
W3C 定义 line-height 的默认值为 normal,normal 的值在不同浏览器规定为 1~2
,当字体的 font-size 为 100px ,大部分字体的 line-height 都为 115px ,所以这里选了 1.15。
-
text-size-adjust
是干啥的?
text-size-adjust 早期是用来解决 Chrome 浏览器字体不能小于 12px 问题的,后来 Chrome 不支持了,text-size-adjust 在 PC 端的作用就没用了,唯一的用处体现在 IPhone 手机上了,IPhone 手机在由竖屏切到横屏的时候,屏幕宽度大了,为了更好的文字体验,字体会变大。
但是,移动端布局我们有相应的方案,例如 REM,VW 等,这时候字体变大就有点多余了,所以 text-size-adjust 的值 为 100% 就是禁用 IOS 手机的这个效果的。
- font-family 的问题?
虽然 Normalize.css 没有对字体做出限制,但是推荐大家去看看这个关于 font-family 的 issue。
不同系统对字体的加载是有要求的,建议大家在项目中(比如你的全局样式文件中)加入以下代码:
font-family: -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif
个性化重置
个性化重置,其实就是我们使用的第三方 UI 框架,比如说 Ant Design,Element-UI 等等。
而这些 UI 框架,或多或少都用到了前面提到的软重置 Normalize.css 的知识。
小结
前端早期,各浏览器对 CSS 的规范支持和理解是不同的,为了解决网站风格的统一,出现了 CSS Reset 。
早期的 CSS Reset 无脑兼容各浏览器被称为硬重置,因为硬重置会导致许多不必要的覆盖和放弃了浏览器原生支持的特性,就被弃用了。
这时候出现了软重置,它只简单的规范了各种元素的样式和纠正一些错误,做到对元素最小的侵入,而软重置中的翘楚就是 Normalize.css。
最后的集大成者是个性化重置,就是我们平时用到第三方 UI 框架。
最后说一句,CSS Reset 是完全需要的,不然会导致网址布局的混乱,但同时记住不要使用硬重置做过多的事情,来保护 CSS 的原生特性。
参考
PS:CSS reset的重新审视 – 避免样式重置 看完,只能认同张大神 50% 的看法。
时间:2021 年 08 月 12 日 20:05