前置知识: CSS、CSS

CSS 重置与 normalize

4 min中级

浏览器默认样式差异的来源,以及 reset、normalize、现代重置方案的选择与写法。

0. 直觉:浏览器给 HTML 元素“预装了默认样式”

h1 为什么比 p 大?ul 为什么有缩进?按钮为什么有边框?因为浏览器内置了用户代理样式(user agent stylesheet)。问题是各家默认样式不完全一致,所以项目开头通常要“清场”或“统一”,这就是 CSS 重置。

1. 为什么需要重置

/* 没有重置时,不同浏览器对同一元素可能有细微差异 */
/* 例如 button 的默认 padding、字体、背景在不同浏览器不同 */

讲解: 重置解决两类问题:一是跨浏览器差异,二是默认样式(如 h1 外边距)干扰设计系统。但“全部清零”会丢掉有用的语义默认值,所以现代方案从“清空”走向“统一基线”。

2. 经典 reset:全部归零

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

讲解: 经典 reset 简单粗暴,把常见默认值清零。缺点是 * 选择器性能与继承语义欠佳,而且把所有 h1-h6 都抹成一样大小后,需要自己重建层级。

3. normalize.css:保留有用默认值

normalize.css 的思路不是清空,而是“把各浏览器默认样式拉齐”:

/* 示例(normalize.css 片段风格) */
html {
  line-height: 1.15;            /* 统一行高 */
  -webkit-text-size-adjust: 100%; /* 禁止横屏自动放大字号 */
}
body {
  margin: 0;
}

讲解: normalize 保留 h1 层级、列表缩进等语义默认值,只修差异。适合“希望浏览器默认值作为设计起点”的项目;代价是文件里有些规则你可能永远用不到。

4. 现代重置:兼顾基线与语义

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

body {
  margin: 0;
  font-family: system-ui, "PingFang SC", "Microsoft YaHei", sans-serif;
  line-height: 1.5;
  color: #333;
  -webkit-font-smoothing: antialiased;
}

img,
picture,
video {
  display: block;
  max-width: 100%;
}

button,
input,
textarea,
select {
  font: inherit;   /* 表单控件跟随页面字体 */
}

ul[role="list"],
ol[role="list"] {
  list-style: none;
}

讲解: 现代重置(如 Andy Bell 的现代 CSS Reset 思路)只做四件事:统一盒模型、去掉 body 外边距、媒体元素自适应、表单继承字体。保留标题层级与列表语义,配合 role 控制无标记列表。

5. 三种方案如何选

方案思路适用场景
经典 reset全部清零从零搭建、默认值不想要
normalize.css拉齐差异依赖浏览器默认语义
现代重置最小统一设计系统/组件库首选

讲解: 现代项目推荐“现代重置 + 设计令牌(CSS 变量)”,框架项目(Tailwind 等)自带预置,通常不需要再引 normalize。工程化细节见 css/560-CSSArchitectureMethodology。

6. 动手试试

  1. 不写任何 CSS,对比 Chrome 与 Edge(或手机浏览器)中同一页面的默认间距差异;
  2. 分别应用经典 reset 与现代重置,对比 h1 大小、列表缩进、按钮字体的变化;
  3. 给 <img> 加 display: block; max-width: 100%,观察图片底部间隙消失;
  4. 进阶挑战:为你的项目写一份 20 行以内的“现代重置”,并注释每行的目的。

7. 核心知识点

一句话记住重置方案:reset 全清零,normalize 拉齐差异,现代重置只统一基线;盒模型统一 + 媒体自适应 + 表单继承字体是底线。

  • 浏览器默认样式是用户代理样式,优先级最低;
  • 经典 reset:* { margin: 0; padding: 0 },简单但粗暴;
  • normalize.css:保留语义默认值,只修差异;
  • 现代重置:统一盒模型、图片块级化、表单继承字体;
  • box-sizing: border-box 全局统一是重置的核心项;
  • 框架项目自带预置,不必重复引入。

8. 注意事项与改进建议

问题点说明改进方案
重置后又把默认值写回来重复劳动先列设计基线,再决定重置范围
* { margin:0 } 破坏间距语义所有元素都需重设间距用现代重置 + 间距令牌
引入 normalize 又手写 reset规则冲突难排查二选一,推荐现代重置
重置文件放最后覆盖自己的业务样式重置必须放最前,未分层时会被业务覆盖

9. 扩展学习

  • 盒模型与 box-sizing:css/050-CSS3BoxModelDetailed;
  • 继承与层叠:css/160-CascadeInheritanceBasics;
  • 层叠层 @layer(重置入层):css/450-CascadeLayer;
  • 架构方法论:css/560-CSSArchitectureMethodology。