CSS 知识详解
从层叠规则到现代布局,从自定义属性到容器查询,系统梳理 CSS 全栈知识,涵盖 W3C 2025 最新特性,助你写出优雅、高性能的样式代码。
目录
- 什么是 CSS
- 语法与引入方式
- 层叠与继承
- 选择器优先级
- CSS 选择器大全
- 伪类与伪元素
- CSS 盒模型
- Display 与定位
- Flexbox 弹性布局
- Grid 网格布局
- 字体与文本
- 颜色与背景
- 变换与过渡
- CSS 动画
- 自定义属性(变量)
- 响应式设计
- 现代 CSS 特性
- 最佳实践
一、什么是 CSS
CSS(Cascading Style Sheets,层叠样式表)是用于描述 HTML 文档视觉呈现的语言。它与 HTML(结构)、JavaScript(行为)共同构成 Web 三层架构的样式层。
三大核心机制
| 机制 | 说明 |
|---|---|
| 层叠 Cascade | 多个来源的样式规则按特定算法合并,优先级高的规则覆盖低的 |
| 继承 Inherit | 部分属性(如 font、color)会从父元素传递给子元素,减少重复代码 |
| 特异性 Specificity | ID > 类/属性/伪类 > 标签/伪元素,数值越高优先级越高 |
📋 W3C CSS Snapshot 2025: W3C 每年发布 CSS 快照文档,汇总当前所有稳定的 CSS 模块规范。CSS 已从单一规范演进为 50+ 独立模块,浏览器实现程度各异。
二、语法与引入方式
基本语法
1/* 选择器 { 属性: 值; } */ 2 3h1 { 4 color: tomato; 5 font-size: 2rem; 6 margin-bottom: 16px; 7} 8 9/* 分组选择器 */ 10h1, h2, h3 { 11 font-family: serif; 12} 13 14/* @规则 */ 15@media (max-width: 768px) { 16 h1 { font-size: 1.5rem; } 17} 18
四种引入方式
1<!-- ① 外部样式表(推荐):放在 <head> 中 --> 2<link rel="stylesheet" href="style.css" /> 3 4<!-- ② 内部样式:放在 <style> 标签中 --> 5<style> 6 body { margin: 0; } 7</style> 8 9<!-- ③ 内联样式:直接写在元素 style 属性上(最高优先级,不推荐滥用) --> 10<p style="color: red; font-size: 14px;">文字</p> 11
1/* ④ @import:在 CSS 文件中引入另一个 CSS(会阻塞渲染,慎用)*/ 2@import url('variables.css'); 3
✅ 最佳实践: 优先使用外部样式表,利用浏览器缓存。将关键 CSS(首屏必需的少量样式)内联到
<head>以提升 LCP 指标,其余通过<link rel="preload">异步加载。
三、层叠(Cascade)与继承
样式来源优先级(从高到低)
| 优先级 | 来源 | 说明 |
|---|---|---|
| 最高 | 用户 !important | 用户代理或用户浏览器设置,极少见 |
| ↑ | 作者 !important | 开发者在 CSS 中声明的 !important |
| ↑ | 动画样式 | CSS Animation 动画过程中的计算值 |
| ↑ | 作者普通样式 | 开发者编写的普通 CSS 规则(最常用) |
| ↑ | 用户普通样式 | 用户自定义浏览器样式 |
| 最低 | 浏览器默认样式 | User-Agent Stylesheet,如 h1 默认 font-size |
@layer 层叠层(CSS 2022+)
1/* 定义层叠层,后定义的层优先级更高 */ 2@layer reset, base, components, utilities; 3 4@layer reset { 5 * { box-sizing: border-box; margin: 0; } 6} 7 8@layer components { 9 .btn { padding: 8px 16px; } 10} 11 12@layer utilities { 13 .p-4 { padding: 1rem; } /* utilities 层优先级最高 */ 14} 15
可继承属性 vs 不可继承属性
| 可继承属性(举例) | 不可继承属性(举例) |
|---|---|
| color、font-*、line-height、text-align、letter-spacing、word-spacing、visibility、cursor、list-style | margin、padding、border、background、width、height、display、position、float、box-shadow |
继承控制关键字
1.child { 2 color: inherit; /* 强制继承父元素的值 */ 3 color: initial; /* 重置为浏览器默认初始值 */ 4 color: unset; /* 可继承属性→inherit;不可继承→initial */ 5 color: revert; /* 回退到浏览器默认样式(UA stylesheet)*/ 6 7 /* all 简写:一次性重置/继承所有属性 */ 8 all: revert; 9} 10
四、选择器优先级(Specificity)
优先级用三位数 (A, B, C) 表示,从左到右逐位比较,数字越大优先级越高。
| 选择器 | A(ID) | B(类/属性/伪类) | C(标签/伪元素) | 说明 |
|---|---|---|---|---|
| * { } | 0 | 0 | 0 | 通配符,无权重 |
| div { } | 0 | 0 | 1 | 标签选择器 |
| .btn { } | 0 | 1 | 0 | 类选择器 |
| div.btn:hover { } | 0 | 2 | 1 | 类 + 伪类 + 标签 |
| #header .nav a { } | 1 | 1 | 1 | ID + 类 + 标签 |
| style="..." | — | — | — | 内联样式,约等于 1000 |
| !important | — | — | — | 覆盖一切(谨慎使用) |
⚠️ 避免 !important: 过度使用会导致样式无法维护。正确做法是提升选择器特异性或使用 CSS
@layer管理优先级顺序。
注意::where()伪类的特异性永远为 0,:is()的特异性取其参数中最高的那个。
五、CSS 选择器大全
基础选择器
| 选择器 | 说明 |
|---|---|
| * | 通配选择器,匹配所有元素(权重为 0) |
| div | 类型/标签选择器,匹配指定标签名的所有元素 |
| .class | 类选择器,匹配拥有该 class 的元素,可叠加 .a.b |
| #id | ID 选择器,匹配 id 属性值的元素,页面内唯一 |
| [attr] | 属性选择器,见下方详细列表 |
组合选择器
1A B { /* 后代选择器:A 内部所有 B(含嵌套)*/ } 2A > B { /* 子代选择器:A 的直接子元素 B */ } 3A + B { /* 相邻兄弟:紧接在 A 后的第一个 B */ } 4A ~ B { /* 通用兄弟:A 后所有的 B(同级)*/ } 5A, B { /* 分组:A 和 B 都应用同一规则 */ } 6
属性选择器
1[href] { /* 存在 href 属性 */ } 2[type="text"] { /* 属性值精确匹配 */ } 3[class~="btn"] { /* 属性值列表中含 btn(空格分隔)*/ } 4[lang|="zh"] { /* 值等于 zh 或以 zh- 开头 */ } 5[href^="https"] { /* 值以 https 开头 */ } 6[href$=".pdf"] { /* 值以 .pdf 结尾 */ } 7[title*="CSS"] { /* 值中包含 CSS */ } 8[class*="btn" i] { /* i 标志:不区分大小写 */ } 9
现代函数式选择器
1/* :is() — 匹配列表中任意选择器,权重取最高 */ 2:is(h1, h2, h3) { margin-top: 24px; } 3 4/* :where() — 同 :is(),但权重恒为 0 */ 5:where(article, section) p { line-height: 1.8; } 6 7/* :not() — 排除匹配的元素 */ 8li:not(:last-child) { border-bottom: 1px solid #eee; } 9 10/* :has() — 父选择器 ⭐ CSS 2023+ 全浏览器支持 */ 11/* 含有 img 子元素的 figure 加圆角 */ 12figure:has(img) { border-radius: 8px; overflow: hidden; } 13 14/* 含有 :invalid 输入框的 form 高亮边框 */ 15form:has(input:invalid) { 16 border-color: red; 17} 18 19/* 表格列悬停效果(JS 无法做到的 CSS 魔法)*/ 20td:has(+ td:hover) { background: lightyellow; } 21
六、伪类与伪元素
常用伪类
| 伪类 | 触发条件 | 常见用途 |
|---|---|---|
| :hover | 鼠标悬停 | 按钮/链接交互状态 |
| :focus | 键盘/点击获得焦点 | 表单元素焦点样式 |
| :focus-visible | 键盘导航获焦(推荐) | 仅对键盘用户显示焦点轮廓 |
| :active | 鼠标按下期间 | 按钮点击反馈 |
| :visited | 已访问的链接 | 链接颜色区分 |
| :checked | checkbox/radio 被选中 | 自定义表单样式 |
| :disabled | 表单元素被禁用 | 禁用状态样式 |
| :valid / :invalid | 表单验证状态 | 实时校验视觉反馈 |
| :placeholder-shown | placeholder 可见时 | 浮动 label 效果 |
| :empty | 没有子元素(含文本) | 隐藏空容器 |
| :is() / :where() | 参数中任意匹配 | 简化复杂选择器 |
| :has() | 包含指定后代 | 父选择器逻辑 |
结构性伪类(nth 系列)
1li:first-child { /* 第一个子元素 */ } 2li:last-child { /* 最后一个 */ } 3li:only-child { /* 唯一子元素 */ } 4li:nth-child(2) { /* 第 2 个 */ } 5li:nth-child(odd) { /* 奇数行 */ } 6li:nth-child(even) { /* 偶数行(斑马纹)*/ } 7li:nth-child(3n+1) { /* 1, 4, 7, 10… 每 3 个选第 1 个 */ } 8li:nth-last-child(2) { /* 从末尾数第 2 个 */ } 9 10/* ⭐ :nth-child of type — CSS 2023+ */ 11li:nth-child(2 of .selected) { 12 /* 第 2 个含 .selected 类的 li */ 13} 14
伪元素(使用双冒号 ::)
1/* ::before / ::after — 内容前后插入虚拟元素 */ 2.icon::before { 3 content: '🔥'; /* content 必须设置,哪怕为空 '' */ 4 display: inline-block; 5} 6 7/* ::first-line — 首行文字 */ 8p::first-line { font-weight: bold; } 9 10/* ::first-letter — 首字母(下沉效果)*/ 11p::first-letter { 12 float: left; 13 font-size: 3em; 14 line-height: 1; 15 margin-right: 0.1em; 16} 17 18/* ::selection — 用户选中的文字 */ 19::selection { background: #ffd700; color: #000; } 20 21/* ::placeholder — input 占位符 */ 22input::placeholder { color: #aaa; font-style: italic; } 23 24/* ::marker — li 的项目符号 */ 25li::marker { color: tomato; font-size: 1.2em; } 26 27/* ::backdrop — 全屏/dialog 背景遮罩 */ 28dialog::backdrop { background: rgba(0,0,0,.5); } 29
七、CSS 盒模型(Box Model)
每个 HTML 元素都被视为一个矩形盒子,由四个区域从外到内组成:
1┌─────────────────────────────────────┐ 2│ Margin(外边距) │ 3│ ┌───────────────────────────────┐ │ 4│ │ Border(边框) │ │ 5│ │ ┌─────────────────────────┐ │ │ 6│ │ │ Padding(内边距) │ │ │ 7│ │ │ ┌───────────────────┐ │ │ │ 8│ │ │ │ Content(内容区) │ │ │ │ 9│ │ │ └───────────────────┘ │ │ │ 10│ │ └─────────────────────────┘ │ │ 11│ └───────────────────────────────┘ │ 12└─────────────────────────────────────┘ 13
box-sizing 对比
1/* 默认:content-box — width 仅指内容区 */ 2.box { 3 box-sizing: content-box; /* 实际占宽 = width + padding + border */ 4 width: 200px; 5 padding: 20px; 6 border: 2px solid black; /* 总宽 = 244px */ 7} 8 9/* 推荐:border-box — width 包含 padding 和 border */ 10.box { 11 box-sizing: border-box; /* 实际占宽 = width = 200px */ 12 width: 200px; 13 padding: 20px; 14 border: 2px solid black; /* 内容区 = 200 - 40 - 4 = 156px */ 15} 16 17/* 全局最佳实践 */ 18*, *::before, *::after { 19 box-sizing: border-box; 20} 21
Margin 折叠
⚠️ 外边距折叠(Margin Collapse): 垂直方向相邻的
margin会发生折叠,取两者中较大值而非相加。
折叠发生条件:① 相邻兄弟元素 ② 父子元素(父无 border/padding/BFC 时)③ 空元素(自身 margin-top 和 margin-bottom)。
BFC、Flex/Grid 容器内部不会发生折叠。
八、Display 与定位(Position)
display 属性
| 值 | 特性 | 典型元素 |
|---|---|---|
| block | 独占一行,可设宽高 | div, p, h1-h6 |
| inline | 不换行,不可设宽高 | span, a, em |
| inline-block | 不换行,可设宽高 | button, img |
| none | 隐藏,不占空间 | — |
| flex | 弹性容器 | 详见 Flexbox 章节 |
| grid | 网格容器 | 详见 Grid 章节 |
| contents | 元素本身不渲染盒子,子元素正常显示 | 辅助无障碍场景 |
| table 系列 | 模拟表格布局 | table / table-cell 等 |
position 定位
1/* static — 默认,不偏移,top/left 无效 */ 2.box { position: static; } 3 4/* relative — 相对自身原位置偏移,不脱流 */ 5.box { 6 position: relative; 7 top: 10px; left: 20px; /* 原位置占位保留 */ 8} 9 10/* absolute — 相对最近的 positioned 祖先定位,脱流 */ 11.popup { 12 position: absolute; 13 top: 0; right: 0; /* 找最近的 relative/absolute/fixed 父 */ 14} 15 16/* fixed — 相对视口定位,滚动不移动 */ 17.navbar { 18 position: fixed; 19 top: 0; left: 0; right: 0; 20} 21 22/* sticky — 滚动到阈值前是 relative,之后是 fixed */ 23.section-header { 24 position: sticky; 25 top: 60px; /* 距视口顶部 60px 时"吸附" */ 26} 27 28/* z-index — 控制层叠顺序(仅对非 static 有效)*/ 29.modal { position: fixed; z-index: 1000; } 30
九、Flexbox 弹性布局
Flexbox 是一维布局模型,擅长在行或列方向上分配空间、对齐元素。
容器属性(父元素 display: flex)
1.container { 2 display: flex; /* 或 inline-flex */ 3 4 /* 主轴方向 */ 5 flex-direction: row; /* row | row-reverse | column | column-reverse */ 6 7 /* 换行 */ 8 flex-wrap: wrap; /* nowrap | wrap | wrap-reverse */ 9 10 /* flex-flow 简写 */ 11 flex-flow: row wrap; 12 13 /* 主轴对齐(水平,当 direction=row)*/ 14 justify-content: flex-start; /* flex-start|flex-end|center|space-between|space-around|space-evenly */ 15 16 /* 交叉轴对齐(垂直)*/ 17 align-items: stretch; /* stretch|flex-start|flex-end|center|baseline */ 18 19 /* 多行交叉轴对齐(wrap 时有效)*/ 20 align-content: flex-start; 21 22 /* 子项间距 */ 23 gap: 16px; 24 row-gap: 12px; 25 column-gap: 24px; 26} 27
子项属性(Flex Item)
1.item { 2 /* flex-grow: 剩余空间分配比例(0=不扩张)*/ 3 flex-grow: 1; 4 5 /* flex-shrink: 空间不足时收缩比例(0=不收缩)*/ 6 flex-shrink: 1; 7 8 /* flex-basis: 初始尺寸,优先级高于 width */ 9 flex-basis: 200px; 10 11 /* flex 简写 = grow shrink basis */ 12 flex: 1 1 auto; /* flex: 1 等于 1 1 0% */ 13 flex: none; /* 0 0 auto — 不伸缩 */ 14 15 /* align-self: 覆盖容器的 align-items */ 16 align-self: center; 17 18 /* order: 显示顺序(默认 0,越小越前)*/ 19 order: -1; 20} 21 22/* 经典垂直居中 */ 23.center { 24 display: flex; 25 justify-content: center; 26 align-items: center; 27} 28
十、CSS Grid 网格布局
Grid 是二维布局模型,同时控制行和列,适合复杂页面级布局。
1.grid { 2 display: grid; 3 4 /* 定义列:3列,各占 1 份 */ 5 grid-template-columns: 1fr 1fr 1fr; 6 7 /* 定义列:repeat + minmax — 响应式神器 */ 8 grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); 9 10 /* 显式行高 */ 11 grid-template-rows: 80px auto 60px; 12 13 /* 命名区域布局 */ 14 grid-template-areas: 15 "header header header" 16 "sidebar main main" 17 "footer footer footer"; 18 19 /* 间距 */ 20 gap: 20px 16px; /* row-gap column-gap */ 21 22 /* 对齐 */ 23 justify-items: stretch; /* 子项在列轴对齐 */ 24 align-items: stretch; /* 子项在行轴对齐 */ 25 place-items: center; /* align + justify 简写 */ 26} 27 28/* Grid Item 属性 */ 29.header { 30 grid-area: header; /* 引用命名区域 */ 31} 32 33.banner { 34 /* 跨列:从第 1 条线到第 3 条线(占 2 列)*/ 35 grid-column: 1 / 3; 36 grid-column: 1 / span 2; /* 等价写法 */ 37 grid-row: 1 / 3; 38} 39 40/* 隐式网格控制 */ 41.grid { 42 grid-auto-rows: minmax(100px, auto); 43 grid-auto-flow: dense; /* 自动填充空洞 */ 44} 45
💡 Flexbox vs Grid 选择原则:
- Flexbox:一维排列(导航栏、卡片行、对齐按钮组)
- Grid:二维布局(页面骨架、图片墙、仪表盘)
- 两者可以嵌套使用:Grid 构建大布局,Flex 处理组件内部对齐。
十一、字体与文本
1body { 2 /* 字体栈:优先使用第一个,逐级回退 */ 3 font-family: 'Noto Sans SC', '微软雅黑', sans-serif; 4 5 font-size: 16px; /* 基准字号 */ 6 font-weight: 400; /* 100-900,400=normal,700=bold */ 7 font-style: normal; /* normal | italic | oblique */ 8 line-height: 1.6; /* 行高,推荐无单位(相对于字号)*/ 9 letter-spacing: 0.02em; /* 字符间距 */ 10 word-spacing: 0.1em; /* 单词间距 */ 11 12 /* font 简写 */ 13 font: italic bold 16px/1.6 'Noto Sans SC', sans-serif; 14} 15 16p { 17 text-align: left; /* left|right|center|justify */ 18 text-indent: 2em; /* 首行缩进 */ 19 text-decoration: none; /* underline|line-through|overline */ 20 text-transform: uppercase; /* uppercase|lowercase|capitalize */ 21 white-space: nowrap; /* 禁止换行 */ 22 23 /* 单行溢出省略号 */ 24 overflow: hidden; 25 text-overflow: ellipsis; 26 white-space: nowrap; 27 28 /* 多行省略(CSS 2023 正式标准)*/ 29 display: -webkit-box; 30 -webkit-line-clamp: 3; 31 -webkit-box-orient: vertical; 32 overflow: hidden; 33} 34 35/* ⭐ text-wrap: balance — 标题换行均衡(2023+)*/ 36h1, h2, h3 { 37 text-wrap: balance; /* 每行字数尽量均匀,避免孤行 */ 38} 39 40/* Web 字体加载 */ 41@font-face { 42 font-family: 'MyFont'; 43 src: url('font.woff2') format('woff2'); 44 font-display: swap; /* 防止 FOIT:先显示备用字体 */ 45 font-weight: 100 900; /* 可变字体范围 */ 46} 47
十二、颜色与背景
颜色表示方式
1.colors { 2 /* 关键字 */ 3 color: tomato; 4 color: transparent; 5 color: currentColor; /* 继承当前 color 值 */ 6 7 /* HEX */ 8 color: #ff6347; /* RGB */ 9 color: #ff634780; /* RGBA(最后2位为透明度)*/ 10 11 /* RGB */ 12 color: rgb(255 99 71); /* 现代无逗号语法 */ 13 color: rgb(255 99 71 / 0.5); /* 50% 透明度 */ 14 15 /* HSL(更直观)*/ 16 color: hsl(9 100% 64%); 17 color: hsl(9 100% 64% / 0.8); 18 19 /* ⭐ OKLCH — 感知均匀颜色空间(2024+ 推荐)*/ 20 color: oklch(65% 0.2 30); /* 亮度 色度 色相 */ 21 22 /* ⭐ 相对颜色语法(CSS 2024+ 全浏览器)*/ 23 color: oklch(from var(--brand) calc(l + 0.1) c h); 24 25 /* ⭐ light-dark() — 自动适应深色/浅色模式 */ 26 color: light-dark(#000, #fff); 27} 28
背景属性
1.box { 2 background-color: #f0f0f0; 3 background-image: url('bg.jpg'); 4 background-repeat: no-repeat; /* repeat|repeat-x|repeat-y|no-repeat */ 5 background-size: cover; /* cover|contain|100% auto */ 6 background-position: center; /* center|top left|50% 50% */ 7 background-attachment: fixed; /* scroll|fixed|local */ 8 background-origin: border-box; 9 background-clip: text; /* 渐变文字效果 */ 10 11 /* 渐变背景 */ 12 background: linear-gradient(135deg, #667eea, #764ba2); 13 background: radial-gradient(circle at center, #fff, #000); 14 background: conic-gradient(from 0deg, red, yellow, green); 15 16 /* 多背景叠加 */ 17 background: 18 url('icon.svg') top right no-repeat, 19 linear-gradient(#f5f5f5, #fff); 20} 21 22/* 渐变文字 */ 23.gradient-text { 24 background: linear-gradient(90deg, #f093fb, #f5576c); 25 -webkit-background-clip: text; 26 background-clip: text; 27 color: transparent; 28} 29
十三、变换(Transform)与过渡(Transition)
transform 变换函数
1.el { 2 /* 位移 */ 3 transform: translateX(20px); 4 transform: translate(20px, -10px); 5 6 /* 缩放 */ 7 transform: scale(1.2); /* 等比放大 1.2 倍 */ 8 transform: scaleX(2) scaleY(0.5); 9 10 /* 旋转 */ 11 transform: rotate(45deg); 12 transform: rotateX(60deg); /* 3D 旋转 */ 13 14 /* 倾斜 */ 15 transform: skew(20deg, 5deg); 16 17 /* 组合变换(从右到左执行)*/ 18 transform: translateY(-50%) rotate(30deg) scale(1.1); 19 20 /* 变换原点 */ 21 transform-origin: top left; /* 默认 center */ 22 23 /* 3D 透视 */ 24 perspective: 800px; 25 transform-style: preserve-3d; 26} 27
transition 过渡
1.btn { 2 background: #3b82f6; 3 transform: scale(1); 4 5 /* transition: property duration timing-function delay */ 6 transition: background .3s ease, 7 transform .2s cubic-bezier(0.34,1.56,0.64,1); 8} 9 10.btn:hover { 11 background: #2563eb; 12 transform: scale(1.05); 13} 14 15/* 16 timing functions: 17 ease | linear | ease-in | ease-out | ease-in-out 18 cubic-bezier(x1,y1,x2,y2) 19 steps(4, end) — 分步动画(如精灵图动画) 20*/ 21 22/* ⭐ CSS 2024: transition-behavior — 支持 display 过渡 */ 23.modal { 24 transition: opacity .3s, display .3s; 25 transition-behavior: allow-discrete; 26} 27
十四、CSS 动画(Animation)
1/* ① 定义关键帧 */ 2@keyframes slideIn { 3 from { 4 opacity: 0; 5 transform: translateY(-20px); 6 } 7 to { 8 opacity: 1; 9 transform: translateY(0); 10 } 11} 12 13@keyframes pulse { 14 0%, 100% { transform: scale(1); } 15 50% { transform: scale(1.1); } 16} 17 18/* ② 应用动画 */ 19.card { 20 /* animation: name duration timing-function delay iteration-count direction fill-mode */ 21 animation: slideIn .5s ease-out both; 22 23 /* 多动画叠加 */ 24 animation: slideIn .5s ease-out, pulse 2s ease-in-out infinite; 25} 26 27/* ③ 各属性详解 */ 28.el { 29 animation-name: slideIn; 30 animation-duration: 1s; 31 animation-timing-function: ease-in-out; 32 animation-delay: 0.2s; 33 animation-iteration-count: infinite; /* 数字或 infinite */ 34 animation-direction: alternate; /* normal|reverse|alternate|alternate-reverse */ 35 animation-fill-mode: both; /* none|forwards|backwards|both */ 36 animation-play-state: paused; /* 暂停/运行 */ 37} 38 39/* ⭐ 无障碍:尊重用户减少动画的系统偏好 */ 40@media (prefers-reduced-motion: reduce) { 41 *, *::before, *::after { 42 animation-duration: 0.01ms !important; 43 transition-duration: 0.01ms !important; 44 } 45} 46 47/* ⭐ scroll-driven animations — 滚动驱动动画(CSS 2024+)*/ 48@keyframes reveal { 49 from { opacity: 0; translate: 0 40px; } 50 to { opacity: 1; translate: 0 0; } 51} 52 53.card { 54 animation: reveal linear both; 55 animation-timeline: view(); /* 进入视口时触发 */ 56 animation-range: entry 0% entry 30%; 57} 58
十五、CSS 自定义属性(变量)
CSS 自定义属性(Custom Properties)是原生变量系统,比预处理器变量更强大,支持运行时修改、作用域继承。
1/* ① 定义:在 :root 上定义全局变量 */ 2:root { 3 --color-primary: #3b82f6; 4 --color-text: #1a1a1a; 5 --spacing-md: 16px; 6 --radius: 8px; 7 --font-heading: 'Playfair Display', serif; 8} 9 10/* ② 使用:var(--name, fallback) */ 11.btn { 12 background: var(--color-primary); 13 padding: var(--spacing-md); 14 border-radius: var(--radius, 4px); /* 4px 为回退值 */ 15} 16 17/* ③ 局部作用域:在组件内覆盖 */ 18.card-danger { 19 --color-primary: #ef4444; /* 仅在此元素及子元素有效 */ 20} 21 22/* ④ 主题切换 */ 23[data-theme="dark"] { 24 --color-text: #f0f0f0; 25 --color-bg: #1a1a1a; 26} 27 28/* ⑤ 用于 calc() 计算 */ 29:root { 30 --base-size: 16; /* 无单位 */ 31} 32.el { 33 font-size: calc(var(--base-size) * 1px); 34} 35 36/* ⑥ JavaScript 读写 */ 37/* 38 读取:getComputedStyle(el).getPropertyValue('--color-primary') 39 写入:el.style.setProperty('--color-primary', '#ff0000') 40*/ 41 42/* ⭐ @property — 注册类型化变量(CSS 2024+)*/ 43@property --progress { 44 syntax: '<number>'; 45 initial-value: 0; 46 inherits: false; 47} 48/* 类型化变量可以被 transition/animation 插值! */ 49
十六、响应式设计
媒体查询(Media Queries)
1/* 断点:移动优先(推荐)*/ 2/* 基础样式针对移动端,然后用 min-width 向上扩展 */ 3 4@media (min-width: 640px) { /* sm: 平板竖屏 */ } 5@media (min-width: 768px) { /* md: 平板横屏 */ } 6@media (min-width: 1024px) { /* lg: 桌面 */ } 7@media (min-width: 1280px) { /* xl: 宽屏 */ } 8 9/* 组合条件 */ 10@media (min-width: 768px) and (max-width: 1023px) { } 11 12/* 媒体类型 */ 13@media print { /* 打印样式 */ } 14@media screen { /* 屏幕 */ } 15 16/* 用户偏好媒体特性 */ 17@media (prefers-color-scheme: dark) { /* 系统深色模式 */ } 18@media (prefers-reduced-motion: reduce) { /* 减少动画 */ } 19@media (prefers-contrast: high) { /* 高对比度模式 */ } 20@media (hover: none) { /* 触摸设备,无 hover */ } 21 22/* ⭐ 范围媒体查询语法(CSS 2023+,更直观)*/ 23@media (768px <= width <= 1024px) { } 24
容器查询(Container Queries)— CSS 2023+
1/* ① 声明容器 */ 2.card-wrapper { 3 container-type: inline-size; /* 响应宽度变化 */ 4 container-name: card; /* 命名(可选)*/ 5} 6 7/* ② 在容器内部查询 */ 8@container (min-width: 400px) { 9 .card { 10 display: flex; 11 gap: 16px; 12 } 13} 14 15/* ③ 容器查询单位 */ 16.card-title { 17 font-size: clamp(1rem, 3cqi, 2rem); 18 /* cqi = container inline 的 1%(类似 vw,但基于容器)*/ 19} 20
响应式单位与函数
1/* 视口单位 */ 2.hero { 3 height: 100vh; /* 视口高度 */ 4 width: 50vw; /* 视口宽度 */ 5 font-size: 5vmin; /* vmin = min(vw, vh) */ 6 7 /* ⭐ 动态视口单位(解决移动端地址栏问题)*/ 8 height: 100svh; /* small viewport height */ 9 height: 100lvh; /* large viewport height */ 10 height: 100dvh; /* dynamic viewport height(推荐)*/ 11} 12 13/* 相对字体单位 */ 14.text { 15 font-size: 1rem; /* 相对于根元素字号 */ 16 padding: 1em; /* 相对于当前元素字号 */ 17 width: 60ch; /* 约 60 个字符宽,文章理想宽度 */ 18} 19 20/* clamp() — 流体字体尺寸 */ 21h1 { 22 /* 最小1.5rem,最大3rem,中间随视口线性变化 */ 23 font-size: clamp(1.5rem, 4vw + 0.5rem, 3rem); 24} 25 26/* min() max() */ 27.container { 28 width: min(100%, 1200px); /* 取较小值,等于 max-width */ 29 padding: max(16px, 4vw); /* 取较大值 */ 30} 31
十七、现代 CSS 特性(2023–2025)
① CSS Nesting — 原生嵌套(无需 Sass)
1.card { 2 padding: 16px; 3 4 & h2 { font-size: 1.5rem; } /* .card h2 */ 5 &:hover { box-shadow: 0 4px 16px #0002; } 6 7 @media (min-width: 768px) { 8 display: flex; /* 嵌套 @media */ 9 } 10} 11
② @scope — 样式作用域
1@scope (.card) to (.card__footer) { 2 p { color: navy; } /* 仅影响 .card 内、.card__footer 之前的 p */ 3} 4
③ @starting-style — 入场动画(2024+)
1.popover { 2 transition: opacity .3s, transform .3s, display .3s; 3 transition-behavior: allow-discrete; 4 opacity: 1; 5 transform: translateY(0); 6} 7 8@starting-style { 9 .popover { 10 opacity: 0; 11 transform: translateY(-10px); 12 } 13} 14
④ View Transitions — 页面转场动画
1@view-transition { 2 navigation: auto; 3} 4 5::view-transition-old(root) { 6 animation: fadeOut .3s ease-in; 7} 8
⑤ Anchor Positioning — 锚点定位(Chrome 2024+)
1.tooltip { 2 position-anchor: --btn; 3 top: anchor(bottom); 4 left: anchor(center); 5} 6
⑥ text-wrap 新值
1h1 { text-wrap: balance; } /* 均匀分配每行字数 */ 2p { text-wrap: pretty; } /* 避免段落最后一行孤字 */ 3
⑦ Scrollbar 样式
1.scroll { 2 scrollbar-color: #888 #f0f0f0; /* thumb track */ 3 scrollbar-width: thin; 4 scrollbar-gutter: stable; /* 预留滚动条空间防止布局跳动 */ 5} 6
⑧ content-visibility — 性能优化
1.long-list-item { 2 content-visibility: auto; /* 跳过屏幕外元素的渲染 */ 3 contain-intrinsic-size: 0 200px; /* 告知浏览器占位高度 */ 4} 5
新特性速览表
| 特性 | 说明 | 浏览器支持 |
|---|---|---|
| :has() | 父选择器 | 全浏览器(2023+) |
| @layer | 层叠层管理 | 全浏览器(2022+) |
| @container | 容器查询 | 全浏览器(2023+) |
| CSS Nesting | 原生嵌套 | 全浏览器(2023+) |
| @scope | 样式作用域 | Chrome/Safari(2024+) |
| @starting-style | 入场动画 | Chrome/Firefox(2024+) |
| text-wrap: balance | 标题均衡换行 | 全浏览器(2023+) |
| scrollbar-color | 滚动条样式 | 全浏览器(2024+) |
| light-dark() | 自动深浅色 | 全浏览器(2024+) |
| oklch() 颜色 | 感知均匀色彩 | 全浏览器(2023+) |
| 滚动驱动动画 | 基于滚动的动画 | Chrome(2023+) |
| 锚点定位 | CSS 定位工具 | Chrome(2024+) |
十八、CSS 最佳实践
性能优化
- 将关键 CSS(Critical CSS)内联到
<head>中,消除渲染阻塞 - 使用
will-change: transform提示浏览器提前创建合成层,但勿滥用 - 动画优先使用
transform和opacity(不触发重排/重绘,由 GPU 合成) - 使用
content-visibility: auto跳过屏幕外元素渲染 - 避免在频繁触发的事件(scroll、resize)中读取触发重排的属性
BEM 命名规范
1/* BEM: Block__Element--Modifier */ 2.card { /* Block 块 */ } 3.card__title { /* Element 元素(双下划线)*/ } 4.card__image { /* Element */ } 5.card--featured { /* Modifier 修饰符(双连字符)*/ } 6.card--featured .card__title { /* 修饰符影响子元素 */ } 7 8/* 实用类(Utility Classes)配合使用 */ 9.mt-4 { margin-top: 1rem; } 10.flex { display: flex; } 11.sr-only { /* 仅供屏幕阅读器 */ 12 position: absolute; 13 width: 1px; height: 1px; 14 overflow: hidden; 15 clip: rect(0,0,0,0); 16 white-space: nowrap; 17} 18
@layer 现代架构分层
1/* 使用 @layer 明确定义层级顺序 */ 2@layer 3 reset, /* 浏览器默认样式重置 */ 4 tokens, /* 设计令牌(CSS 变量)*/ 5 base, /* 全局基础样式 */ 6 layout, /* 页面骨架布局 */ 7 components, /* 可复用 UI 组件 */ 8 patterns, /* 组合模式 */ 9 utilities; /* 单一功能类(最高优先级)*/ 10
核心检查清单
- ✅ 全局设置
box-sizing: border-box,避免!important滥用 - ✅ 动画用
transform/opacity,不用top/left/width - ✅ 媒体查询采用移动优先(
min-width)策略 - ✅ 图片设置
max-width: 100%防溢出,文字用rem单位 - ✅ 注意
:focus-visible键盘焦点样式,颜色对比度 ≥ 4.5:1 - ✅ 使用 CSS 变量统一管理设计令牌,用
@layer管理优先级 - ✅ 为
prefers-reduced-motion提供无动画回退 - ✅ 生产环境压缩 CSS,移除未使用的选择器(PurgeCSS)
推荐工具与资源
| 工具/资源 | 用途 |
|---|---|
| MDN Web Docs | 最权威的 CSS 属性文档与浏览器兼容性查询 |
| Can I Use | 查询 CSS 特性浏览器支持度 |
| CSS-Tricks | 深度教程与实践技巧 |
| Autoprefixer | 自动添加浏览器前缀 |
| PostCSS | CSS 转换工具链(类比 Babel for JS) |
| Sass / Less | CSS 预处理器(原生嵌套普及后逐渐简化) |
| PurgeCSS | 移除未使用的 CSS 选择器 |
| Stylelint | CSS 代码规范检查 |
| State of CSS | 年度 CSS 开发者调查报告(stateofcss.com) |
| web.dev / Chrome Developers | Google 出品的现代 CSS 最新特性文章 |
《CSS 全栈指南:从基础到 2025 新特性》 是转载文章,点击查看原文。
