Article

CSS 文档

更新于:2026-07-07

第 1 章:CSS 基础语法与应用

1.1 CSS 的作用与核心概念

项目内容
定义CSS (Cascading Style Sheets),层叠样式表,用于描述 HTML 或 XML(包括 SVG)文档的呈现方式(外观和格式)。
核心作用1. 分离关注点 (Separation of Concerns):将网页的结构 (HTML) 与表现 (CSS) 分离。
2. 控制视觉样式:精确控制元素的颜色、字体、布局、大小、位置、动画等。
3. 提高效率与维护性:一套 CSS 可以控制多个页面,修改样式无需改动 HTML 结构。
4. 实现响应式设计:根据设备特性(如屏幕尺寸)动态调整页面布局。
与 HTML 关系HTML 负责”是什么”(What),CSS 负责”长什么样”(How)。两者协同工作构建现代网页。
类比说明想象 HTML 是一栋房子的钢筋水泥骨架和房间划分,而 CSS 则是房子的装修风格、墙纸颜色、家具摆放。

关键要点:

  • CSS 是 Web 前端三大基石之一(HTML, CSS, JavaScript)。
  • “层叠 (Cascading)” 指的是当多个样式规则应用于同一元素时,浏览器如何决定最终样式(通过特异性、来源顺序等规则)。

1.2 CSS 语法规则:选择器、声明块、属性与值

项目内容
语法结构选择器 { 属性: 值; }
选择器 (Selector)指定需要应用样式的 HTML 元素。可以是标签名 (p)、类名 (.class)、ID 名 (#id) 或更复杂的组合。
声明块 (Declaration Block)由一对花括号 {} 包围,包含一个或多个声明。
声明 (Declaration)由一个属性和一个值组成,中间用冒号 : 分隔,以分号 ; 结尾。
属性 (Property)定义要修改的样式方面,如 color, font-size, margin。
值 (Value)属性的具体设置,如 red, 16px, 10px。

代码示例

/* 选择器 */
p {
  /* 声明块开始 */
  color: blue;        /* 声明1:属性: 值; */
  font-size: 18px;    /* 声明2:属性: 值; */
} /* 声明块结束 */

多声明示例

h1 {
  color: green;
  background-color: yellow;
  padding: 10px;
  margin-bottom: 20px;
  /* 每个声明都以分号结尾 */
}

单行 vs 多行

  • 单行写法(紧凑):p { color: blue; font-size: 18px; }
  • 多行写法(推荐,易读):如上所示。

关键要点:

  • 分号 ; 至关重要:它是声明的结束符。最后一个声明的分号可省略,但强烈建议始终添加以避免错误和便于扩展。
  • 选择器决定了”谁”被影响,声明块决定了”如何”被影响。

1.3 引入 CSS 的方式:内联样式、内部样式表、外部样式表(<link>

引入方式方法描述优点缺点使用场景
内联样式 (Inline Styles)直接在 HTML 元素的 style 属性中编写 CSS 规则。- 权重最高,优先级最高。
- 即时生效。
- 严重违反结构与表现分离原则。
- 无法复用,维护性极差。
- 代码冗余。
仅用于临时调试或极少数必须覆盖所有其他样式的场景。
内部样式表 (Internal/Embedded Stylesheet)在 HTML 文档的 <head> 部分使用 <style> 标签包裹 CSS 代码。- 样式集中在一个文件内。
- 不污染全局。
- 样式与 HTML 仍在同一文件,未完全分离。
- 无法跨页面复用。
适用于单页应用或样式非常简单的独立页面。
外部样式表 (External Stylesheet)将 CSS 代码写在独立的 .css 文件中,然后在 HTML 的 <head> 中使用 <link> 标签引入。- 最佳实践!
- 完全实现结构与表现分离。
- 高度可复用(一个 CSS 文件可被多个 HTML 文件引用)。
- 易于维护和更新(改一处,所有引用处生效)。
- 浏览器可缓存 CSS 文件,提升加载速度。
- 需要额外的 HTTP 请求来加载 CSS 文件(现代优化可缓解)。所有生产环境项目的标准做法。

代码示例

内联样式

<p style="color: red; font-weight: bold;">红色粗体段落。</p>

内部样式表

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>内部样式表</title>
    <style>
      body { background-color: #f0f0f0; }
      p { color: blue; }
    </style>
  </head>
  <body>
    <p>这个段落是蓝色的。</p>
  </body>
</html>

外部样式表

styles.css:

/* styles.css */
body { background-color: #e0e0e0; }
h1 { color: purple; }

index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>外部样式表</title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <h1>标题</h1>
    <p>正文</p>
  </body>
</html>

关键要点:

  • 优先级:内联 > 内部 > 外部(在特异性相同的情况下)
  • 文件路径:href 属性中的路径需正确指向 .css 文件(相对路径或绝对路径)。
  • rel="stylesheet":这是必需的属性,告诉浏览器链接的是样式表。

1.4 CSS 注释 (/* … */) 与代码组织

项目内容
注释语法/* 这是一个 CSS 注释,可以跨越多行 */

代码示例

/* **************************************
 * 页面通用样式
 * Author: Your Name
 * Date: 2025-09-11
 ************************************** */

body, h1, h2, p {
  margin: 0;
  padding: 0;
}

/* 导航栏样式 */
.navbar {
  background-color: #333; /* 深灰色背景 */
  overflow: hidden; /* 清除浮动并隐藏溢出 */
}

.navbar a {
  float: left; /* 链接左浮动 */
  color: white; /* 白色文字 */
  text-align: center;
  padding: 14px 20px;
  text-decoration: none; /* 去掉下划线 */
}

注释用途

  • 解释复杂逻辑:说明为什么这样写 CSS。
  • 标记代码区域:如 /* Header Styles */, /* Footer Styles */
  • 临时禁用代码:将不想生效的 CSS 代码块用 /* */ 包裹起来。
  • 添加作者、日期、版权信息。

代码组织建议

  • 按功能/模块分组:将相关的样式放在一起(如头部、导航、内容、侧边栏、底部)。
  • 使用空行分隔:不同功能模块之间用空行隔开,提高可读性。
  • 保持缩进一致:使用统一的缩进(通常 2 或 4 个空格)。
  • 合理排序属性:可按字母顺序或逻辑分组(如盒模型 -> 排版 -> 视觉 -> 布局)。

关键要点:

  • CSS 不支持 // 单行注释(这是预处理器或 JS 的语法)。
  • 注释不会被浏览器渲染,不影响页面性能,但会使文件体积略微增大(可忽略)。
  • 养成写注释的好习惯,尤其是团队协作或长期维护的项目。

1.5 CSS 文件结构与最佳实践

文件结构示例

project-root/
├── index.html
├── css/
│   ├── reset.css      # (可选) CSS Reset 或 Normalize.css
│   ├── base.css       # 基础样式 (body, typography, links)
│   ├── layout.css     # 布局相关 (header, footer, grid)
│   ├── components.css # 可复用组件 (buttons, cards, modals)
│   ├── pages.css      # 特定页面样式 (home.css, about.css)
│   └── theme.css      # 主题变量 (colors, fonts)
└── …
项目说明
文件拆分策略• reset.css / normalize.css: 统一不同浏览器的默认样式差异。
• base.css: 设置全局基础样式(字体、链接、列表等)。
• layout.css: 定义页面整体框架和网格系统。
• components.css: 存放按钮、卡片、表单控件等 UI 组件的样式。
• pages.css: 针对特定页面的独特样式。
• theme.css: 使用 CSS 自定义属性 (--primary-color: #007bff;) 定义主题变量,方便全局更换主题。
命名约定• 小写字母 + 连字符 (-):main-content, user-profile
• 避免使用下划线 (_) 或驼峰命名 (camelCase)。
• 语义化命名:名称应反映其用途或含义,而非外观(如 .btn-primary.blue-button 更好)。

最佳实践总结

  1. 始终使用外部样式表。
  2. 拥抱模块化:将样式拆分成小的、专注的文件。
  3. 利用 CSS 自定义属性:管理颜色、间距、字体等变量,提升一致性与可维护性。
  4. 遵循 BEM/OOCSS 等方法论:解决命名冲突和样式蔓延问题。
  5. 使用版本控制 (Git):跟踪样式变更。
  6. 考虑使用预处理器 (Sass/Less):它们提供了变量、嵌套、混合等功能,能更好地组织大型 CSS 项目。

关键要点:

  • 良好的文件结构是大型项目成功的关键。
  • normalize.css 比传统的 reset.css 更受欢迎,因为它保留了有用的默认样式,只修复不一致的地方。

第 2 章:选择器详解

2.1 基础选择器:元素、类、ID、通配符

选择器类型语法作用关键要点
元素选择器element选择指定类型的 HTML 元素。• 最基础的选择器。
• 会影响文档中所有该类型的元素。
类选择器.classname选择具有指定 class 属性值的元素。• 可复用性最强,一个类可在多个元素上使用。
• 一个元素可以有多个类(class="highlight important"),用空格分隔。
• 类名区分大小写。
ID 选择器#idname选择具有指定 id 属性值的唯一元素。• ID 在页面中必须是唯一的(HTML 规范要求)。
• 优先级高于类选择器和元素选择器。
• 过度使用 ID 会降低 CSS 的可复用性。
通配符选择器*选择文档中的所有元素。• 性能较低,应谨慎使用,避免在复杂选择器中滥用。
• 常用于全局重置或特定上下文下的批量设置。

代码示例

元素选择器

/* 选择所有 <p> 段落 */
p {
  color: black;
  font-size: 16px;
}

/* 选择所有 <h1> 标题 */
h1 {
  margin-bottom: 20px;
}

类选择器

HTML:

<p class="highlight">这个段落有高亮样式。</p>
<div class="highlight">这个 div 也有高亮样式。</div>

CSS:

/* 选择所有 class="highlight" 的元素 */
.highlight {
  background-color: yellow;
}

ID 选择器

HTML:

<div id="header">这是页面头部</div>

CSS:

/* 选择 id="header" 的元素 */
#header {
  background-color: #333;
  color: white;
  padding: 20px;
}

通配符选择器

/* 重置所有元素的内外边距 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* 选择 body 内的所有后代元素 */
body * {
  font-family: Arial, sans-serif;
}

2.2 组合选择器:后代、子代、相邻兄弟、通用兄弟

组合方式语法作用关键要点
后代选择器A B选择 A 元素内部的所有 B 元素(无论嵌套多深)。• 应用最广泛的组合方式。
• 空格是后代选择器的关键。
子代选择器A > B选择 A 元素的直接子元素 B(只限一层嵌套)。> 符号表示“直接子元素”。
• 比后代选择器更精确,避免意外样式污染。
相邻兄弟选择器A + B选择紧接在 A 元素之后的同级 B 元素(必须是下一个兄弟)。+ 号连接两个同级元素。
• 必须是紧邻的下一个兄弟元素。
通用兄弟选择器A ~ B选择 A 元素之后的所有同级 B 元素(不要求紧邻)。~ 波浪号表示“之后的所有同级兄弟”。
• 范围比相邻兄弟选择器更广。

代码示例

后代选择器

HTML:

<div class="container">
  <p>第一层段落</p>
  <section>
    <p>第二层段落(也被选中)</p>
  </section>
</div>

CSS:

/* 选择 .container 内部的所有 <p> 元素 */
.container p {
  color: blue;
}

子代选择器

HTML:

<div class="container">
  <p>直接子段落(被选中)</p>
  <section>
    <p>非直接子段落(不被选中)</p>
  </section>
</div>

CSS:

/* 选择 .container 的直接子 <p> 元素 */
.container > p {
  font-weight: bold;
}

相邻兄弟选择器

HTML:

<h2>标题 1</h2>
<p>段落 1(紧跟在 h2 后,被选中)</p>
<p>段落 2(不被选中)</p>
<h2>标题 2</h2>
<p>段落 3(紧跟在 h2 后,被选中)</p>

CSS:

/* 选择紧跟在 h2 后的第一个 <p> 元素 */
h2 + p {
  margin-top: 5px;
}

通用兄弟选择器

HTML:

<h2>标题 1</h2>
<p>段落 1(被选中)</p>
<blockquote>引用</blockquote>
<p>段落 2(被选中)</p>
<h2>标题 2</h2>
<p>段落 3(被选中)</p>

CSS:

/* 选择 h2 之后的所有同级 <p> 元素 */
h2 ~ p {
  color: green;
}

2.3 属性选择器:[attr], [attr=value], [attr~=value], [attr|=value]

属性选择器语法作用关键要点
存在性选择器[attr]选择带有指定属性 attr 的元素(无论属性值是什么)。• 不关心属性的具体值,只关心属性是否存在。
精确值选择器[attr="value"]选择属性 attr 的值完全等于 "value" 的元素。• 区分大小写(除非使用 i 修饰符)。
单词匹配选择器[attr~="value"]选择属性 attr 的值包含单词 "value" 的元素(以空格分隔的单词列表)。• 常用于选择包含特定类名的元素,等价于 .primary
• value 必须是一个独立的单词(由空格界定)。
前缀匹配选择器`[attr=“value”]`选择属性 attr 的值等于 "value" 或以 "value-" 开头的元素。
子串匹配选择器[attr^="value"]^=:值以 "value" 开头。• 非常强大的动态选择能力。
^=, $=, *= 是现代 CSS 布局和交互中常用的技巧。
[attr$="value"]$=:值以 "value" 结尾。
[attr*="value"]*=:值包含 "value" 子串。

代码示例

存在性选择器

HTML:

<a href="https://example.com">外部链接</a>
<a href="#">内部锚点</a>
<img src="logo.png" alt="Logo">

CSS:

/* 选择所有带有 href 属性的 <a> 元素 */
a[href] {
  text-decoration: underline;
}

/* 选择所有带有 alt 属性的 <img> 元素 */
img[alt] {
  border: 1px solid gray;
}

精确值选择器

HTML:

<input type="text" name="username">
<input type="password" name="password">

CSS:

/* 选择 type="text" 的输入框 */
input[type="text"] {
  background-color: #f9f9f9;
}

/* 选择 name="password" 的输入框 */
input[name="password"] {
  font-family: monospace;
}

单词匹配选择器

HTML:

<div class="btn primary large">大号主要按钮</div>
<div class="btn secondary small">小号次要按钮</div>

CSS:

/* 选择 class 中包含 "primary" 这个词的元素 */
[class~="primary"] {
  background-color: blue;
  color: white;
}

子串匹配选择器

HTML:

<a href="https://external.com">外部链接</a>
<a href="/internal/page">内部链接</a>
<a href="mailto:contact@example.com">邮箱链接</a>

CSS:

/* 选择 href 以 "https://" 开头的链接 (外部链接) */
a[href^="https://"] {
  color: red;
}

/* 选择 href 以 ".pdf" 结尾的链接 */
a[href$=".pdf"] {
  background: url(icon-pdf.png) left center no-repeat;
}

/* 选择 href 包含 "example.com" 的链接 */
a[href*="example.com"] {
  font-weight: bold;
}

2.4 伪类选择器

结构性伪类

伪类作用关键要点
:first-child选择作为其父元素第一个子元素的元素。• 关注元素在其父容器内的位置。
:nth-* 系列功能强大,使用公式 (an + b) 计算。例如 :nth-child(2n) 选择所有偶数项,:nth-child(3n+1) 选择第 1, 4, 7… 项。
:only-child 表示该元素是其父元素的唯一子元素。
:empty 选择没有任何子元素(包括文本节点)的元素。
:last-child选择作为其父元素最后一个子元素的元素。
:nth-child(n)选择其父元素的第 n 个子元素(按所有子元素计数)。
:nth-of-type(n)选择其父元素的第 n 个同类型子元素(只计算指定类型的元素)。:nth-child:nth-of-type 的区别在于计数范围。nth-of-type 更精确,只针对特定标签类型。
:only-child选择其父元素的唯一子元素。
:empty选择没有子元素(包括文本)的元素。

状态伪类

伪类作用关键要点
:hover当用户将指针悬停在元素上时应用样式。• 最常用的交互效果之一。
• 对触摸设备支持有限(通常模拟为点击后短暂状态)。
:focus 对键盘导航至关重要,不应移除默认轮廓(可通过 outline: none 移除,但需提供替代焦点指示)。
:checked 常用于样式化选中的单选/复选框。
:focus当元素获得焦点时(如通过 Tab 键或点击)。
:active当元素被激活时(如鼠标按下但未释放)。
:visited选择用户已访问过的链接。• 出于隐私考虑,visited 链接的可设置样式非常有限(主要是颜色相关属性)。
:checked选择处于选中状态的 <input type="radio"><input type="checkbox">
:disabled / :enabled分别选择禁用或启用的表单元素。
:required / :optional分别选择有 required 属性或没有 required 属性的表单元素。
:valid / :invalid分别选择通过或未通过验证的表单元素。

链接伪类

伪类作用关键要点
:link选择未被访问过的链接。:link:visited:any-link 的子集。
• 伪类顺序很重要!推荐遵循 LVHA 顺序::link, :visited, :hover, :active,以确保预期的行为。如果顺序错误,某些样式可能被覆盖。
:visited选择用户已访问过的链接。(见上文状态伪类)

代码示例

结构性伪类

<ul>
  <li>项目 1(被选中)</li>
  <li>项目 2</li>
  <li>项目 3</li>
</ul>
li:first-child {
  font-weight: bold;
}

li:last-child {
  color: gray;
}

/* 选择列表中的奇数项 */
li:nth-child(odd) {
  background-color: #f0f0f0;
}

/* 选择列表中的偶数项 */
li:nth-child(even) {
  background-color: #e0e0e0;
}

/* 选择第 3 个元素 */
li:nth-child(3) {
  border-top: 2px solid black;
}

:nth-of-type 示例:

<article>
  <h2>章节标题</h2>
  <p>第一段</p>
  <p>第二段(被选中)</p>
  <h2>另一个标题</h2>
  <p>第三段</p>
</article>
/* 选择 article 内的第二个 <p> 元素 */
p:nth-of-type(2) {
  font-style: italic;
}

:only-child:empty 示例:

.single-item > *:only-child {
  text-align: center;
}

.placeholder:empty::before {
  content: "暂无内容";
  color: #aaa;
}

状态伪类

button:hover {
  background-color: #0056b3;
}

a:hover {
  text-decoration: underline;
}

input:focus {
  border-color: #007bff;
  outline: 2px solid #007bff;
}

button:active {
  transform: translateY(1px);
}

a:visited {
  color: purple;
}

input[type="checkbox"]:checked + label {
  color: green;
  font-weight: bold;
}

input:disabled {
  background-color: #eee;
  cursor: not-allowed;
}

input:required {
  border-left: 3px solid red;
}

input:valid {
  border-color: green;
}

input:invalid {
  border-color: red;
}

链接伪类

a:link {
  color: blue;
}

a:visited {
  color: purple;
}

a:hover {
  text-decoration: underline;
}

a:active {
  color: red;
}

2.5 伪元素选择器:::before, ::after, ::first-line, ::first-letter, ::selection

伪元素语法作用关键要点
::before::before在选定元素的内容之前插入生成的内容。• 必须配合 content 属性使用,否则不会显示。
• 默认是行内元素 (display: inline)。
• 常用于添加图标、装饰符号、清除浮动(::after { content: ""; display: table; clear: both; })。
• 单冒号 : 是 CSS2 的旧语法,双冒号 :: 是 CSS3 为区分伪类而引入的标准,推荐使用 ::
::after::after在选定元素的内容之后插入生成的内容。(同上)
::first-line::first-line选择块级元素的第一行文本。• 只能应用于块级容器内的文本。
• 可设置的属性有限(字体、颜色、背景、文本对齐等排版属性)。
::first-letter::first-letter选择块级元素的第一个字母(或标点符号)。• 常用于创建“首字下沉”(Drop Cap) 效果。
• 同样只能应用于块级容器内的文本。
• 如果第一个字符是标点(如引号),它也会被选中。
::selection::selection选择用户选中(高亮)的文本部分。• 是一个全局伪元素,但可以限定在特定元素内。
• 可设置 color, background-color, cursor, outline 等少数属性。
• 提升用户体验的小细节。

代码示例

::before

.quote::before {
  content: "\""; /* 插入引号 */
  font-size: 2em;
  color: #ccc;
}

HTML:

<p class="quote">这是一个引用段落。</p>

渲染效果: “这是一个引用段落。

::after

.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

.icon::after {
  content: " ➔"; /* 添加右箭头 */
  color: blue;
}

HTML:

<a href="#" class="icon">了解更多</a>

渲染效果: 了解更多 ➔

::first-line

p::first-line {
  font-weight: bold;
  color: #555;
}

HTML:

<p>这是一段很长的文字,它的第一行会被加粗并变色。当文本换行后,后续行不受此样式影响...</p>

::first-letter

p::first-letter {
  font-size: 3em;
  font-weight: bold;
  float: left;
  margin-right: 0.1em;
  color: red;
}

HTML:

<p>从前有一座山,山里有一座庙...</p>

渲染效果: 从前有一座山,山里有一座庙…

::selection

/* 修改选中文本的样式 */
::selection {
  background-color: orange;
  color: white;
}

/* 特定元素内的选中样式 */
p.special::selection {
  background-color: pink;
}

HTML:

<p>普通段落,选中时背景橙色。</p>
<p class="special">特殊段落,选中时背景粉色。</p>

2.6 选择器优先级 (Specificity):权重计算规则与 !important 的使用规范

权重计算规则

概念说明权重值计算示例
内联样式直接在 HTML 元素的 style 属性中定义的样式。1000<h1 style="color: red;">标题</h1> → 权重 = 1000
ID 选择器每个 #id 选择器增加 100 点权重。100#main-header → 权重 = 100
#sidebar ul li → 权重 = 100 (只有1个ID)
类选择器、属性选择器、伪类每个 .class, [attr], :hover 等增加 10 点权重。10.nav-menu → 权重 = 10
[type="text"] → 权重 = 10
:hover → 权重 = 10
ul.menu li.active:hover → 权重 = 10 + 10 + 10 = 30
元素选择器、伪元素每个 div, p, ::before 等增加 1 点权重。1div → 权重 = 1
p::first-line → 权重 = 1 + 1 = 2
ul li a → 权重 = 1 + 1 + 1 = 3
通配符、组合符、否定伪类 :not()不增加权重。:not(.class) 的权重取决于 :not() 内部的选择器。0* → 权重 = 0
div p → 权重 = 1 + 1 = 2 (空格不加分)
:not(.important) → 权重 = 10 (内部 .important 的权重)
!important最高优先级,会覆盖任何其他声明(包括内联样式)。∞ (无限)p { color: blue !important; } → 无论其他规则权重多高,只要匹配,文字就是蓝色。
例外:!important 在用户样式表中的权重低于作者样式表中的 !important

优先级比较规则

  1. 比较权重:将四个数值(ID, 类/属性/伪类, 元素/伪元素)分别比较。从左到右,哪个数值大,哪个选择器优先级就高。例如 100 (ID) > 013 (0个ID, 1个类, 3个元素)。

  2. 比较来源与重要性:如果权重相同,则比较:!important 声明 > 普通声明。然后比较来源:作者样式表 > 用户样式表 > 用户代理(浏览器默认)样式表。

  3. 比较声明顺序:如果以上都相同,则后出现的声明覆盖先出现的(层叠的体现)。

!important 使用规范

建议说明
何时使用• 覆盖第三方库或框架中难以修改的内联样式(临时方案)。
• 在开发调试时快速测试样式效果(记得移除)。
何时避免• 日常开发中应极力避免。
• 它破坏了 CSS 的自然层叠和特异性,使样式难以预测和维护。
• 大量使用 !important 会导致“!important 战争”,最终所有样式都需要 !important 才能生效,代码变得混乱不堪。
最佳实践• 通过提高选择器特异性来解决问题(如添加一个更具体的类),而不是使用 !important
• 如果必须使用,务必添加注释说明原因。

第 3 章:盒模型与尺寸计算

3.1 标准盒模型 (W3C Box Model) 解析

内容项说明
定义标准盒模型(W3C Box Model)是 CSS 中默认的盒模型,元素的 widthheight 仅指内容区域(content)的尺寸,不包括 paddingbordermargin
组成部分- Content:实际内容显示区域
- Padding:内边距,围绕 content 的透明区域
- Border:边框,围绕 padding 的线条
- Margin:外边距,元素与其他元素之间的空白区域
总尺寸计算公式- 总宽度 = width + 2×padding-left/right + 2×border-left/right + 2×margin-left/right
- 总高度 = height + 2×padding-top/bottom + 2×border-top/bottom + 2×margin-top/bottom

结构图示

+-------------------------------------------+
|               Margin (outer)              |
|   +-----------------------------------+   |
|   |           Border                  |   |
|   |   +---------------------------+   |   |
|   |   |        Padding            |   |   |
|   |   |   +-------------------+   |   |   |
|   |   |   |     Content       |   |   |   |
|   |   |   +-------------------+   |   |   |
|   |   +---------------------------+   |   |
|   +-----------------------------------+   |
+-------------------------------------------+

代码示例

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <title>标准盒模型示例</title>
  <style>
    .box {
      width: 200px;
      height: 100px;
      padding: 20px;
      border: 5px solid #000;
      margin: 10px;
      background-color: lightblue;
      box-sizing: content-box; /* 默认值,即标准模型 */
    }
  </style>
</head>
<body>
  <div class="box">这是一个标准盒模型的 div</div>
</body>
</html>

计算验证

  • 内容宽高:200px × 100px
  • 实际占用宽度:200 + 2×20 + 2×5 + 2×10 = 270px
  • 实际占用高度:100 + 2×20 + 2×5 + 2×10 = 170px

3.2 IE 盒模型与 box-sizing 属性

属性名描述适用场景
box-sizingcontent-box默认值,遵循 W3C 标准盒模型,width/height 仅作用于 content兼容旧布局
border-boxIE 盒模型逻辑,width/height 包括 content + padding + border现代布局、响应式设计常用

对比表格:相同设置下的差异

设置项.box1 { width: 200px; padding: 20px; border: 5px; }

box-sizing 值尺寸计算
content-box- content 宽度 = 200px
- 总宽度 = 200 + 40 + 10 = 250px
border-box- content 宽度自动压缩为 150px
- 总宽度 = 200px(固定)

⚠️ 注意margin 始终不计入 box-sizing 计算范围。

代码示例

/* 使用 border-box 统一重置所有元素 */
* {
  box-sizing: border-box;
}

.example {
  width: 200px;
  height: 100px;
  padding: 20px;
  border: 5px solid red;
  margin: 10px;
  background: yellow;
}

此时 .example 的总宽度仍为 200px,内部 content 自动调整为 200 - 2*(20+5) = 150px

推荐实践

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

这是现代 CSS Reset 或 Normalize 的常见做法,避免尺寸计算混乱。

3.3 深入理解 content、padding、border、margin

区域功能说明是否可设背景是否影响布局特殊性质
Content显示文本、图像等内容✅ 是(background-color/image)✅ 是可滚动(若 overflow 非 visible)
Padding内部留白,增强可读性✅ 是(继承父背景或独立设置)✅ 是不可为负值
Border边框装饰或分隔✅ 是✅ 是支持样式(solid/dashed等)、圆角(border-radius)
Margin外部间距,控制元素间距离❌ 否(透明)✅ 是可为负值,支持自动居中(auto)

属性语法速查表

属性单边写法简写规则(顺时针)
paddingpadding-top, padding-rightpadding: 10px; → 四边一致
padding: 10px 20px; → 上下=10, 左右=20
padding: 10px 20px 15px; → 上=10, 右=20, 下=15, 左=20
padding: 10px 20px 15px 25px; → 上右下左
margin同上规则同 padding
borderborder-width, border-style, border-colorborder: 2px solid red;

示例代码

.box {
  content: "伪元素内容"; /* 仅用于 ::before/after */
  padding: 10px 20px;        /* 上下10px,左右20px */
  border: 3px dashed green;  /* 宽度、样式、颜色 */
  margin: 20px auto;         /* 上下20px,左右自动居中 */
  background: #eee url("bg.jpg") no-repeat center;
}

📌 提示paddingborder 会影响点击热区;margin 不可点击。

3.4 计算元素的总宽度与总高度

参数符号是否受 box-sizing 影响
内容宽度W_c✅ 是(由 width 定义)
内边距总和P = 2×(left + right)
边框总和B = 2×(left + right)
外边距总和M = 2×(left + right)

尺寸计算对照表

box-sizing 类型实际宽度(含 margin)内容可用宽度
content-boxwidth + P + B + Mwidth
border-boxspecified width + Mspecified width - P - B

💡 示例:一个元素设置 width: 300px; padding: 10px; border: 5px; margin: 20px;

box-sizing内容宽度实际占用宽度(页面中)
content-box300px300 + 20 + 10 + 40 = 370px
border-box270px(自动压缩)300 + 40 = 340px

JavaScript 获取尺寸方法对比

方法返回值说明是否包含 margin
offsetWidthwidth + padding + border❌ 否
clientWidthwidth + padding❌ 否
getBoundingClientRect().width浮点型渲染后宽度❌ 否
getComputedStyle(elem).width字符串如 “300px”❌ 否(需手动加 margin)

要获取完整占位宽度,需手动相加:

// 注意:以下代码仅在浏览器环境中运行
// const elem = document.querySelector('.box');
// const style = getComputedStyle(elem);
// const totalWidth = 
//   elem.offsetWidth + 
//   parseFloat(style.marginLeft) + 
//   parseFloat(style.marginRight);
// console.log(totalWidth); // 包括 margin 的总宽度

3.5 外边距折叠 (Margin Collapse) 现象与处理

外边距折叠类型汇总表

类型发生条件折叠规则图示说明
相邻兄弟元素垂直排列的 block 元素,之间无 border/padding/inline content 隔开取两者 margin 的最大值(同向)或代数和(反向)A↓10px 与 B↑20px → 实际间距 20px
父子关系折叠父元素无 border/padding/block formatting context,子元素 margin-top/bottom 无阻挡子元素的 margin 会”穿透”到父元素外部导致父元素整体下移
空块级元素自身折叠元素无 border/padding/content,且上下 margin 存在上下 margin 合并为一个,取较大者<div style="margin:20px 0 30px;"></div> → 实际 margin: 30px

折叠规则详解(同方向)

margin-top Amargin-bottom B折叠后垂直间距
20px30px30px(取大)
-10px20px20px(正数优先)
-15px-25px-25px(更小)

⚠️ 注意:只有垂直方向的 margin 会折叠,水平方向不会!

解决方案对照表

问题类型解决方法原理
防止兄弟折叠使用 padding 或 border 替代部分 margin打破”纯 margin 相邻”条件
防止父子折叠给父元素添加 padding-top: 1pxborder-top: 1px solid transparent阻断 margin 传递路径
将父元素变成 BFC(Block Formatting Context)创建独立布局环境
例如:overflow: hidden/auto
使用伪元素 ::before { content: ""; display: table; }触发 BFC
统一控制布局使用 CSS Grid / Flexbox 布局这些容器默认不参与传统 margin 折叠

代码示例:防止父子 margin 折叠

<div class="parent">
  <div class="child">子元素</div>
</div>
.parent {
  background: #f0f0f0;
  /* 解决方案任选其一 */
  /* 方案1:加 border */
  /* border: 1px solid transparent; */
  
  /* 方案2:创建 BFC */
  overflow: hidden;
  
  /* 方案3:使用伪元素触发 BFC */
  /* &:before { content:""; display:table; } */
}

.child {
  margin-top: 30px;
  background: coral;
  height: 50px;
}

✅ 应用以上任一方案后,.childmargin-top 将只作用于内部,不再导致 .parent 整体下移。

第 4 章:文档流、定位与层叠

4.1 块级元素、行内元素、行内块元素 (display 属性)

显示类型典型元素是否换行可设宽高占据空间方式内容排列
block<div>, <p>, <h1>~<h6>, <ul>✅ 自动换行✅ 可设置独占一行,默认宽度为父容器 100%垂直堆叠
inline<span>, <a>, <strong>, <em>❌ 不换行❌ 宽高无效(由内容决定)仅占内容所需空间水平排列,忽略上下 margin
inline-block—(需手动设置)❌ 不换行✅ 可设置行内排列但可设宽高类似 inline,但支持 block 特性

特性对比表

特性blockinlineinline-block
换行显示
可设置 width/height
忽略 vertical-align✅(有效)
margin 上下生效⚠️ 不影响布局(但视觉存在)
padding 生效✅(但可能重叠)

💡 提示inline 元素的上下 margin 和 padding 不会推挤其他元素,但背景仍会渲染。

结构图示

[ Block Element 1 ] ← 占满整行
[ Block Element 2 ] ← 下一行开始

Inline: This is <span style="background:yellow">highlighted</span> text.
        ↑ 所有内容在同一行流动

Inline-block:
[Item1][Item2][Item3] ← 可设宽高,同行排列

代码示例

.box1 {
  display: block;
  width: 100px;
  height: 50px;
  background: red;
}

.box2 {
  display: inline;
  background: blue;
  padding: 10px;
}

.box3 {
  display: inline-block;
  width: 80px;
  height: 40px;
  background: green;
  margin: 5px;
}
<div class="box1">Block</div>
<span class="box2">Inline</span>
<span class="box3">In-B</span>
<span class="box3">In-B</span>

输出效果

  • .box1 单独一行,红色方块
  • .box2 蓝色背景,文字连排
  • 两个 .box3 并列显示,绿色小方块带间距

4.2 定位方案 (position 属性)

position 值含义是否脱离文档流定位参考点使用场景
static默认值,遵循正常文档流❌ 否无(不可用 top/right/bottom/left)常规布局
relative相对自身原始位置偏移❌ 否(仍占原位)自身原本位置微调位置、作为绝对定位的容器
absolute绝对定位✅ 是(脱离文档流)最近的已定位祖先元素(非 static);否则为初始包含块(通常是视口)弹窗、提示框、复杂层叠布局
fixed固定定位✅ 是(脱离文档流)浏览器视口(viewport)导航栏、回到顶部按钮
sticky粘性定位❌ 否(条件性固定)视口 + 滚动容器边界吸顶菜单、侧边栏锚定

定位行为说明表

类型文档流中占位?是否响应 scroll?是否创建层叠上下文?注意事项
static✅ 是N/A设置 top 等无效
relative✅ 是❌(除非 z-index ≠ auto)偏移后原位置保留空白
absolute❌ 否✅(若 z-index ≠ auto)需注意父级是否”已定位”
fixed❌ 否❌(相对于视口)在移动端可能表现异常(Safari)
sticky✅ 是(滚动前)✅(当”粘住”时)必须指定 top 或 bottom 才生效

代码示例

.container {
  position: relative;
  border: 2px solid #000;
  height: 300px;
  background: #f0f0f0;
}

.abs-box {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 100px;
  height: 100px;
  background: red;
}

.fix-btn {
  position: fixed;
  bottom: 20px;
  right: 20px;
  padding: 10px;
  background: black;
  color: white;
}

.sticky-header {
  position: sticky;
  top: 0;
  background: blue;
  color: white;
  padding: 10px;
  font-weight: bold;
}
<div class="container">
  <div class="abs-box">绝对定位</div>
</div>
<header class="sticky-header">吸顶标题</header>
<button class="fix-btn">回到顶部</button>

效果说明

  • .abs-box 相对于 .container 定位(因父级 relative)
  • .fix-btn 固定在右下角,滚动不消失
  • .sticky-header 滚动到顶部时”吸附”

4.3 top, right, bottom, left 偏移属性

属性适用 position 类型正值方向负值效果特殊规则
toprelative, absolute, fixed, sticky向下偏移向上移动对 absolute/fixed,距离参考点的距离
right同上向左偏移向右移动优先级高于 left(当两者都设时)
bottom同上向上偏移向下移动常用于底部对齐
left同上向右偏移向左移动默认基准为 0

偏移行为对照表

position设置 top: 50px 效果
static❌ 无效
relative元素从原位置向下移动 50px,原位置保留
absolute元素距其定位祖先顶部 50px 处定位
fixed元素距视口顶部 50px 处定位
sticky当滚动到距视口顶部 ≤50px 时,“粘住”在此位置

居中技巧示例

/* 水平居中(relative/absolute) */
.center-h {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}

/* 垂直居中 */
.center-v {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

/* 完全居中 */
.center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 200px;
  height: 100px;
}

📌 替代方法(现代布局)

.modern-center {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  margin: auto;
  width: 200px;
  height: 100px;
}

4.4 z-index 与层叠上下文 (Stacking Context)

属性作用取值范围是否创建层叠上下文?
z-index控制元素在 Z 轴上的堆叠顺序auto(默认)、整数(正/负)✅ 仅当 position 非 static 且值不为 auto 时

层叠顺序(从后到前)

  1. 根元素的背景和边框
  2. position: static/relative 的 block 元素(按 HTML 顺序)
  3. position: static/relative 的 inline 元素
  4. 浮动元素(内容在前,浮动框在后)
  5. position: absolute/fixed 元素(按 z-index 排序)

🔁 在同一层叠上下文中,z-index 越大越靠前。

创建新层叠上下文的条件(任一满足即成立)

条件示例 CSS
position + z-index(非 auto)position: relative; z-index: 1;
opacity < 1opacity: 0.9;
transform 非 nonetransform: scale(1);
filter 非 nonefilter: blur(1px);
will-change 指定相关属性will-change: transform;
isolation: isolateisolation: isolate;
mix-blend-mode 非 normalmix-blend-mode: multiply;

层叠陷阱示例

<div class="parent-a" style="position:relative; z-index:10;">
  <div class="child-a" style="position:absolute; z-index:100;">A</div>
</div>
<div class="parent-b" style="position:relative; z-index:20;">
  <div class="child-b" style="position:absolute; z-index:1;">B</div>
</div>

❌ 尽管 .child-az-index=100 > .child-b=1,但由于 .parent-bz-index=20 > 10,整个 B 分支都在 A 上方!

解决方案:统一管理 z-index,避免深层嵌套冲突。

4.5 浮动 (float) 原理、历史用途与清除浮动方法

float 值行为描述是否脱离文档流是否影响后续元素
left向左浮动,允许文本环绕右侧✅ 是✅ 是(后续 inline 内容会环绕)
right向右浮动✅ 是✅ 是
none默认值,不浮动❌ 否❌ 否

浮动特性表

特性说明
脱离文档流后续 block 元素可能”上移”填充空间
创建块格式化上下文 (BFC)浮动元素自动成为 BFC,防止外边距折叠
高度塌陷问题父容器无法感知浮动子元素的高度,导致高度为 0

清除浮动方法对比

方法实现方式原理优缺点
空 div 法<div style="clear:both;"></div>插入不可见元素阻止环绕简单但语义差,增加冗余标签
overflow 触发 BFC.parent { overflow: hidden; }创建 BFC 包含浮动简洁,但可能裁剪内容或影响滚动
after 伪元素法.clearfix::after { content:""; display:block; clear:both; }动态添加清除符推荐做法,无额外标签
Flex/Grid 替代.parent { display: flex; }现代布局天然解决浮动问题更优方案,无需清除

代码示例:clearfix 技巧

.clearfix::before,
.clearfix::after {
  content: "";
  display: table;
}

.clearfix::after {
  clear: both;
}

/* IE6/7 兼容(可选) */
.clearfix {
  *zoom: 1;
}
<div class="parent clearfix">
  <div style="float:left; width:100px; height:100px; background:red;"></div>
  <div style="float:left; width:100px; height:100px; background:blue;"></div>
</div>
<!-- 父元素现在能正确包裹两个浮动子元素 -->

浮动的历史与现状

  • ✅ 曾用于:多列布局、导航菜单、图片环绕文字
  • ❌ 现已被取代:Flexbox 和 Grid 提供更强大、可控的布局能力
  • ⚠️ 仍适用场景:简单的文本环绕图像(如文章配图)

第 5 章:Flexbox 弹性布局

5.1 Flexbox 核心概念:容器、项目、主轴、交叉轴

概念定义说明
Flex 容器 (Flex Container)应用了 display: flexdisplay: inline-flex 的父元素所有直接子元素自动成为”flex 项目”
Flex 项目 (Flex Items)Flex 容器的直接子元素受容器的 flex 属性控制排列方式
主轴 (Main Axis)主要排列方向轴flex-direction 决定,默认为水平从左到右
交叉轴 (Cross Axis)垂直于主轴的方向自动确定,用于对齐垂直方向

主轴与交叉轴方向对照表

flex-direction 值主轴方向交叉轴方向图示(→=主轴,↓=交叉轴)
row(默认)← → 水平(左到右)↑ ↓ 垂直(上到下)[Item1][Item2][Item3]
row-reverse→ ← 水平(右到左)↑ ↓ 垂直(上到下)[Item3][Item2][Item1]
column↑ ↓ 垂直(上到下)← → 水平(左到右)Item1
Item2
Item3 ←
column-reverse↓ ↑ 垂直(下到上)← → 水平(左到右)Item3
Item2
Item1 ←

📌 提示:主轴决定排列顺序,交叉轴决定对齐方式。

结构图示

flex-direction: row;

+-----------------------------+
| [Item 1] [Item 2] [Item 3]  |
+-----------------------------+
←---------- Main Axis --------→
            ↓ ↓ ↓
       Cross Axis (vertical)

flex-direction: column;

+---------+
| Item 1  | ← Main Axis (down)
+---------+
| Item 2  |
+---------+
| Item 3  |
+---------+
←-- Cross Axis (horizontal) --→

代码示例

.container {
  display: flex;           /* 创建 flex 容器 */
  flex-direction: row;     /* 主轴为水平方向 */
  height: 200px;           /* 为 column 提供交叉轴空间 */
  border: 2px solid #333;
}

.item {
  width: 100px;
  height: 80px;
  background: lightblue;
  margin: 5px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

效果:三个项目水平排列,主轴为水平,交叉轴为垂直。

5.2 容器属性详解:display, flex-direction, flex-wrap, justify-content, align-items, align-content, gap

属性值示例功能说明适用场景
displayflex, inline-flex启用 Flex 布局必须设置
flex-directionrow, row-reverse, column, column-reverse设置主轴方向控制排列方向
flex-wrapnowrap(默认), wrap, wrap-reverse是否换行多行布局、响应式卡片
justify-contentflex-start, center, flex-end, space-between, space-around, space-evenly主轴对齐方式水平/垂直居中、间距分配
align-itemsstretch(默认), flex-start, center, flex-end, baseline交叉轴对齐方式垂直居中、顶部对齐
align-contentstretch, flex-start, center, space-between多行时行之间的对齐仅当 flex-wrap: wrap 时有效
gap10px, 1em, 1rem项目间间距(主轴+交叉轴)替代 margin,避免外边距折叠

justify-content 详细对照表

描述图示([ ] = 项目)
flex-start靠近起点[1][2][3]
center居中 [1][2][3]
flex-end靠近终点 [1][2][3]
space-between两端对齐,中间间距相等[1] [2] [3]
space-around每个项目周围空间相等[1] [2] [3]
space-evenly所有间距完全相等[1] [2] [3]

align-items 详细对照表

描述适用情况
stretch拉伸填满容器(无固定高度时)默认行为
flex-start顶部对齐所有项目顶部对齐
center居中对齐垂直居中
flex-end底部对齐所有项目底部对齐
baseline文本基线对齐多行文字对齐

代码示例:完整容器布局

.flex-container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  align-content: space-around;
  gap: 16px;
  height: 400px;
  border: 2px dashed #666;
}
<div class="flex-container">
  <div style="height:60px;background:red;">A</div>
  <div style="height:80px;background:blue;">B</div>
  <div style="height:40px;background:green;">C</div>
  <div style="height:100px;background:orange;">D</div>
</div>

效果

  • 项目主轴间距相等(space-between)
  • 交叉轴居中对齐(align-items)
  • 若换行,行间间距分配(align-content)

5.3 项目属性详解:order, flex-grow, flex-shrink, flex-basis, flex, align-self

属性作用取值说明示例
order控制项目显示顺序整数(默认 0),数值越小越靠前order: -1; → 最前
flex-grow放大比例(剩余空间分配)数字(默认 0),0=不放大flex-grow: 1; → 平分剩余空间
flex-shrink缩小比例(空间不足时)数字(默认 1),0=不缩小flex-shrink: 0; → 禁止压缩
flex-basis项目主轴初始尺寸长度值(如 100px, auto)flex-basis: 200px; → 初始宽 200px
flex缩写:flex-grow flex-shrink flex-basis推荐写法:flex: 1flex: 0 1 autoflex: 1; = 1 1 0(注意:现代浏览器中 flex: 1 等价于 1 1 0%
align-self单个项目交叉轴对齐方式覆盖 align-items,值同 align-itemsalign-self: flex-end;

flex 缩写常见写法对照表

写法等效展开含义
flex: 0 1 autogrow=0, shrink=1, basis=auto默认行为,大小由内容决定,可压缩
flex: 11 1 0%占据可用空间(推荐用于”填满”)
flex: 0 0 200pxgrow=0, shrink=0, basis=200px固定尺寸,不放大不缩小
flex: 22 2 0%放大权重为 2,优先获得更多空间

代码示例

.container {
  display: flex;
  width: 600px;
  height: 100px;
  border: 1px solid #000;
}

.item-a {
  flex: 2;                /* 占比 2 */
  background: red;
}

.item-b {
  flex: 1;                /* 占比 1 */
  background: blue;
}

.item-c {
  flex: 0 0 100px;        /* 固定 100px */
  background: green;
}

.item-d {
  order: -1;              /* 最先显示 */
  background: orange;
  width: 50px;
}

.item-e {
  align-self: flex-end;   /* 底部对齐 */
  background: purple;
  height: 60px;
}
<div class="container">
  <div class="item-a">A (flex:2)</div>
  <div class="item-b">B (flex:1)</div>
  <div class="item-c">C (fixed)</div>
  <div class="item-d">D (order:-1)</div>
  <div class="item-e">E (align-self)</div>
</div>

效果

  • .item-d 显示在最左侧(order 最小)
  • A:B 宽度比约为 2:1
  • C 固定 100px
  • E 底部对齐

5.4 Flexbox 实战案例:居中对齐、导航栏、卡片布局、圣杯布局

案例 1:完美居中对齐

.center {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh; /* 或任意容器高度 */
}
<div class="center">
  <div>居中的内容</div>
</div>

✅ 支持文字、图片、固定尺寸元素的居中。

案例 2:水平导航栏

.nav {
  display: flex;
  justify-content: space-between; /* 或 center */
  list-style: none;
  padding: 0;
  background: #333;
}

.nav-item {
  padding: 1rem 1.5rem;
  color: white;
  text-decoration: none;
}

.nav-item:hover {
  background: #555;
}
<ul class="nav">
  <li><a href="#" class="nav-item">首页</a></li>
  <li><a href="#" class="nav-item">产品</a></li>
  <li><a href="#" class="nav-item">关于</a></li>
</ul>

✅ 响应式,无需浮动。

案例 3:卡片布局(响应式)

.card-container {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 1rem;
}

.card {
  flex: 1 1 200px; /* 最小 200px,可伸缩 */
  border: 1px solid #ddd;
  border-radius: 8px;
  overflow: hidden;
  background: white;
}
<div class="card-container">
  <div class="card">卡片 1</div>
  <div class="card">卡片 2</div>
  <div class="card">卡片 3</div>
  <div class="card">卡片 4</div>
</div>

✅ 在小屏幕上自动换行,每行尽可能放满。

.holy-grail {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.header, .footer {
  flex: 0 0 auto; /* 不伸缩,保持原高 */
  background: #333;
  color: white;
  text-align: center;
  padding: 1rem;
}

.main {
  flex: 1; /* 填满剩余空间 */
  display: flex;
  gap: 1rem;
  padding: 1rem;
}

.sidebar {
  flex: 0 0 200px;
  background: #f0f0f0;
}

.content {
  flex: 1;
  background: #fff;
}
<div class="holy-grail">
  <header class="header">Header</header>
  <main class="main">
    <aside class="sidebar">Sidebar</aside>
    <section class="content">Main Content</section>
  </main>
  <footer class="footer">Footer</footer>
</div>

特点

  • 头尾固定高度
  • 中间主体填满剩余空间
  • 侧边栏固定宽度,内容区自适应

核心口诀

  • 容器控方向(flex-direction
  • 主轴看 justify-content
  • 交叉轴看 align-items
  • 项目用 flex 调比例

第 6 章:Grid 网格布局

6.1 Grid 布局核心概念:网格容器、网格项目、网格线、网格轨道、网格区域

概念定义说明
网格容器 (Grid Container)设置了 display: gridinline-grid 的父元素所有直接子元素自动成为”网格项目”
网格项目 (Grid Items)网格容器的直接子元素可跨越多个单元格
网格线 (Grid Lines)划分行和列的线(从 1 开始编号)可用于定位项目起止位置
网格轨道 (Grid Track)相邻两条网格线之间的空间(即行或列)对应 grid-template-rows/columns 中定义的一行/一列
网格单元格 (Grid Cell)单个行与列交叉形成的最小单位类似表格中的一个”格子”
网格区域 (Grid Area)由四条网格线围成的矩形区域(可跨多行多列)可命名并用于布局

结构图示

网格线编号(列):
     1     2       3        4
     |     |       |        |
     v     v       v        v
   +-----+-------+--------+
 1 |  A  |   B   |   C    | ← 第1行(轨道)
   +-----+-------+--------+
 2 |     |       |        |
   |  D  |   E   |   F    | ← 第2行
   |     |       |        |
   +-----+-------+--------+
 3 |  G  |   H   |   I    | ← 第3行
   +-----+-------+--------+

A 占据:列1→2,行1→2 E 是一个单元格:列2→3,行2→3 一个”网格区域”可以是 A + D + G(第1列全部)

📌 提示:网格线支持负数编号(如 -1 表示最右边/底部的线)。

6.2 容器属性详解:display, grid-template-columns/rows, grid-template-areas, gap, justify-items, align-items, justify-content, align-content

属性功能说明示例值适用场景
display启用 Grid 布局grid, inline-grid必须设置
grid-template-columns定义列宽(每条轨道)100px 1fr 2fr, repeat(3, 1fr)控制列分布
grid-template-rows定义行高auto 100px minmax(50px, auto)控制行高度
grid-template-areas使用名称定义区域布局"header header"<br />"nav main"<br />"footer footer"可视化布局设计
gap / row-gap, column-gap行/列间距10px, 1rem替代 margin,避免外边距折叠
justify-items项目在单元格内的水平对齐start, center, end, stretch统一控制项目水平对齐方式
align-items项目在单元格内的垂直对齐start, center, end, stretch(默认)统一控制垂直对齐
justify-content整个网格在容器中的水平对齐(当总尺寸小于容器)start, center, space-between, space-around多余空间分配
align-content整个网格在容器中的垂直对齐同上垂直方向多余空间分配

grid-template-columns/rows 示例对照表

写法含义
100px 200px 1fr三列:第一列100px,第二列200px,第三列占剩余空间
repeat(3, 1fr)三列等分剩余空间
minmax(100px, 1fr)最小100px,最大占满可用空间
2fr 1fr两列,比例为 2:1
fit-content(200px)内容宽度最多不超过200px,否则自适应

代码示例:使用 grid-template-areas 布局

.container {
  display: grid;
  grid-template-areas:
    "header header"
    "nav    main"
    "footer footer";
  grid-template-columns: 200px 1fr;
  grid-template-rows: 80px 1fr 60px;
  gap: 10px;
  min-height: 100vh;
}

.header { grid-area: header; background: #333; color: white; }
.nav   { grid-area: nav;     background: #f0f0f0; }
.main  { grid-area: main;    background: white; }
.footer{ grid-area: footer;  background: #333; color: white; }
<div class="container">
  <header class="header">Header</header>
  <nav class="nav">Nav</nav>
  <main class="main">Main Content</main>
  <footer class="footer">Footer</footer>
</div>

效果:清晰的二维布局,语义化强,易于维护。

6.3 项目属性详解:grid-column/row-start/end, grid-area, justify-self, align-self

属性作用示例说明
grid-column-start项目从哪条列线开始grid-column-start: 2;支持数字或名称
grid-column-end项目到哪条列线结束grid-column-end: 4;可用 span 2 表示跨越2列
grid-row-start项目从哪条行线开始grid-row-start: 1;
grid-row-end项目到哪条行线结束grid-row-end: span 2;
grid-column简写:start / endgrid-column: 2 / 4;推荐写法
grid-row简写:start / endgrid-row: 1 / span 2;
grid-area四合一简写:row-start / col-start / row-end / col-endgrid-area: 1 / 2 / 3 / 4;也可用于命名区域
justify-self单个项目在单元格内的水平对齐center, start, end, stretch覆盖 justify-items
align-self单个项目在单元格内的垂直对齐center, start, end, stretch覆盖 align-items

grid-area 缩写示例

.item {
  grid-area: 2 / 1 / 4 / 3;
  /* 等价于:
     grid-row-start: 2;
     grid-column-start: 1;
     grid-row-end: 4;
     grid-column-end: 3;
  */
}

即:从第2行开始,第1列开始,到第4行结束,第3列结束 → 跨越2行2列。

代码示例:项目跨越与对齐

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 200px;
  gap: 10px;
}

.item-a {
  grid-column: 1 / 3;    /* 横跨前两列 */
  background: red;
}

.item-b {
  grid-row: 1 / 3;       /* 纵跨两行 */
  justify-self: center;  /* 水平居中 */
  align-self: end;       /* 底部对齐 */
  background: blue;
}
<div class="container">
  <div class="item-a">A (col 1-2)</div>
  <div class="item-b">B (row 1-2)</div>
  <div>C</div>
</div>

效果

  • A 横跨第1-2列,第1行
  • B 纵跨第1-2行,第3列,且在单元格内右下角对齐
  • C 自动填入剩余位置

6.4 网格函数:fr 单位、minmax(), repeat(), fit-content()

函数/单位语法功能说明示例
fr1fr, 2fr分数单位,表示可用空间的份数1fr 2fr → 比例 1:2
minmax(min, max)minmax(100px, 1fr)定义尺寸范围最小100px,最大占满
repeat(n, track-list)repeat(3, 1fr)重复生成轨道三列等分
repeat(auto-fill, 100px)自动填充尽可能多的100px列响应式卡片
repeat(auto-fit, minmax(100px, 1fr))自动适配,每列至少100px,可伸缩更智能的响应式
fit-content(length)fit-content(200px)内容宽度最多不超过指定长度类似 max-width 行为

响应式网格技巧对比

写法行为描述
repeat(3, 1fr)固定3列,等分宽度
repeat(auto-fill, 100px)容器够宽就一直加100px列,不够就不显示
repeat(auto-fit, 100px)同上,但会拉伸填满剩余空间
repeat(auto-fit, minmax(150px, 1fr))每列至少150px,超出则等分剩余空间(推荐)

代码示例:响应式卡片网格

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.5rem;
  padding: 1rem;
}

.card {
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 1rem;
  background: white;
}
<div class="card-grid">
  <div class="card">Card 1</div>
  <div class="card">Card 2</div>
  <div class="card">Card 3</div>
  <!-- 可添加更多卡片 -->
</div>

效果

  • 大屏:每行尽可能放满 ≥250px 的卡片
  • 小屏:自动变为单列
  • 无媒体查询,纯 CSS 实现响应式

6.5 Grid 实战案例:复杂网页布局、仪表盘、杂志式排版

案例 1:复杂网页布局(带侧边栏和页脚)

.layout {
  display: grid;
  grid-template-areas:
    "sidebar header"
    "sidebar main"
    "sidebar footer";
  grid-template-columns: 200px 1fr;
  grid-template-rows: 80px 1fr 60px;
  gap: 10px;
  min-height: 100vh;
}

.sidebar { grid-area: sidebar; background: #333; color: white; }
.header  { grid-area: header;  background: #007acc; color: white; }
.main    { grid-area: main;    background: #f9f9f9; padding: 20px; }
.footer  { grid-area: footer;  background: #666; color: white; }

优势:无需浮动或定位,语义清晰。

案例 2:仪表盘布局(不规则区域)

.dashboard {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  grid-template-rows: 100px 200px 150px;
  gap: 10px;
  height: 100vh;
}

.big-chart   { grid-area: 1 / 1 / 3 / 4; background: #ffcc00; } /* 横跨三列两行 */
.stats-left  { grid-area: 3 / 1 / 4 / 2; background: #66bb6a; }
.stats-right { grid-area: 3 / 2 / 4 / 4; background: #42a5f5; }
.sidebar     { grid-area: 1 / 4 / 4 / 5; background: #9c27b0; color: white; }
<div class="dashboard">
  <div class="big-chart">主图表</div>
  <div class="stats-left">统计A</div>
  <div class="stats-right">统计B</div>
  <div class="sidebar">控制面板</div>
</div>

✅ 实现不规则、跨区域的复杂布局。

案例 3:杂志式排版(图文混排)

.magazine {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto;
  gap: 15px;
  padding: 20px;
}

.article-main {
  grid-column: 1 / 5; /* 全宽标题 */
  font-size: 2em;
  font-weight: bold;
}

.img-large {
  grid-column: 1 / 3;
  grid-row: span 2; /* 跨两行 */
  background: url('large.jpg') center/cover;
}

.text-block {
  grid-column: 3 / 5;
  background: #f8f8f8;
  padding: 10px;
}

✅ 模拟传统印刷品的灵活排版效果。

第 7 章:响应式设计与视口管理

7.1 移动优先 (Mobile-First) 设计理念

概念定义说明
移动优先 (Mobile-First)从最小屏幕开始设计,逐步增强大屏体验使用 min-width 媒体查询向上适配
桌面优先 (Desktop-First)从最大屏幕开始设计,向下调整小屏样式使用 max-width 向下覆盖
渐进增强 (Progressive Enhancement)基础功能在所有设备可用,高级功能按需添加移动优先的实现策略

移动优先 vs 桌面优先 对比表

特性移动优先桌面优先
媒体查询方向@media (min-width: ...)@media (max-width: ...)
默认样式针对手机(窄屏)针对桌面(宽屏)
性能优化✅ 更好(小屏加载轻量 CSS)❌ 可能加载冗余样式
维护性✅ 推荐现代开发方式⚠️ 易产生样式覆盖混乱
用户覆盖所有设备都能访问基础内容小屏可能被忽略

开发流程图示

[ 编写基础移动端样式 ]

[ 添加 min-width 断点 ]

[ 为平板/桌面增加布局增强 ]

[ 最终:所有设备良好体验 ]

💡 核心原则:先保证小屏可用,再为大屏”加料”。

代码示例:移动优先媒体查询

/* 基础样式(手机) */
.container {
  padding: 10px;
  font-size: 14px;
}

/* 平板及以上 */
@media (min-width: 768px) {
  .container {
    padding: 20px;
    font-size: 16px;
  }
}

/* 桌面及以上 */
@media (min-width: 1024px) {
  .container {
    max-width: 1200px;
    margin: 0 auto;
  }
}

优势:小屏设备无需下载和解析大屏专用样式。

7.2 视口元标签(<meta name="viewport">

属性取值示例功能说明是否必需
widthdevice-width, 320, 414设置视口宽度✅ 推荐设置为 device-width
initial-scale1.0, 0.5初始缩放比例✅ 推荐设为 1.0
user-scalableyes, no是否允许用户缩放⚠️ 设 no 不利于无障碍访问
maximum-scale / minimum-scale1.0, 2.0限制缩放范围可选

常见组合写法

场景<meta> 标签写法
标准响应式网页<meta name="viewport" content="width=device-width, initial-scale=1">
禁止缩放(不推荐)<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
固定宽度(如H5游戏)<meta name="viewport" content="width=375, initial-scale=1">

📌 提示

  • device-width 表示设备的逻辑像素宽度(如 iPhone 14 Pro Max 为 430px)
  • 缺少该标签时,移动浏览器会模拟桌面宽度(通常 980px),导致页面被缩小显示

代码示例

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>响应式页面</title>
  <style>
    body { margin: 0; font-size: 16px; }
    .box {
      width: 100%;
      height: 200px;
      background: #007acc;
      color: white;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  </style>
</head>
<body>
  <div class="box">全宽蓝色块</div>
</body>
</html>

效果.box 在手机上正确占据 100% 屏幕宽度。

7.3 媒体查询(@media)语法与常用特性 (width, height, orientation, resolution)

语法结构示例说明
@media media-type and (media-feature) { ... }@media screen and (min-width: 768px) { ... }标准写法
多条件 and(min-width: 768px) and (max-width: 1023px)同时满足
多条件 ,(或)(orientation: portrait), (hover: hover)满足任一
not 否定not all and (color)取反结果

常用媒体特性对照表

特性取值示例用途
width768px, min-width, max-width响应式布局主要依据
height600px控制垂直空间(如全屏 banner)
orientationportrait, landscape区分竖屏/横屏
resolution2dppx, 192dpi高清屏适配(@2x 图)
hoverhover, none判断是否支持悬停(触摸屏为 none)
prefers-color-schemedark, light深色模式检测
prefers-reduced-motionreduce动画偏好(无障碍)

代码示例:多条件媒体查询

/* 横屏手机 */
@media (max-width: 767px) and (orientation: landscape) {
  .hero-text { font-size: 18px; }
}

/* 平板竖屏 */
@media (min-width: 768px) and (max-width: 1023px) and (orientation: portrait) {
  .grid { grid-template-columns: repeat(2, 1fr); }
}

/* 高分辨率屏幕 */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .logo {
    background-image: url('logo@2x.png');
    background-size: 100px 50px;
  }
}

/* 支持悬停的设备 */
@media (hover: hover) and (pointer: fine) {
  .nav-item:hover { background: #eee; }
}

/* 深色模式 */
@media (prefers-color-scheme: dark) {
  body { background: #121212; color: #fff; }
}

✅ 实现真正的”情境感知”式设计。

7.4 断点 (Breakpoints) 的设定策略

策略说明推荐做法
内容驱动断点当内容在特定宽度下出现换行、挤压等问题时添加断点✅ 推荐
设备参考断点基于主流设备尺寸设置(iPhone, iPad, etc.)可作为起点,但需验证
预设断点系统使用框架提供的断点(如 Bootstrap 的 sm/md/lg/xl)适合快速开发

常见断点参考值(单位:px)

断点名称min-width对应设备
xs (超小)0手机(竖屏)
sm (小)576px小屏手机横屏 / 超小平板
md (中)768px平板(竖屏)
lg (大)992px平板(横屏) / 小桌面
xl (超大)1200px桌面
xxl1400px大桌面

📌 建议使用 Sass 变量或 CSS 自定义属性管理断点

:root {
  --breakpoint-sm: 576px;
  --breakpoint-md: 768px;
  --breakpoint-lg: 992px;
}

/* 使用 */
@media (min-width: var(--breakpoint-md)) {
  /* 中屏以上样式 */
}

断点设计原则

  • ✅ 从窄到宽:使用 min-width 逐步增强
  • ✅ 避免过多断点:3~5 个足够
  • ✅ 测试真实内容:不要只看骨架
  • ❌ 不要为每台设备设断点:响应的是”宽度”而非”设备”

7.5 相对单位深度解析:em, rem, vw, vh, %, ch, ex

单位基准说明适用场景
%父元素对应尺寸高度 % 需父元素有明确高度宽度、弹性布局
em继承字体大小(或自身)文字相关组件内常用font-size, padding 在文字组件中
rem根元素字体大小(通常是 <html>推荐用于全局布局边距、容器尺寸、响应式字体
vw视口宽度的 1%1vw = 1% of viewport width全屏元素、响应式字体
vh视口高度的 1%注意移动端地址栏影响全高布局(需处理兼容性)
ch字符 “0” 的宽度等宽字体中特别准确代码块、输入框宽度
ex小写字母 “x” 的高度字体相关度量特殊排版需求(较少用)

单位使用建议表

场景推荐单位示例
字体大小remfont-size: 1.2rem;
容器宽度%, rem, vwwidth: 90%;max-width: 80rem;
间距(margin/padding)remmargin: 1rem 0;
响应式字体clamp() + vwfont-size: clamp(1rem, 2.5vw, 2rem);
全屏背景100vw × 100vhwidth: 100vw; height: 100vh;
输入框字符限制宽度chinput[type="text"] { width: 20ch; }

代码示例:响应式字体

h1 {
  /* 最小 1.5rem, 最大 3rem, 在视口中动态变化 */
  font-size: clamp(1.5rem, 4vw, 3rem);
}

.sidebar {
  width: 80%;           /* 相对于父容器 */
  max-width: 20rem;     /* rem 保证不会过大 */
}

.hero-section {
  height: 100vh;        /* 全高 */
  padding: 10vh 5vw;    /* 边距随视口变化 */
}

✅ 实现真正流体的响应式效果。

7.6 流体布局与弹性设计原则

原则说明实现方式
使用相对单位避免固定像素值(px)用 rem, %, vw 替代 px
弹性容器容器能自动调整子元素排列Flexbox、Grid、display: inline-block
最大最小约束防止过度拉伸或压缩min-width, max-width, min-height
内容自适应图片、视频等媒体可缩放img { max-width: 100%; height: auto; }
断点微调在关键宽度点优化布局@media 调整 flex-direction, grid-template

流体布局示例:卡片网格

.card-container {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.card {
  flex: 1 1 calc(33.333% - 1rem); /* 三列,减去gap */
  min-width: 250px;                /* 最小宽度 */
  background: white;
  border-radius: 8px;
  overflow: hidden;
}

.card img {
  width: 100%;
  height: auto;
}

效果

  • 大屏:每行最多3张卡
  • 中屏:自动变为2列
  • 小屏:单列堆叠
  • 无媒体查询,纯流体实现

弹性设计检查清单

  • ✅ 所有尺寸使用相对单位(rem/%/vw)
  • ✅ 图片设置 max-width: 100%
  • ✅ 容器使用 Flexbox 或 Grid
  • ✅ 关键元素设置 min-width/max-width
  • ✅ 在不同设备宽度下测试布局流畅性

第 8 章:视觉样式与装饰效果

8.1 颜色系统:十六进制、RGB/RGBA、HSL/HSLA、颜色关键字

颜色格式示例说明适用场景
十六进制 (Hex)#ff0000, #f00前缀 #,6位或3位表示 RGB最常用,简洁
RGBrgb(255, 0, 0)红绿蓝三原色,0–255精确控制色彩
RGBArgba(255, 0, 0, 0.5)RGB + Alpha(透明度 0–1)半透明背景、遮罩
HSLhsl(0, 100%, 50%)色相(H)、饱和度(S)、亮度(L)更直观的颜色调整
HSLAhsla(0, 100%, 50%, 0.3)HSL + Alpha半透明且易调色
颜色关键字red, blue, transparent预定义名称(共147个)快速原型、语义化

📌 提示

  • transparent 等价于 rgba(0,0,0,0)
  • HSL 更适合通过 JS 动态调整颜色(如”更亮”、“更饱和”)

HSL 参数说明

参数取值范围含义
H (Hue)0–360色相(红=0,绿=120,蓝=240)
S (Saturation)0%–100%饱和度(灰→鲜艳)
L (Lightness)0%–100%亮度(黑→白)

代码示例

.example {
  color: #f00;                    /* 红 */
  background-color: rgba(0,0,255,0.3); /* 半透蓝 */
  border-color: hsl(120, 100%, 25%);   /* 深绿色 */
  box-shadow: 0 0 10px hsla(0, 100%, 50%, 0.5); /* 红色半透阴影 */
}

推荐使用 HSLA 进行动态主题切换。

8.2 背景 (background) 属性:图像、重复、位置、大小 (cover, contain)、多重背景、background-origin/clip

属性功能示例
background-color背景色#eee
background-image背景图url(bg.jpg)
background-repeat重复方式no-repeat, repeat-x
background-position图片位置center, 10px 20px, top right
background-size图片尺寸cover, contain, 100% 200px
background-attachment滚动行为scroll, fixed(视差)
background-origin定位参考框padding-box, border-box, content-box
background-clip裁剪区域同上,控制背景绘制范围
background(简写)组合写法推荐顺序见下方

background-size 对照表

行为描述
auto保持原始尺寸
cover缩放图片以完全覆盖容器(可能裁剪)
contain缩放图片使其完整显示(留空白)
100% 100%拉伸填满(可能变形)
200px auto宽200px,高自动等比

多重背景语法(从上到下堆叠)

.multi-bg {
  background-image: 
    url(layer1.png),  /* 最上层 */
    url(layer2.png),
    linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5));
  background-position: 
    center,
    top left,
    center;
  background-repeat: no-repeat, repeat, no-repeat;
  background-size: cover, auto, cover;
}

实现图像+渐变叠加效果。

background-origin vs background-clip

属性控制什么?默认值
background-originposition 和 size 的参考点padding-box
background-clip背景(包括颜色和图像)的绘制区域border-box
.example {
  padding: 20px;
  border: 10px dashed red;
  background: url(logo.png) no-repeat;
  background-origin: content-box;  /* 图片从内容区开始定位 */
  background-clip: content-box;    /* 背景只在内容区显示 */
}

效果:背景图不覆盖 padding 和 border 区域。

8.3 边框 (border):border-radius (圆角), border-image

属性功能示例
border-width边框宽度2px
border-style边框样式solid, dashed, double
border-color边框颜色#333
border-radius圆角半径10px, 50%(圆形)
border-image-source边框图像源url(border.png)
border-image-slice切片方式30 fill(保留中间)
border-image-width图像边框宽度10px, 20%
border-image-outset外扩距离5px
border-image-repeat平铺方式stretch, repeat, round
border-image(简写)source slice width outset repeaturl() 30 round

border-radius 高级用法

/* 四角统一 */
border-radius: 10px;

/* 左上右下 */
border-radius: 10px 20px;

/* 左上 右上 右下 左下 */
border-radius: 10px 20px 30px 40px;

/* 椭圆圆角(水平 / 垂直) */
border-radius: 20px / 10px;

/* 分别设置每个角 */
border-top-left-radius: 15px;

50% 可创建完美圆形头像

.avatar {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  overflow: hidden;
}

border-image 示例:花纹边框

.fancy-border {
  border: 20px solid transparent;
  border-image: url('border-pattern.png') 30 round;
  /* 图像被切成9宫格,30px为切片宽度,round自动平铺 */
}

⚠️ 注意border-image 兼容性较好,但性能开销略高。

8.4 阴影:box-shadow, text-shadow

属性参数顺序示例
box-shadowh-offset v-offset blur spread color inset?2px 2px 5px 0px rgba(0,0,0,0.3)
text-shadowh-offset v-offset blur color1px 1px 2px black

参数说明

参数含义取值
h-offset水平偏移正右负左
v-offset垂直偏移正下负上
blur模糊半径越大越模糊
spread扩展半径(仅 box-shadow)正值扩大,负值收缩
inset内阴影关键字添加则为内阴影

多重阴影语法(逗号分隔)

.card {
  box-shadow: 
    0 2px 4px rgba(0,0,0,0.1),
    0 8px 16px rgba(0,0,0,0.1);
}

.button {
  text-shadow: 
    1px 1px 1px #fff,
    -1px -1px 1px #000;
}

多层阴影可模拟真实光照层次感。

内阴影示例(凹陷效果)

.inset-panel {
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.2);
  background: #f0f0f0;
}

常用于输入框、按钮按下状态。

8.5 渐变:线性渐变 (linear-gradient), 径向渐变 (radial-gradient), 重复渐变

渐变类型函数示例
线性渐变linear-gradient()to right, red, blue
径向渐变radial-gradient()circle at center, yellow, red
重复线性repeating-linear-gradient()45deg, red 0, red 10px, white 10px, white 20px
重复径向repeating-radial-gradient()circle, red 0 10px, white 10px 20px

linear-gradient 语法

background: linear-gradient(
  [to left | right | top | bottom | 角度],
  color-stop1, color-stop2, ...
);

/* 从左到右红→蓝 */
background: linear-gradient(to right, red, blue);

/* 45度角,带色标位置 */
background: linear-gradient(45deg, red 0%, orange 25%, yellow 50%, green 75%, blue 100%);

radial-gradient 语法

background: radial-gradient(
  [shape] [size] at [position],
  color-stop1, color-stop2
);

/* 圆形,中心点,黄→红 */
background: radial-gradient(circle at center, yellow, red);

/* 椭圆,左上角,小→大 */
background: radial-gradient(ellipse farthest-corner at top left, #ff0, #00f);

重复渐变应用:条纹背景

.stripes {
  background: repeating-linear-gradient(
    45deg,
    #f00,
    #f00 10px,
    #000 10px,
    #000 20px
  );
}

创建无限重复的 45° 红黑条纹。

8.6 变形 (transform):2D 变换 (translate, rotate, scale, skew),3D 变换基础

函数作用示例
translate(x, y)位移translate(10px, -5px)
rotate(angle)旋转rotate(45deg)
scale(sx, sy?)缩放scale(1.5), scale(1, 2)
skew(ax, ay?)倾斜skew(10deg, 5deg)
matrix(a,b,c,d,tx,ty)2D 矩阵变换高级用法
perspective(n)3D 透视距离perspective(500px)
rotateX(angle)绕 X 轴旋转rotateX(45deg)
rotateY(angle)绕 Y 轴旋转rotateY(30deg)
translateZ(z)Z 轴位移translateZ(100px)
scaleZ(sz)Z 轴缩放scaleZ(2)

3D 变换关键属性

属性作用
transform-style: preserve-3d子元素也参与 3D 空间
perspective设置观察者与 Z=0 平面的距离
perspective-origin透视视角原点(默认 center)

代码示例:3D 卡片翻转

.card-container {
  perspective: 1000px;
}

.card {
  transform-style: preserve-3d;
  transition: transform 0.6s;
}

.card:hover {
  transform: rotateY(180deg);
}

.front { backface-visibility: hidden; }
.back  { backface-visibility: hidden; transform: rotateY(180deg); }

实现鼠标悬停翻转卡片效果。

8.7 过渡 (transition):属性、时长、缓动函数、延迟

属性作用示例
transition-property要过渡的属性width, all
transition-duration过渡时长0.3s, 500ms
transition-timing-function缓动函数ease, linear, cubic-bezier()
transition-delay延迟时间0.2s
transition(简写)property duration timing-function delay推荐写法

常用缓动函数

效果适用场景
ease(默认)慢快慢通用
linear匀速旋转、循环动画
ease-in慢→快元素入场
ease-out快→慢元素消失
ease-in-out慢→快→慢弹性进出
cubic-bezier(x1,y1,x2,y2)自定义贝塞尔曲线精确控制

代码示例:按钮悬停效果

.btn {
  background: #007acc;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  /* 过渡所有变化属性 */
  transition: all 0.3s ease;
}

.btn:hover {
  background: #005a99;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}

用户交互更流畅、有反馈感。

8.8 动画 (animation):@keyframes, animation-* 属性详解

属性作用示例
@keyframes name定义动画关键帧@keyframes slideIn { from {} to {} }
animation-name引用关键帧名称slideIn
animation-duration动画时长1s
animation-timing-function缓动函数ease-in-out
animation-delay延迟启动0.5s
animation-iteration-count循环次数3, infinite
animation-direction方向normal, reverse, alternate
animation-fill-mode动画前后状态none, forwards, backwards, both
animation-play-state播放状态running, paused
animation(简写)组合所有属性推荐最后写 name duration

@keyframes 语法

@keyframes fadeIn {
  0%   { opacity: 0; transform: translateY(10px); }
  100% { opacity: 1; transform: translateY(0); }
}

@keyframes pulse {
  from, to { transform: scale(1); }
  50%      { transform: scale(1.1); }
}

完整动画示例:加载动画

@keyframes spin {
  to { transform: rotate(360deg); }
}

.loader {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #007acc;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}
<div class="loader"></div>

创建无限旋转的加载指示器。

animation-fill-mode 说明

含义
none动画外无影响
forwards结束后保持最后一帧
backwards开始前应用第一帧样式
both同时应用 forwards 和 backwards
.fade-in {
  animation: fadeIn 1s forwards;
}
/* 动画结束后 opacity 保持 1 */

第 9 章:高级 CSS 概念与机制

9.1 层叠 (Cascading) 与继承 (Inheritance) 规则

概念定义说明
层叠 (Cascading)多个样式规则作用于同一元素时的冲突解决机制按”来源 → 重要性 → 特异性 → 顺序”决定
继承 (Inheritance)子元素自动获得父元素某些样式的特性并非所有属性都可继承

层叠优先级(从高到低)

优先级来源说明
1用户代理样式(浏览器默认)<h1> 默认加粗
2用户样式(用户自定义)较少使用
3作者样式(开发者编写)我们编写的 CSS
4!important 声明打破常规层叠,慎用
5特异性 (Specificity)ID > 类 > 标签
6源码顺序后出现的覆盖先出现的(同特异性)

特异性计算表

选择器类型权重(千-百-十-个)
内联样式 style=""1,0,0,0
ID 选择器 #id0,1,0,0
类、属性、伪类 .class, [type], :hover0,0,1,0
元素、伪元素 div, ::before0,0,0,1
通配符 *、组合符 +, >、否定伪类 :not()0,0,0,0

📌 示例

  • #nav .item a → 0,1,1,1
  • div#header nav ul li a → 0,1,0,5

可继承属性示例

属性类别可继承属性
文本相关color, font-family, font-size, line-height, text-align
列表相关list-style
不可继承width, height, margin, padding, border, display, position

代码示例

/* 特异性 0,0,1,1 */
.nav .link { color: blue; }

/* 特异性 0,0,0,1,但后出现,同级覆盖 */
.link { color: red; } /* ✅ 最终生效 */

/* 使用 !important 强制优先 */
.link { color: green !important; } /* ✅ 最终为绿色 */

⚠️ 建议:避免滥用 !important,可通过提高特异性或重构选择器解决冲突。

9.2 特殊值:inherit, initial, unset, revert

关键字作用示例适用场景
inherit强制继承父元素的计算值color: inherit;子元素需与父元素一致(如链接颜色)
initial重置为属性的初始值display: initial;恢复默认行为(如取消 display: flex
unset若可继承 → inherit;否则 → initialmargin: unset;通用重置
revert恢复到用户代理或用户样式,忽略作者样式font-weight: revert;覆盖框架样式

初始值对照表

属性初始值 (initial)
colorblack(通常由浏览器决定)
displayinline
margin0
font-weightnormal (400)
text-alignstart (通常为 left)

代码示例

.parent {
  color: #007acc;
  font-weight: bold;
  margin: 20px;
}

.child {
  color: inherit;        /* 蓝色,继承父元素 */
  font-weight: initial;   /* normal,重置为初始值 */
  margin: unset;          /* 0,因为 margin 不可继承 */
  display: revert;        /* 恢复为 inline(若原为 block) */
}

unset 是最常用的”安全重置”值。

9.3 BFC (块级格式化上下文):触发条件与实际应用

概念定义说明
BFC (Block Formatting Context)一个独立的渲染区域,内部块级元素的布局不受外部影响类似”隔离的沙箱”

触发 BFC 的条件(满足任一即可)

条件示例 CSS
根元素 <html>
float 不为 nonefloat: left;
positionabsolutefixedposition: absolute;
displayinline-block, flex, grid, table-cell, table-captiondisplay: flex;
overflow 不为 visibleoverflow: hidden;(最常用)

BFC 的特性

  • ✅ 内部块级元素垂直排列
  • ✅ 相邻 margin 不会合并(外边距折叠被阻止)
  • ✅ 不与浮动元素重叠
  • ✅ 包含内部浮动元素(清除浮动)

实际应用案例

案例 1:防止外边距折叠

.container {
  overflow: hidden; /* 触发 BFC */
}
.child {
  margin: 20px;
}
/* 两个 .child 的上下 margin 不会折叠 */

案例 2:文字环绕浮动元素时避免重叠

.float-left {
  float: left;
  width: 100px;
  height: 100px;
  background: red;
}

.text-content {
  overflow: hidden; /* 触发 BFC,文字不与浮动块重叠 */
}

案例 3:清除浮动(旧方法 vs 现代方法)

/* 旧方法:clearfix */
.clearfix::after {
  content: "";
  display: block;
  clear: both;
}

/* 现代方法:直接触发 BFC */
.container {
  overflow: hidden; /* 自动包含浮动子元素 */
}

推荐使用 overflow: hiddendisplay: flow-root(专为清除浮动设计)。

9.4 IFC (行内格式化上下文) 基础

概念定义说明
IFC (Inline Formatting Context)块级容器中仅包含行内级元素时形成的格式化上下文文本排版的基础

触发条件

  • 块级容器(如 div, p)中只包含行内元素(span, a, img 等)
  • 或包含纯文本内容

IFC 的布局规则

  • ✅ 行内元素水平排列,超出换行
  • ✅ 每行形成一个”行框”(line box)
  • ✅ 行框高度由内部元素的 line-heightvertical-align 决定
  • text-align 控制行内内容水平对齐

vertical-align 常用值

说明
baseline(默认)基线对齐
top顶部对齐
middle居中对齐
bottom底部对齐
text-top / text-bottom文本顶部/底部对齐

垂直对齐问题示例

<div>
  <img src="icon.png" alt="icon">
  <span>文本</span>
</div>
img { vertical-align: middle; } /* 使图标与文本垂直居中 */

若不设置,img 默认 baseline 对齐,底部会留空隙。

9.5 CSS 自定义属性 (Variables):定义、使用 (var())、作用域

语法说明示例
--name: value;定义变量(必须以 -- 开头)--primary-color: #007acc;
var(--name, fallback)使用变量(可设默认值)color: var(--primary-color, blue);
作用域在哪个选择器内定义,就在其后代中生效推荐在 :root 定义全局变量

代码示例:主题变量系统

:root {
  --primary-color: #007acc;
  --error-color: #d32f2f;
  --font-size-base: 16px;
  --border-radius: 4px;
}

.button {
  background: var(--primary-color);
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: var(--border-radius);
  font-size: var(--font-size-base);
}

/* 动态修改变量(JS) */
/* document.documentElement.style.setProperty('--primary-color', 'purple'); */

支持 JavaScript 动态修改,实现主题切换。

9.6 calc() 函数:动态计算值

语法说明示例
calc(expression)表达式中可包含 +, -, *, /width: calc(100% - 20px);
运算符+- 两侧必须有空格calc(100% - 2em) ✅;calc(100%-2em)
单位混合可混合 %, px, em, vwheight: calc(100vh - 60px);
嵌套可嵌套 calc()width: calc(50% + calc(10px * 2));

实际应用场景

场景calc() 写法
全宽减去边栏width: calc(100% - 200px);
响应式字体font-size: clamp(1rem, 2.5vw, 2rem);(配合 calc 更灵活)
网格间隙补偿grid-template-columns: repeat(3, calc((100% - 20px) / 3));
视口减去导航栏main { height: calc(100vh - 80px); }

代码示例:自适应侧边栏布局

.container {
  display: flex;
}

.sidebar {
  width: 200px;
}

.main-content {
  width: calc(100% - 200px);
  /* 主内容区自动填满剩余空间 */
}

替代部分 JavaScript 计算逻辑。

9.7 :root 伪类与全局变量

概念定义说明
:root代表文档的根元素(即 <html>特异性为 0,0,1,0,高于普通标签选择器
全局变量:root 中定义的 CSS 变量可在文档任何位置使用

优势

  • ✅ 变量集中管理,易于维护
  • ✅ 支持继承,子元素可直接使用
  • ✅ 可结合媒体查询动态更新

代码示例:响应式断点变量

:root {
  --breakpoint-sm: 576px;
  --breakpoint-md: 768px;
  --breakpoint-lg: 992px;
  --spacing-unit: 1rem;
}

@media (max-width: var(--breakpoint-md)) {
  :root {
    --spacing-unit: 0.5rem; /* 小屏减小间距 */
  }
}

.card {
  margin: var(--spacing-unit);
}

主题切换示例

:root {
  --bg-color: white;
  --text-color: black;
}

[data-theme="dark"] {
  --bg-color: #121212;
  --text-color: #eee;
}

body {
  background: var(--bg-color);
  color: var(--text-color);
  transition: all 0.3s ease;
}
<!-- 注意:以下示例中的 onclick 在服务端渲染环境中无法运行 -->
<!-- <button onclick="document.body.setAttribute('data-theme','dark')">切换深色模式</button> -->
<button class="theme-toggle">切换深色模式</button>

实现无需预编译的动态主题系统。

第 10 章:CSS 方法论与工程化

10.1 CSS 架构模式:BEM, SMACSS, OOCSS

架构全称核心思想适用场景
BEMBlock Element Modifier将 UI 拆分为独立的块(Block),元素(Element)和修饰符(Modifier)中大型项目,组件化开发
SMACSSScalable and Modular Architecture for CSS将样式分为五类:基础、布局、模块、状态、主题复杂页面结构,强调分层
OOCSSObject-Oriented CSS面向对象思想,分离结构与皮肤,容器与内容提高样式复用性

BEM 命名规范详解

部分语法示例说明
Blockblock-nameheader, menu独立功能模块
Elementblock__elementmenu__item, header__logo属于某个块的子元素
Modifierblock--modifierblock__element--modifiermenu--vertical, button__icon--hidden表示状态或变体

📌 BEM 优势

  • 类名语义清晰
  • 避免嵌套过深
  • 支持并行开发

BEM 代码示例

<nav class="menu menu--horizontal">
  <ul class="menu__list">
    <li class="menu__item menu__item--active">
      <a href="#" class="menu__link">首页</a>
    </li>
    <li class="menu__item">
      <a href="#" class="menu__link">关于</a>
    </li>
  </ul>
</nav>
.menu { display: flex; }
.menu--horizontal { flex-direction: row; }
.menu__list { list-style: none; margin: 0; padding: 0; }
.menu__item { position: relative; }
.menu__item--active { font-weight: bold; }
.menu__link { text-decoration: none; padding: 10px; }

SMACSS 分类表

类别描述示例
Base元素默认样式body, h1, a
Layout页面级布局容器.header, .sidebar, .main
Module可复用组件.carousel, .dropdown
State特定状态样式.is-active, .is-hidden
Theme主题相关样式.theme-dark

OOCSS 原则示例

/* 结构与皮肤分离 */
.btn          { display: inline-block; padding: 10px 20px; border-radius: 4px; }
.btn-primary  { background: #007acc; color: white; }
.btn-success  { background: #28a745; color: white; }

/* 容器与内容分离 */
.media        { display: flex; align-items: flex-start; }
.media__img   { margin-right: 16px; }
.media__body  { flex: 1; }

实现高复用、低耦合的样式系统。

10.2 CSS 预处理器:Sass/SCSS, Less, Stylus (变量、嵌套、混合、函数)

特性Sass (SCSS) 示例说明
变量$primary-color: #007acc;$ 开头,支持作用域
嵌套nav { ul { li { a { &:hover { ... } } } } }模拟 DOM 结构,减少重复选择器
混合 (Mixin)@mixin center { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }可带参数的代码块
继承 (@extend)%.btn-base { padding: 10px; } .btn { @extend %btn-base; }减少 CSS 重复
函数@function pow($n, $exp) { @return $n * $exp; }自定义计算逻辑
条件与循环@if $type == primary { ... } @for $i from 1 through 3 { .item-#{$i} { order: $i; } }动态生成样式

SCSS 代码示例:按钮系统

// 变量
$primary: #007acc;
$spacing: 1rem;

// 混合
@mixin button-style($bg, $color: white) {
  background: $bg;
  color: $color;
  border: none;
  padding: $spacing * 0.8 $spacing;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s ease;
  
  &:hover {
    opacity: 0.9;
    transform: translateY(-1px);
  }
}

// 使用
.btn {
  @include button-style($primary);
  
  &--success {
    @include button-style(#28a745);
  }
  
  &--large {
    padding: $spacing $spacing * 1.5;
  }
}

编译后生成标准 CSS,可在浏览器运行。

预处理器对比

工具语法风格特点
Sass/SCSS.sass(缩进)或 .scss(类似 CSS)生态最成熟,功能最全
Less.less,类似 CSS支持客户端编译(不推荐)
Stylus.styl,极简语法(可省略 {} ;灵活但易混乱

推荐使用 SCSS,社区支持最好。

10.3 CSS 后处理器:PostCSS (插件生态、自动前缀、未来语法)

概念说明
PostCSS基于 JavaScript 的 CSS 处理工具,通过插件转换 CSS
AST (抽象语法树)将 CSS 解析为树结构,便于程序操作

常用 PostCSS 插件

插件功能示例配置
autoprefixer自动添加浏览器前缀browsers: ['> 1%', 'last 2 versions']
postcss-preset-env使用未来 CSS 语法(如 nesting, custom media)支持 @custom-media
cssnanoCSS 压缩优化减小文件体积
postcss-import支持 @import 合并文件替代预处理器的 @import
postcss-flexbugs-fixes修复 Flexbox 兼容性问题提升跨浏览器一致性

postcss.config.js 示例

module.exports = {
  plugins: [
    require('postcss-import'),
    require('postcss-preset-env')({
      stage: 3, // 使用稳定提案
      features: {
        'nesting-rules': true
      }
    }),
    require('autoprefixer'),
    require('cssnano') // 生产环境启用
  ]
}

使用未来语法示例(需 postcss-preset-env)

/* 嵌套(类似 SCSS) */
.card {
  padding: 1rem;
  
  &__title {
    font-weight: bold;
  }
  
  &__footer {
    border-top: 1px solid #eee;
  }
}

/* 自定义媒体查询 */
@custom-media --sm (width >= 576px);

@media (--sm) {
  .card { max-width: 500px; }
}

实现”原生 CSS + 插件增强”的现代开发流。

10.4 模块化与组件化 CSS

方案机制优点缺点
CSS Modules将 CSS 文件编译为 JS 模块,类名局部作用域彻底避免命名冲突需构建工具支持
Scoped CSSVue <style scoped> 或 Shadow DOM样式仅作用于当前组件Vue 特有
原子化 CSS (Tailwind)每个类只负责一个样式属性高复用,无冗余学习成本高,HTML 膨胀
CSS-in-JS在 JS 中写样式(Styled-components)动态样式强,作用域安全运行时开销

CSS Modules 示例

/* Button.module.css */
.root {
  padding: 10px 20px;
  background: #007acc;
  color: white;
  border: none;
  border-radius: 4px;
}

.primary {
  background: #d32f2f;
}
// React 组件中使用
import styles from './Button.module.css';

function Button({ variant }) {
  return (
    <button className={`${styles.root} ${styles[variant]}`}>
      Click Me
    </button>
  );
}
// 编译后类名类似:`Button_root__abc123`

组件化设计原则

  • ✅ 单一职责:每个组件只做一件事
  • ✅ 可组合:组件可嵌套使用
  • ✅ 可配置:通过类名或属性定制外观
  • ✅ 文档化:提供使用说明和示例

10.5 CSS 性能优化:减少重排重绘、高效选择器、文件压缩、动画性能 (transform, opacity, will-change)

优化方向策略说明
减少重排重绘避免频繁修改布局属性(width, height, margin, top 等)每次修改可能触发整个页面重新计算
高效选择器避免深层嵌套和通用选择器(*, tag)浏览器从右向左匹配,.a .b .c.c
动画性能优先使用 transform 和 opacity这些属性由 GPU 加速,不触发重排
will-change提示浏览器提前优化will-change: transform;
文件压缩使用 cssnano 或构建工具压缩删除空格、注释,合并规则
关键 CSS 内联将首屏关键样式内联到 <head>减少渲染阻塞
异步加载非关键 CSS<link rel="preload" as="style"> 或动态插入提升首屏速度

触发重排的属性(慎用)

  • width, height, margin, padding, display, position, overflow, float, border

高性能动画示例

.animated-box {
  /* ✅ 推荐:GPU 加速 */
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.animated-box:hover {
  transform: scale(1.1) rotate(5deg);
  opacity: 0.8;
}

/* ❌ 不推荐:触发重排 */
.bad-animation {
  width: 200px;
  height: 200px;
}

.bad-animation:hover {
  width: 220px;
  height: 220px;
}

will-change 使用建议

.carousel-item {
  will-change: transform; /* 提示将要变换 */
  transition: transform 0.5s ease;
}

⚠️ 仅对真正会动画的元素使用,滥用会导致内存浪费。

构建优化流程

源文件 (.scss)

Sass 编译 → CSS

PostCSS 处理(autoprefixer, nesting)

压缩(cssnano)

输出生产 CSS 文件

结合 Webpack/Vite 实现自动化工程流。

第 11 章:无障碍访问 (a11y) 与用户体验

11.1 CSS 在无障碍中的角色

作用说明正确做法 vs 错误做法
视觉呈现将语义化 HTML 转换为用户可感知的界面✅ 用 CSS 控制样式
❌ 用 CSS 改变语义(如用 div 模拟按钮)
响应用户偏好尊重用户系统设置(如动画、颜色模式)✅ 使用 prefers-* 媒体查询
❌ 强制覆盖用户设置
焦点管理确保键盘用户能清晰看到当前焦点✅ 定义清晰的 :focus 样式
❌ 设置 outline: none 而不提供替代样式
内容隐藏控制元素的显示与隐藏✅ 使用 visibility: hiddenaria-hidden="true"
❌ 仅用 display: none 隐藏仍需屏幕阅读器读取的内容

📌 核心原则:CSS 不应破坏 HTML 的语义结构。

常见反模式与修复

问题反模式代码修复方案
用 div 当按钮<div onclick="...">提交</div>改用 <button> 或添加 role="button" tabindex="0"
隐藏标题但需读取<h2 style="display:none">搜索结果</h2>改用 .sr-only 类(见下文)
移除轮廓后无替代*:focus { outline: none; }提供高对比度背景或边框

屏幕阅读器友好类(.sr-only)

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
<h2 class="sr-only">搜索结果</h2>
<!-- 屏幕阅读器可读,视觉上隐藏 -->

用于分页、状态提示等视觉隐藏但语义重要的内容。

11.2 颜色对比度与可读性

WCAG 等级正常文本 (≥)大文本 (≥)说明
AA4.5:13:1最低可接受标准
AAA7:14.5:1更高可访问性

📌 大文本:18pt(24px)以上,或粗体 14pt(18.66px)以上。

对比度计算示例

背景色文本色对比度是否达标 (AA)
#ffffff (白)#000000 (黑)21:1
#ffffff#6666664.5:1✅ (刚好)
#f0f0f0#33333312.6:1
#ffeb3b (黄)#00000019.7:1
#ffeb3b#ffffff1.1:1❌ 极差

提高对比度策略

  • ✅ 使用深灰 (#333) 替代纯黑,减少视觉疲劳
  • ✅ 背景复杂时添加文字阴影或半透底衬
  • ✅ 提供”高对比度”主题切换选项

代码示例:增强可读性

.text-overlay {
  color: white;
  /* 添加半透黑底衬提升对比度 */
  background: linear-gradient(transparent, rgba(0,0,0,0.7));
  padding: 10px;
}

/* 或使用 text-shadow */
.high-contrast {
  color: #000;
  text-shadow: 1px 1px 1px #fff, -1px -1px 1px #fff;
}

推荐工具:WebAIM Contrast Checker

11.3 键盘导航与 :focus 样式

概念说明
键盘用户包括残障人士、开发者、高效用户
Tab 键在可聚焦元素间移动(<a>, <button>, input, tabindex 元素)
:focus伪类,表示元素获得焦点
:focus-visible仅在键盘触发时显示焦点样式(现代浏览器支持)

可聚焦元素

元素默认可聚焦?
<a href="...">
<button>
<input>, <textarea>, <select>
<details>, <summary>
tabindex="0"✅(手动添加)
tabindex="-1"❌(不可聚焦,但可通过 JS 聚焦)

焦点样式最佳实践

/* ✅ 好做法:提供清晰的视觉反馈 */
button:focus,
input:focus,
.custom-button:focus {
  outline: 2px solid #007acc;
  outline-offset: 2px;
  /* 或使用 box-shadow */
  box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.3);
}

/* ✅ 现代方案:仅键盘用户显示轮廓 */
.custom-button {
  outline: none;
}

.custom-button:focus {
  /* 默认无轮廓 */
}

.custom-button:focus-visible {
  /* 仅键盘聚焦时显示 */
  outline: 2px solid #007acc;
  outline-offset: 2px;
}

避免焦点陷阱

// 注意:以下代码仅在浏览器环境中运行
// 模态框打开时
// modal.addEventListener('keydown', (e) => {
//   if (e.key === 'Tab') {
//     const focusable = modal.querySelectorAll('button, a, input');
//     const first = focusable[0];
//     const last = focusable[focusable.length - 1];
//     
//     if (e.shiftKey && document.activeElement === first) {
//       e.preventDefault();
//       last.focus();
//     } else if (!e.shiftKey && document.activeElement === last) {
//       e.preventDefault();
//       first.focus();
//     }
//   }
// });

确保模态框内焦点循环,不跳出到背景内容。

11.4 媒体查询与用户偏好

媒体查询作用示例
prefers-reduced-motion用户请求减少动画关闭非必要动画
prefers-color-scheme用户偏好浅色或深色模式切换主题
prefers-contrast用户需要高对比度增强颜色对比
prefers-reduced-transparency减少透明效果移除模糊、半透背景

代码示例

/* 11.4.1 减少动画 (prefers-reduced-motion) */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* 11.4.2 暗黑/明亮模式 (prefers-color-scheme) */
:root {
  --bg-color: white;
  --text-color: #333;
  --link-color: #007acc;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #121212;
    --text-color: #eee;
    --link-color: #4ea4f8;
  }
}

body {
  background: var(--bg-color);
  color: var(--text-color);
  transition: background 0.3s ease;
}

a { color: var(--link-color); }

/* 11.4.3 高对比度 (prefers-contrast) */
@media (prefers-contrast: high) {
  :root {
    --border-thick: 3px;
    --bg-highlight: black;
    --text-highlight: white;
  }
  
  .card {
    border: var(--border-thick) solid black;
  }
  
  .highlight {
    background: var(--bg-highlight);
    color: var(--text-highlight);
    font-weight: bold;
  }
}

尊重用户设置是现代 Web 的基本素养。

11.5 避免仅依赖视觉线索传达信息

问题类型仅视觉线索多通道解决方案
必填字段红星 *添加 aria-required="true" 和文本”(必填)“
错误提示红色边框添加 aria-invalid="true"、错误图标、错误文本
成功状态绿色对勾添加 aria-live="polite" 播报”提交成功”
警告信息黄色背景添加感叹号图标、role="alert"
链接状态下划线添加 aria-current="page" 表示当前页

代码示例:表单验证

<label for="email">
  邮箱 <span aria-hidden="true">*</span>
  <span class="sr-only">(必填)</span>
</label>
<input 
  type="email" 
  id="email" 
  required 
  aria-describedby="email-error"
>
<div id="email-error" role="alert" aria-live="assertive" style="display:none;">
  ❌ 请输入有效的邮箱地址
</div>
// JS 验证逻辑
emailInput.addEventListener('invalid', () => {
  emailError.style.display = 'block';
  emailInput.setAttribute('aria-invalid', 'true');
});

导航当前页指示

<nav>
  <a href="/home" aria-current="page">首页</a>
  <a href="/about">关于</a>
</nav>
[aria-current="page"] {
  font-weight: bold;
  text-decoration: underline;
  /* 视觉用户可见 */
}
/* 屏幕阅读器会播报"当前页" */

所有状态信息应通过视觉、听觉、程序化三种方式传达。

第 12 章:浏览器兼容性与开发工具

12.1 主流浏览器差异与兼容性策略

浏览器内核市场份额(2025)特点
ChromeBlink (Chromium)~65%更新快,支持新特性最早
EdgeBlink (Chromium)~10%基于 Chromium,兼容性好
SafariWebKit~18%iOS 唯一内核,更新慢,私有前缀多
FirefoxGecko~5%注重隐私与标准,支持良好
旧版 IETrident<1%已淘汰,但遗留系统仍需考虑

📌 当前主流:Blink (Chrome/Edge) 和 WebKit (Safari)

兼容性策略

策略说明示例
渐进增强 (Progressive Enhancement)从基础功能开始,逐步为高级浏览器添加增强特性先实现静态布局,再为支持 Flex 的浏览器使用弹性布局
优雅降级 (Graceful Degradation)为现代浏览器设计,确保旧浏览器仍可使用核心功能使用 Grid 布局,旧浏览器回退到 Float 布局
特性检测检测浏览器是否支持某特性,而非检测浏览器类型使用 @supports (display: grid) { ... }
Polyfill用 JS 模拟缺失的 CSS/JS 功能flexibility.js 为 IE 支持 Flexbox

常见兼容性问题与修复

问题受影响浏览器解决方案
Flexbox 不支持IE 10-使用 display: -ms-flexbox 或回退布局
Grid 不支持IE, 旧版 Safari使用 @supports 检测,提供 Float 回退
position: stickyIE, 旧版 Firefox使用 JS 模拟或回退为 relative
:focus-visible旧版 Chrome/Firefox使用 :focus 作为备选
aspect-ratioSafari < 15使用 padding-bottom 技巧

12.2 Can I Use 等兼容性查询工具

工具网址功能优势
Can I usehttps://caniuse.com查询 CSS/JS 特性在各浏览器的支持情况数据权威,支持筛选地区/版本
MDN Web Docshttps://developer.mozilla.org官方文档 + 兼容性表格与规范同步,解释清晰
Browserlist配置文件(如 .browserslistrc定义目标浏览器范围,供构建工具使用与 PostCSS/Autoprefixer 集成
AutoprefixerPostCSS 插件自动添加浏览器前缀基于 Can I Use 数据

caniuse.com 使用指南

  • 搜索特性:如 css-grid, flexbox, prefers-color-scheme
  • 查看支持率:
    • ✅ 绿色:完全支持
    • 🟡 黄色:部分支持
    • ❌ 红色:不支持
  • 筛选目标:
    • 按”全球”或”中国”用户统计
    • 按”最新版本”或”指定版本”
  • 查看注意事项:
    • 已知 bug
    • 前缀需求(如 -webkit-
    • 启用标志(需手动开启)

browserslist 配置示例

# .browserslistrc
> 1%           # 全球使用率 >1%
last 2 versions # 每个浏览器最近2个版本
not dead       # 不支持已停止更新的浏览器
not IE <= 11   # 明确排除 IE 11
// package.json 中
"browserslist": [
  "> 1%",
  "last 2 versions",
  "not ie <= 11"
]

Autoprefixer 会根据此配置自动添加 -webkit-, -moz- 等前缀。

12.3 CSS 重置 (Reset) 与规范化 (Normalize.css)

方案目标代表库特点
CSS Reset移除所有默认样式,从零开始Meyer Reset, Eric Meyer’s Reset彻底,但需重新定义所有样式
Normalize.css统一不同浏览器的默认样式差异normalize.css保留有用默认值,修复常见 bug
Modern Reset轻量、现代、基于自定义属性modern-css-reset, minireset.css仅处理关键差异

Normalize.css 核心修复

问题修复方式
HTML5 元素样式<article>, <section> 等添加默认 display
表单元素一致性统一 <button>, <input> 的字体、边框
链接颜色保留蓝色,但移除虚线轮廓
pre 和 code正确换行与字体
移动端缩放设置 viewport 提示

现代轻量重置示例

/* modern-css-reset 风格 */
* {
  box-sizing: border-box;
}

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

html,
body {
  margin: 0;
  padding: 0;
}

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

input,
button,
textarea,
select {
  font: inherit;
}

p,
h1,
h2,
h3,
h4,
h5,
h6 {
  overflow-wrap: break-word;
}

#root,
#__next {
  isolation: isolate;
}

推荐方案

项目类型推荐方案
新项目使用 modern-css-reset 或自定义轻量重置
老项目使用 normalize.css 稳定过渡
极简项目手动重置 margin, padding, box-sizing

强烈建议设置 *, *::before, *::after { box-sizing: border-box; }

12.4 浏览器开发者工具 (DevTools) 深度使用

12.4.1 元素检查与样式调试

功能操作用途
元素选择Ctrl+Shift+C (Win) / Cmd+Shift+C (Mac)快速选中页面元素
样式面板右侧面板查看 Styles查看应用的 CSS 规则、特异性、继承
修改样式直接编辑颜色、尺寸、类名实时调试,无需刷新
伪类强制:hov 按钮强制 :hover, :active 状态调试交互样式
CSS 变量查看在 Computed 面板查看变量值调试主题系统

12.4.2 盒模型可视化

功能说明
盒模型图示元素下方显示 margin, border, padding, content 区域
颜色区分外边距(Margin):橙色
边框(Border):黄色
内边距(Padding):紫色
内容(Content):蓝色
实时编辑点击数值可直接修改 margin, padding 等

快速诊断布局错位、间距异常问题。

12.4.3 布局分析 (Flex/Grid Overlay)

布局类型操作功能
Flexbox在 Styles 面板点击 Flex 图标显示主轴、交叉轴、对齐方式、项目顺序
Grid在 Styles 面板点击 Grid 图标显示网格线、区域、轨道大小,可重命名
多层叠加可同时开启多个布局分析调试嵌套布局

用于调试 justify-content, align-items, grid-template-areas 等复杂设置。

12.4.4 性能分析

面板功能用途
Rendering开启”Paint flashing”、“Layout shift regions”高亮重绘区域,检测布局抖动
Performance录制页面交互分析 FPS、CPU 占用、重排重绘耗时
CoverageCtrl+Shift+P → “Show Coverage”检测未使用的 CSS/JS 代码
Lighthouse审计性能、可访问性、SEO生成优化建议报告

12.4.5 响应式设计测试

功能操作优势
设备模式Ctrl+Shift+M模拟手机、平板等设备
设备预设下拉选择 iPhone, Pixel, iPad 等快速切换常见分辨率
自定义尺寸拖拽边框或输入尺寸精确测试断点
网络 throttling限制为 “Slow 3G”模拟弱网环境加载
方向切换横屏/竖屏按钮测试移动端旋转

结合 @media 查询实时调试断点。

第 13 章:现代 CSS 与前沿技术

13.1 容器查询 (@container)

概念说明
媒体查询 (Media Query)基于视口(viewport)尺寸变化
容器查询 (Container Query)基于容器元素自身尺寸变化
核心价值实现”上下文感知”的组件,提升组件复用性

使用步骤

  • 定义查询容器:使用 container-type 指定查询类型
  • 命名容器(可选):使用 container-name
  • 编写查询规则:使用 @container

代码示例

<div class="card-container">
  <article class="card">
    <img src="image.jpg" alt="Card image" class="card__image">
    <div class="card__content">
      <h3 class="card__title">标题</h3>
      <p class="card__desc">描述文字...</p>
    </div>
  </article>
</div>
/* 1. 定义容器 */
.card-container {
  container-type: inline-size; /* 或 'size' */
  container-name: card-wrapper;
  width: 50%; /* 容器宽度可变 */
}

/* 2. 使用容器查询 */
@container (min-width: 400px) {
  .card {
    display: flex;
    gap: 1rem;
  }
  .card__image {
    width: 120px;
    flex-shrink: 0;
  }
}

@container (max-width: 399px) {
  .card {
    flex-direction: column;
  }
  .card__image {
    width: 100%;
    height: auto;
  }
}

卡片组件在窄容器中堆叠,在宽容器中并排,无需关心页面整体宽度。

多容器查询(命名)

.sidebar {
  container-name: sidebar;
  container-type: inline-size;
}

.main-content {
  container-name: main;
  container-type: block-size;
}

/* 同时满足两个容器条件 */
@container sidebar (min-width: 200px) and main (min-height: 500px) {
  .widget {
    display: grid;
  }
}

📌 支持:Chrome 105+, Firefox 110+, Safari 17+

13.2 CSS 嵌套 (Native Nesting)

特性原生 CSS 嵌套Sass/SCSS 嵌套
编译浏览器原生支持构建时编译为标准 CSS
作用域全局可配合模块化
父选择器&&
状态组合&:hover, &.active相同

语法规范

/* 基础嵌套 */
.card {
  padding: 1rem;
  
  &__title {
    font-weight: bold;
    
    &:hover {
      color: #007acc;
    }
  }
  
  &__footer {
    border-top: 1px solid #eee;
    
    .btn {
      margin-right: 0.5rem;
    }
  }
}

编译后等效 CSS

.card { padding: 1rem; }
.card__title { font-weight: bold; }
.card__title:hover { color: #007acc; }
.card__footer { border-top: 1px solid #eee; }
.card__footer .btn { margin-right: 0.5rem; }

注意事项

  • ❌ 不支持深层嵌套(如 a { b { c { d { ... } } } } 易降低性能)
  • ✅ 推荐嵌套层级 ≤ 3
  • ✅ 结合 BEM 命名使用效果更佳

📌 支持:Chrome 119+, Safari 17+, Firefox 正在实现中(可通过 layout.css.nested-boxes.enabled 启用)

13.3 作用域样式 (@scope)

概念说明
@scope将样式规则限制在特定 HTML 范围内
语法@scope (<root>) to (<anchor>) { ... }
用途第三方组件样式隔离、主题区域、避免全局污染

基本语法

@scope (.card) {
  h2 {
    color: #333;
    font-size: 1.2rem;
  }
  p {
    line-height: 1.5;
  }
}

等效于

.card h2, .card > h2 { color: #333; font-size: 1.2rem; }
.card p, .card > p { line-height: 1.5; }

高级用法:锚点限制 (to)

@scope (.header) to (.footer) {
  nav a {
    color: white;
    background: black;
  }
}

仅当 .header.footer 同时存在,且 nav a 在它们之间时才生效。

组件化应用

/* 第三方评论组件样式隔离 */
@scope ([data-widget="comments"]) {
  * {
    all: initial; /* 重置所有样式 */
    font-family: system-ui;
  }
  ul, ol { margin: 0; padding: 0; list-style: none; }
  .comment { border-bottom: 1px solid #eee; padding: 0.5rem 0; }
}

防止外部样式污染,也防止内部样式泄漏。

📌 状态:实验性功能,Chrome Canary 可通过 flag 启用,尚未广泛支持。

13.4 滚动驱动动画 (Scroll-driven Animations)

动画类型触发机制API
时间动画随时间推移播放@keyframes, animation
滚动驱动动画随用户滚动进度播放scroll-timeline, animation-timeline

核心属性

属性说明
scroll-timeline将元素的滚动容器绑定为动画时间轴
view-timeline将视口或某个元素作为时间轴(推荐)
animation-timeline指定动画使用的时间轴(而非默认时间)

代码示例:视口时间轴动画

<section class="hero">Hero Section</section>
<section class="animate-in">滚动到我时开始动画</section>
.animate-in {
  opacity: 0;
  transform: translateY(50px);
  animation: fadeSlide 1s linear forwards;
  
  /* 关键:使用视口作为时间轴 */
  view-timeline: --slide-in;
}

@keyframes fadeSlide {
  from {
    opacity: 0;
    transform: translateY(50px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.animate-in 元素进入视口时,动画开始;完全离开时,动画反向播放。

自定义滚动时间轴

.container {
  overflow-y: scroll;
  scroll-timeline: --scroll-y;
}

.sticky-element {
  position: sticky;
  top: 0;
  animation: parallax 1s linear forwards;
  animation-timeline: --scroll-y; /* 使用容器滚动作为时间轴 */
}

实现容器内滚动驱动的视差效果。

📌 支持:Chrome 120+, Safari 17+,Firefox 正在开发

13.5 子网格 (Subgrid)

问题:传统 Grid 嵌套缺陷

层级问题
父网格grid-template-columns: 1fr 2fr;
子网格必须重新定义列,无法继承父网格轨道

子网格解决方案

.wrapper {
  display: grid;
  grid-template-columns: 
    [full-start] 1fr 
    [main-start] minmax(300px, 800px) [main-end] 
    1fr 
    [full-end];
  gap: 1rem;
}

.content {
  display: grid;
  grid-column: main; /* 占据主区域 */
  grid-template-rows: auto 1fr auto;
  /* 关键:列使用 subgrid 继承父网格 */
  grid-template-columns: subgrid;
  grid-column: full; /* 横跨整个外层网格 */
}

.sidebar {
  grid-column: full-start / main-start;
}

.main {
  grid-column: main;
}

.footer {
  grid-column: full;
  /* 子元素可对齐到外层网格线 */
  display: grid;
  grid-template-columns: subgrid;
}
<div class="wrapper">
  <aside class="sidebar">Sidebar</aside>
  <main class="content">
    <header>Header</header>
    <div>Main Content</div>
    <footer class="footer">
      <button>Btn 1</button>
      <button>Btn 2</button>
    </footer>
  </main>
</div>

.footer 内的按钮可对齐到 .wrapper 的网格线,实现跨层级设计一致性。

📌 支持:Firefox 71+, Chrome 111+, Safari 17+

13.6 aspect-ratio 属性

语法示例说明
aspect-ratio: <ratio>16 / 9, 4 / 3, 1宽高比
auto <ratio>auto 16 / 9优先使用固有比例,否则使用指定比例

传统 vs 现代方案

方案代码缺点
Padding 技巧.container { position: relative; padding-top: 56.25%; }需要额外包装,难以控制内容
aspect-ratio.container { aspect-ratio: 16 / 9; }简洁直观

代码示例

.media-container {
  width: 100%;
  aspect-ratio: 16 / 9; /* 或 4 / 3, 1 / 1 (正方形) */
  background: #000;
  overflow: hidden;
}

.media-container img,
.media-container video {
  width: 100%;
  height: 100%;
  object-fit: cover; /* 保持比例填充 */
}
<div class="media-container">
  <img src="landscape.jpg" alt="Landscape">
</div>

响应式比例

.image {
  width: 100%;
  aspect-ratio: 1; /* 默认正方形 */
}

@media (min-aspect-ratio: 16/9) {
  .image {
    aspect-ratio: 16 / 9;
  }
}

📌 支持:Chrome 88+, Firefox 89+, Safari 15.4+, 全面支持

13.7 CSS Houdini (自定义属性、Paint API 等)

概念说明
CSS Houdini一组底层 API,让开发者”参与”CSS 引擎工作
目标实现真正的自定义 CSS 功能(如自定义属性、函数、布局)

13.7.1 CSS 自定义属性(Typed OM)

// 注册强类型自定义属性
CSS.registerProperty({
  name: '--accent-color',
  syntax: '<color>',
  inherits: false,
  initialValue: 'blue'
});

CSS.registerProperty({
  name: '--rotate-progress',
  syntax: '<number>',
  inherits: true,
  initialValue: 0
});
.spinner {
  --rotate-progress: 0; /* 现在是数字类型,可动画 */
  animation: spin 2s infinite linear;
}

@keyframes spin {
  to {
    --rotate-progress: 1; /* 从 0 → 1 */
  }
}

.spinner::before {
  content: '';
  display: block;
  width: 40px;
  height: 40px;
  background: paint(spinnerPainter); /* 使用 Paint API */
}

13.7.2 Paint API(自定义绘制)

// worklet.js
class SpinnerPainter {
  static get inputProperties() {
    return ['--rotate-progress', '--accent-color'];
  }
  
  paint(ctx, geom, properties) {
    const progress = properties.get('--rotate-progress').value;
    const color = properties.get('--accent-color').value;
    
    const { width, height } = geom;
    const radius = Math.min(width, height) / 2 - 10;
    
    ctx.lineWidth = 8;
    ctx.strokeStyle = color;
    ctx.lineCap = 'round';
    
    // 绘制圆弧
    ctx.beginPath();
    ctx.arc(
      width / 2, height / 2,
      radius,
      -0.5 * Math.PI,
      (progress * 1.8 - 0.5) * Math.PI
    );
    ctx.stroke();
  }
}

registerPaint('spinnerPainter', SpinnerPainter);
<!-- 注意:以下脚本仅在浏览器环境中运行 -->
<!-- <script>
CSS.paintWorklet.addModule('worklet.js');
</script> -->

实现可动画、高性能的自定义 SVG 级别图形。

Houdini API 概览

API用途状态
CSS Properties & Values API注册可动画的自定义属性广泛支持
CSS Paint API自定义背景、边框绘制Chrome/Edge/Safari
CSS Layout API自定义布局算法(如 masonry)实验性
CSS Animation Worklet高性能自定义动画实验性

📌 Houdini 是未来,但目前主要用于高级优化与创新 UI。

第 14 章:综合实战项目

14.1 响应式企业官网重构

核心技术

  • ✅ flexbox 导航栏
  • ✅ grid 主内容布局
  • @media 响应式断点
  • prefers-color-scheme 暗黑模式
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>企业官网</title>
  <style>
    :root {
      --primary: #007acc;
      --text: #333;
      --bg: white;
      --gap: 1rem;
    }
    @media (prefers-color-scheme: dark) {
      :root {
        --text: #eee;
        --bg: #121212;
      }
    }
    body {
      margin: 0;
      font-family: system-ui;
      background: var(--bg);
      color: var(--text);
      line-height: 1.6;
    }
    header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 1rem;
      border-bottom: 1px solid #ddd;
    }
    nav ul {
      display: flex;
      list-style: none;
      gap: var(--gap);
      margin: 0;
      padding: 0;
    }
    main {
      display: grid;
      grid-template-columns: 1fr;
      gap: var(--gap);
      padding: 1rem;
    }
    .hero {
      text-align: center;
      padding: 2rem 0;
    }
    .features {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
      gap: var(--gap);
    }
    @media (min-width: 768px) {
      main {
        grid-template-columns: 2fr 1fr;
      }
      .sidebar {
        grid-row: 1;
      }
    }
  </style>
</head>
<body>
  <header>
    <h1>Company</h1>
    <nav>
      <ul>
        <li><a href="#home">首页</a></li>
        <li><a href="#about">关于</a></li>
        <li><a href="#contact">联系</a></li>
      </ul>
    </nav>
  </header>
  <main>
    <div class="content">
      <section class="hero">
        <h2>欢迎来到我们的网站</h2>
        <p>提供优质服务</p>
      </section>
      <section class="features">
        <div class="card"><h3>功能一</h3><p>描述</p></div>
        <div class="card"><h3>功能二</h3><p>描述</p></div>
      </section>
    </div>
    <aside class="sidebar">侧边栏</aside>
  </main>
</body>
</html>

14.2 个人博客系统 UI 实现

核心技术

  • ✅ grid 卡片布局
  • aspect-ratio 图片容器
  • :focus-visible 键盘友好
  • @container 组件响应
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width"/>
  <title>个人博客</title>
  <style>
    * { box-sizing: border-box; }
    body {
      margin: 0;
      font-family: 'Segoe UI', sans-serif;
      line-height: 1.6;
      padding: 1rem;
      max-width: 800px;
      margin: 0 auto;
    }
    .blog-posts {
      container-type: inline-size;
      display: grid;
      gap: 1.5rem;
      margin-top: 2rem;
    }
    @container (min-width: 500px) {
      .blog-posts {
        grid-template-columns: 1fr 1fr;
      }
    }
    .post {
      border: 1px solid #eee;
      border-radius: 8px;
      overflow: hidden;
    }
    .post-img {
      aspect-ratio: 16 / 9;
      background: #f0f0f0;
      background-image: linear-gradient(45deg, #ddd 25%, transparent 25%),
                        linear-gradient(-45deg, #ddd 25%, transparent 25%),
                        linear-gradient(45deg, transparent 75%, #ddd 75%),
                        linear-gradient(-45deg, transparent 75%, #ddd 75%);
      background-size: 20px 20px;
      background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
    }
    .post-content {
      padding: 1rem;
    }
    a:focus-visible {
      outline: 3px solid #007acc;
      outline-offset: 2px;
    }
  </style>
</head>
<body>
  <h1>我的博客</h1>
  <div class="blog-posts">
    <article class="post">
      <div class="post-img"></div>
      <div class="post-content">
        <h3><a href="#">文章标题一</a></h3>
        <p>摘要文字...</p>
      </div>
    </article>
    <article class="post">
      <div class="post-img"></div>
      <div class="post-content">
        <h3><a href="#">文章标题二</a></h3>
        <p>摘要文字...</p>
      </div>
    </article>
  </div>
</body>
</html>

14.3 数据可视化仪表盘布局

核心技术

  • ✅ CSS Grid 复杂布局
  • ✅ subgrid 子网格对齐
  • ✅ scroll-driven animation 滚动动画
  • ✅ 自定义属性控制主题
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width"/>
  <title>仪表盘</title>
  <style>
    :root {
      --primary: #4a90e2;
      --success: #7ed321;
      --danger: #d0021b;
      --gap: 1rem;
      --header-height: 60px;
    }
    body {
      margin: 0;
      font-family: system-ui;
      background: #f5f5f5;
    }
    header {
      height: var(--header-height);
      background: var(--primary);
      color: white;
      display: flex;
      align-items: center;
      padding: 0 1rem;
    }
    .dashboard {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr 1fr;
      grid-template-rows: auto 1fr;
      gap: var(--gap);
      padding: var(--gap);
      height: calc(100vh - var(--header-height));
    }
    .card {
      background: white;
      border-radius: 8px;
      padding: 1rem;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
    /* 使用 subgrid 对齐卡片内部网格 */
    .grid-4x2 {
      display: grid;
      grid-template-rows: subgrid;
      grid-row: span 2;
    }
    .stat {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 0.5rem;
    }
    /* 滚动驱动动画 */
    .chart {
      opacity: 0;
      transform: translateY(30px);
      animation: slideIn 0.8s ease-out forwards;
      animation-timeline: view();
    }
    @keyframes slideIn {
      to {
        opacity: 1;
        transform: translateY(0);
      }
    }
  </style>
</head>
<body>
  <header>数据仪表盘</header>
  <div class="dashboard">
    <div class="card grid-4x2">关键指标</div>
    <div class="card chart">图表 A</div>
    <div class="card chart">图表 B</div>
    <div class="card">通知</div>
    <div class="card stat">
      <div>销售额</div>
      <div style="color:var(--success)">+12%</div>
    </div>
    <div class="card stat">
      <div>错误率</div>
      <div style="color:var(--danger)">-8%</div>
    </div>
  </div>
</body>
</html>

14.4 可复用 UI 组件库开发 (按钮、卡片、模态框等)

核心技术

  • ✅ CSS 变量主题化
  • :focus-visible 键盘导航
  • role 语义化
  • ✅ BEM 命名规范
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <title>UI 组件库</title>
  <style>
    :root {
      --btn-primary-bg: #007acc;
      --btn-primary-hover: #005a99;
      --btn-danger-bg: #d32f2f;
      --border-radius: 4px;
      --gap: 0.5rem;
    }
    .btn {
      display: inline-flex;
      align-items: center;
      gap: var(--gap);
      padding: 0.5rem 1rem;
      border: none;
      border-radius: var(--border-radius);
      background: #f0f0f0;
      color: #333;
      font: inherit;
      cursor: pointer;
      transition: background 0.2s;
    }
    .btn:focus-visible {
      outline: 2px solid #007acc;
      outline-offset: 2px;
    }
    .btn--primary {
      background: var(--btn-primary-bg);
      color: white;
    }
    .btn--primary:hover {
      background: var(--btn-primary-hover);
    }
    .btn--danger {
      background: var(--btn-danger-bg);
      color: white;
    }
    .card {
      border: 1px solid #ddd;
      border-radius: var(--border-radius);
      padding: 1rem;
      margin: 1rem 0;
    }
    .modal {
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.5);
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 1rem;
    }
    .modal__content {
      background: white;
      padding: 1.5rem;
      border-radius: 8px;
      max-width: 500px;
      width: 100%;
    }
  </style>
</head>
<body>
  <!-- 按钮 -->
  <button class="btn btn--primary">主按钮</button>
  <button class="btn btn--danger">危险按钮</button>
  
  <!-- 卡片 -->
  <div class="card">
    <h3>卡片标题</h3>
    <p>卡片内容...</p>
  </div>
  
  <!-- 模态框 -->
  <div class="modal" role="dialog" aria-labelledby="modal-title">
    <div class="modal__content">
      <h2 id="modal-title">模态框</h2>
      <p>这是模态框内容</p>
      <button class="btn" onclick="this.parentElement.parentElement.remove()">关闭</button>
    </div>
  </div>
</body>
</html>

14.5 模仿 Dribbble 设计稿实现

核心技术

  • clip-path 创意形状
  • backdrop-filter 毛玻璃
  • scroll-snap 滑动体验
  • hsl() 动态颜色
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width"/>
  <title>Dribbble 风格</title>
  <style>
    * { 
      margin: 0; 
      padding: 0; 
      box-sizing: border-box; 
    }
    body {
      font-family: 'Arial', sans-serif;
      background: linear-gradient(135deg, #fbc2eb 0%, #a6c1ee 100%);
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .hero {
      width: 90%;
      max-width: 400px;
      aspect-ratio: 3 / 4;
      background: url('https://picsum.photos/400/533') center/cover;
      border-radius: 30px;
      position: relative;
      overflow: hidden;
      box-shadow: 0 10px 30px rgba(0,0,0,0.2);
    }
    .hero::before {
      content: '';
      position: absolute;
      inset: 0;
      background: linear-gradient(to top, 
        hsl(200, 50%, 20%) 30%, 
        transparent 80%
      );
    }
    .hero-content {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      padding: 1.5rem;
      color: white;
      backdrop-filter: blur(4px);
      -webkit-backdrop-filter: blur(4px);
    }
    .tag {
      display: inline-block;
      padding: 0.3rem 0.8rem;
      background: rgba(255,255,255,0.2);
      border-radius: 20px;
      font-size: 0.8rem;
      margin-right: 0.5rem;
    }
    .cta {
      margin-top: 1rem;
      display: flex;
      gap: 1rem;
    }
    .btn-round {
      width: 40px;
      height: 40px;
      border-radius: 50%;
      background: white;
      color: #333;
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: bold;
      clip-path: polygon(40% 0%, 70% 50%, 40% 100%, 0% 75%, 0% 25%);
    }
  </style>
</head>
<body>
  <div class="hero">
    <div class="hero-content">
      <div>
        <span class="tag">设计</span>
        <span class="tag">灵感</span>
      </div>
      <h2>创意无限</h2>
      <p>探索前沿视觉设计趋势</p>
      <div class="cta">
        <button class="btn-round">→</button>
        <span>了解更多</span>
      </div>
    </div>
  </div>
</body>
</html>

附录

A. CSS 属性速查表

一、布局(Layout)

属性值示例说明
displayflex, grid, block, inline-block, none设置元素显示模式
positionstatic, relative, absolute, fixed, sticky定位方式
floatleft, right, none浮动(已不推荐用于布局)
clearboth, left, right清除浮动
z-index1, auto, -1层叠顺序(需配合定位使用)

Flexbox

属性(容器)

属性值示例说明
flex-directionrow, column, row-reverse主轴方向
justify-contentcenter, space-between, flex-start主轴对齐
align-itemscenter, flex-start, stretch交叉轴对齐
flex-wrapnowrap, wrap, wrap-reverse是否换行

属性(项目)

属性值示例说明
flex1, 0 1 auto, 2 1 100px缩写:flex-grow flex-shrink flex-basis
align-selfcenter, flex-end单个项目对齐
order1, -1排序(可改变视觉顺序)

Grid

属性(容器)

属性值示例说明
grid-template-columns1fr 2fr, repeat(3, 1fr)列定义
grid-template-rows100px auto, minmax(100px, 1fr)行定义
gap1rem, 10px 20px网格间距(行与列)
grid-auto-flowrow, column, dense自动放置算法
justify-itemsstart, center, stretch内容在单元格中水平对齐
align-itemsstart, center, stretch内容在单元格中垂直对齐

属性(项目)

属性值示例说明
grid-column1 / 3, span 2跨列
grid-row2 / 4跨行
grid-areaheader, 1 / 1 / 3 / 2区域名称或位置
justify-selfcenter, end单个项目水平对齐
align-selfcenter, start单个项目垂直对齐

二、盒模型(Box Model)

属性值示例说明
width / height200px, 50%, fit-content, max-content尺寸
max-width / max-height800px, none最大尺寸
min-width / min-height300px最小尺寸
margin10px, auto, 1rem 0外边距(可设 auto 实现居中)
padding20px, 1rem 2rem内边距
border1px solid #ccc, 2px dashed red边框
border-radius8px, 50%, 10px 20px 30px 40px圆角
box-sizingcontent-box, border-box盒模型计算方式(推荐全局设为 border-box)
overflowvisible, hidden, scroll, auto溢出处理

三、文本与字体(Text & Font)

属性值示例说明
font-family'Arial', 'Segoe UI', system-ui字体族
font-size16px, 1rem, 1.2em字号(推荐使用 rem)
font-weight400, 700, bold字重
font-stylenormal, italic字体样式
line-height1.5, 1.2, 24px行高(推荐无单位)
text-alignleft, center, right, justify文本对齐
text-transformuppercase, lowercase, capitalize文本转换
text-decorationnone, underline, line-through文本装饰
white-spacenormal, nowrap, pre-line, pre-wrap空白处理
word-breakbreak-all, keep-all换行策略
color#333, rgb(255,0,0), hsl(120, 100%, 50%), var(--primary)文本颜色

四、背景与边框(Background & Border)

属性值示例说明
background-color#f0f0f0, transparent背景颜色
background-imageurl('bg.jpg'), linear-gradient(...)背景图像
background-repeatno-repeat, repeat-x重复方式
background-positioncenter, top right, 50% 50%位置
background-sizecover, contain, 100% 100%尺寸
background-attachmentscroll, fixed滚动行为
border-imageurl(border.png) 30 stretch图像边框
box-shadow0 2px 4px rgba(0,0,0,0.1)盒阴影(可多重)
clip-pathcircle(50%), polygon(0 0, 100% 0, 50% 100%)裁剪路径(创意形状)
backdrop-filterblur(10px), brightness(70%)背后滤镜(毛玻璃效果)

五、变换、过渡与动画(Transform, Transition, Animation)

属性值示例说明
transformtranslate(10px, 20px), rotate(45deg), scale(1.2)2D/3D 变换
transform-origincenter, top left变换原点
transitionall 0.3s ease, opacity 0.2s过渡效果(缩写)
transition-propertycolor, background过渡属性
transition-duration0.5s, 300ms持续时间
transition-timing-functionease, linear, cubic-bezier(.42,-0.61,.58,1.4)缓动函数
animationfade 1s infinite ease-in-out动画缩写
@keyframesfrom { opacity: 0; } to { opacity: 1; }定义关键帧动画

六、响应式与媒体查询

属性/规则示例说明
@media@media (min-width: 768px) { ... }媒体查询
常用断点576px, 768px, 992px, 1200px移动优先
orientation(orientation: portrait)设备方向
prefers-color-scheme(prefers-color-scheme: dark)暗黑模式检测
aspect-ratio@media (min-aspect-ratio: 16/9)宽高比查询
container-typeinline-size, size启用容器查询
@container@container (min-width: 300px) { ... }容器查询规则

七、其他实用属性

属性值示例说明
cursorpointer, move, not-allowed鼠标指针样式
visibilityvisible, hidden是否可见(保留空间)
opacity0.5, 1透明度(0 = 完全透明)
filterblur(5px), grayscale(100%), drop-shadow()图像滤镜
pointer-eventsauto, none是否响应鼠标事件(常用于穿透点击)
user-selectnone, text是否允许用户选中文本
scroll-behaviorsmooth平滑滚动(设于 html)
scroll-margin / scroll-padding10px锚点滚动偏移
isolationisolate创建层叠上下文(替代 opacity: 0.99 黑科技)
containlayout, paint, strict提升性能(限制重排重绘范围)

八、CSS 自定义属性(变量)

:root {
  --primary-color: #007acc;
  --spacing: 1rem;
  --border-radius: 4px;
}

.component {
  color: var(--primary-color);
  padding: var(--spacing);
  border-radius: var(--border-radius);
}

使用 var(--name, fallback) 提供默认值

九、无障碍(Accessibility)基础

属性说明
:focus-visible仅在键盘聚焦时显示轮廓
outlinenone(慎用!应替换为自定义焦点样式)
aria-*aria-label, aria-hidden 等辅助技术属性
rolebutton, dialog, navigation 等语义角色

十、推荐全局重置

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

body {
  margin: 0;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

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

input,
button,
textarea,
select {
  font: inherit;
}

B. 选择器优先级计算表

一、优先级计算模型:a-b-c-d 四元组

位数含义可用选择器类型计分方式
a!important唯一来源:!important 声明每出现一次 !important(且在声明末尾),a = 1,否则 a = 0
bID 选择器#header, #nav每个 ID 选择器 +1
c类/属性/伪类.btn, [type="text"], :hover, :nth-child(2)每个此类选择器 +1
d元素/伪元素div, p, ::before, ::first-line每个元素或伪元素 +1

📌 比较规则:从左到右逐位比较(如 0-1-0-0 > 0-0-99-99)

二、优先级计算速查表(示例)

CSS 选择器a (important)b (ID)c (类/属性/伪类)d (元素/伪元素)优先级值
p00010-0-0-1
.intro00100-0-1-0
p.intro00110-0-1-1
#main01000-1-0-0
div#content p.highlight01120-1-1-2
[href]00100-0-1-0
:hover00100-0-1-0
:nth-child(odd)00100-0-1-0
::before00010-0-0-1
.nav li.active:hover00310-0-3-1
#sidebar .widget:nth-of-type(2)01200-1-2-0
body #app .btn[disabled]:focus01310-1-3-1
*(通配符)00000-0-0-0
div *00010-0-0-1
a:hover::after00120-0-1-2

三、!important 的特殊处理

声明是否计入 a说明
color: red !important;✅ 是a = 1
color: red!important;✅ 是空格可省略
color: red ; important❌ 否语法错误,不生效
!important 在变量中?❌ 否--color: red !important; 不合法

⚠️ 注意

  • !important 打破正常优先级规则,仅被更高优先级的 !important 覆盖
  • 内联样式中的 !important 仍计入 a
  • 建议:仅用于调试或第三方库覆盖,避免滥用

四、特殊选择器优先级说明

选择器优先级说明
:where()0-0-0-0零优先级,用于重置优先级
:is()正常计算取括号内最高优先级
:not()正常计算包含的选择器参与计分
:has()正常计算支持较新(Chrome 105+)
内联样式 style=""0-1-0-0相当于一个 ID(但无 ID 语义)
@layer分层控制层次顺序 > 优先级 > 源码顺序

五、实战计算练习

示例 1:谁的字体颜色生效?

/* A */
#main .text {
  color: blue;
}

/* B */
div.container p.text {
  color: red;
}
选择器bcd优先级
#main .text1100-1-1-0
div.container p.text0220-0-2-2

结果:blue 生效(0-1-1-0 > 0-0-2-2)

示例 2::is():where()

:is(#nav, .sidebar) p {
  color: green;
}

.sidebar p {
  color: yellow;
}
  • :is(#nav, .sidebar) 的优先级 = 0-1-0-0(取 #nav 的高优先级)
  • .sidebar p = 0-0-1-1
  • ✅ green 生效
:where(#nav, .sidebar) p {
  color: purple;
}
  • :where(...) 优先级 = 0-0-0-0
  • ✅ purple 不会生效(低于 .sidebar p

六、优先级避坑指南

陷阱解决方案
过度使用 !important使用更具体的选择器替代
ID 选择器滥用改用类名(.header 替代 #header
层层嵌套提升优先级使用 BEM 命名,避免深层嵌套
第三方样式冲突使用 :where()@layer 隔离
通配符重置影响布局使用 *, *::before, *::after { box-sizing: border-box; } 安全重置

七、推荐开发策略

  • 优先级排序!important > 内联样式 > ID > 类/属性/伪类 > 元素 > 通配符
  • 设计系统建议
    • 全局使用 class,避免 ID 选择器
    • 使用 BEM 命名法(如 .btn__icon--large)提升可读性
    • 利用 CSS Custom Properties 实现主题切换
    • 使用 @layer 组织样式层级(基础 → 组件 → 主题)
  • 调试技巧
    • 浏览器 DevTools 中查看”Computed”面板,观察样式来源
    • 使用 specificity calculator 在线工具验证

📌 总结口诀

四个数字比大小,从左到右不能跳。 ID 最狠值一分,类属伪类紧相随。 标签伪元排最后,通配清零全靠它。 !important 插队王,能破天规但别狂。

C. 常用媒体查询断点参考

一、通用响应式断点(推荐)

设备类型最小宽度 (min-width)最大宽度 (max-width)CSS 示例
手机(竖屏)-575px@media (max-width: 575px)
手机(横屏)/ 小平板576px767px@media (min-width: 576px)
平板(竖屏)768px991px@media (min-width: 768px)
桌面(小屏)992px1199px@media (min-width: 992px)
桌面(大屏)1200px-@media (min-width: 1200px)

此方案与 Bootstrap 5 断点一致,广泛采用。

二、断点代码模板(移动优先)

/* 1. 默认样式(手机竖屏) */
.container {
  padding: 1rem;
  font-size: 16px;
}

/* 2. 小平板 / 手机横屏 */
@media (min-width: 576px) {
  .container {
    max-width: 540px;
    margin: 0 auto;
  }
}

/* 3. 平板(竖屏) */
@media (min-width: 768px) {
  .container {
    max-width: 720px;
  }
  .grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
  }
}

/* 4. 桌面(小屏) */
@media (min-width: 992px) {
  .container {
    max-width: 960px;
  }
  .grid {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

/* 5. 桌面(大屏) */
@media (min-width: 1200px) {
  .container {
    max-width: 1140px;
  }
  .hero-text {
    font-size: 2rem;
  }
}

三、常见框架断点对比

框架超小 (xs)小 (sm)中 (md)大 (lg)超大 (xl)说明
Bootstrap 5&lt;576px&gt;=576px&gt;=768px&gt;=992px&gt;=1200px最广泛使用
Tailwind CSSsm:640pxmd:768pxlg:1024pxxl:1280px2xl:1536px略有偏移
Material Design&lt;600px&gt;=600px&gt;=960px&gt;=1280px&gt;=1920pxGoogle 设计规范
自定义常用&lt;768px&gt;=768px&gt;=1024px&gt;=1200px&gt;=1440px简化版,适合内容站

📊 建议:初学者可直接采用 Bootstrap 5 断点,兼容性好,社区资源丰富。

四、方向(Orientation)媒体查询

/* 竖屏(Portrait) */
@media (orientation: portrait) {
  .hero {
    height: 80vh;
  }
}

/* 横屏(Landscape) */
@media (orientation: landscape) {
  .hero {
    height: 50vh;
  }
}

📱 适用于移动端,控制不同方向的布局表现。

五、高分辨率与暗黑模式

/* 高分辨率屏幕(Retina) */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .logo {
    background-image: url('logo@2x.png');
  }
}

/* 暗黑模式 */
@media (prefers-color-scheme: dark) {
  body {
    background: #121212;
    color: #eee;
  }
}

/* 打印样式 */
@media print {
  .no-print {
    display: none;
  }
  body {
    font-size: 12pt;
  }
}

六、容器查询(Container Queries)——未来趋势

适用于组件级响应式,不依赖视口

.widget {
  container-type: inline-size;
  container-name: sidebar;
}

/* 当容器宽度 ≥ 300px 时 */
@container sidebar (min-width: 300px) {
  .widget {
    display: flex;
    gap: 1rem;
  }
}

⚠️ 注意:需检查浏览器支持(Chrome 105+,Firefox 110+)

七、断点设置最佳实践

建议说明
✅ 使用 min-width移动优先,避免样式覆盖混乱
✅ 用 rem 定义断点(min-width: 48rem),与字体大小联动,更灵活
❌ 避免 device-widthdevice-width: 375px,已被弃用,不可靠
✅ 基于内容设置断点在浏览器中缩放页面,观察布局何时”断裂”,在此处加断点
✅ 命名断点变量提升可维护性
/* 推荐:使用 CSS 变量命名断点 */
:root {
  --breakpoint-sm: 576px;
  --breakpoint-md: 768px;
  --breakpoint-lg: 992px;
  --breakpoint-xl: 1200px;
}

@media (min-width: var(--breakpoint-md)) {
  /* 平板以上样式 */
}

八、常见设备分辨率参考

设备典型分辨率适用断点
iPhone SE375 × 667max-width: 575px
iPhone 14393 × 852max-width: 575px
iPad (竖屏)768 × 1024min-width: 768px
iPad Pro (横屏)1024 × 1366min-width: 992px
普通笔记本1366 × 768min-width: 992px
2K / 4K 显示器2560×1440 / 3840×2160min-width: 1200px

🔍 注意:CSS 像素 ≠ 物理像素(Retina 屏幕有缩放)

📌 总结

“没有最好的断点,只有最适合你设计的断点。” 从 移动优先 开始, 用 内容断裂点 定义响应, 借助 主流断点参考 快速起步, 最终实现真正自适应的用户体验。

将此表作为项目模板,快速构建响应式布局!