以往文章
📚 JS 基础笔记:前端面试复习笔记:JS 基础核心知识点梳理
📚 浏览器原理笔记:前端面试复习笔记:浏览器原理核心知识点梳理
📚 前端项目优化(一):前端面试复习笔记:前端项目优化知识点梳理
📚 前端项目优化(二):前端面试复习笔记:前端项目优化知识点梳理
📚 前端项目优化(三):前端面试复习笔记:前端项目优化知识点梳理
📚 前端项目优化(四):前端面试复习笔记:前端项目优化知识点梳理
引言
面试被问 CSS 就头大?Flex 布局说不清、BFC 讲不透、Sticky 定位老出错?这篇笔记专治 "CSS 面试恐惧症"。本文系统梳理了 10 个一线高频的 CSS 核心模块,从 Flex、BFC 到性能优化、硬件加速,不仅有原理拆解,还有实战代码和避坑指南,帮你一次性扫清知识盲点,轻松应对面试官。
拒绝死记硬背,真正理解 CSS 的底层逻辑才是关键。
开始
本节将聚焦 CSS 核心知识,为你系统梳理前端面试中的高频考点:
序号 | 复习专题 | 本节聚焦 | 核心价值 |
---|---|---|---|
1 | JS 基础核心 | 已更 | 掌握 JS 底层原理与高频考点 |
2 | 浏览器原理 | 已更 | 理解浏览器工作流与渲染机制 |
3 | 前端项目优化 | 已更 (系列) | 掌握工程化、性能优化全链路技巧 |
4 | CSS 核心知识 | 本节内容 | 系统梳理 CSS 高频模块与面试陷阱 |
本节将围绕 10 个 CSS 核心模块展开,全是高频考点:
-
flex 布局:弹性盒模型应用与原理。
-
var() 实现换肤:CSS 变量的动态应用。
-
rem+vw 布局:移动端响应式布局方案。
-
link, style, @import 对比:三种样式引入方式的区别。
-
减少回流与重绘:CSS 性能优化核心法则。
-
CSS3 硬件加速:提升动画与过渡性能。
-
移动端实现 1px:高清屏下的精准边框方案。
-
BFC:块级格式化上下文的原理与应用。
-
sticky 粘性布局:实现吸顶、吸底效果。
-
animation 动画:关键帧动画的应用。
介绍
1:flex布局
一、核心概念
Flex 布局 (Flexible Box Layout) 是一种一维布局模型,专为盒状元素的排列、对齐和空间分配而设计。核心特点是通过 容器 (Container) 和 项目(Items) 的属性控制布局,适用于 单行或单列 的场景。
-
两根轴 :
-
主轴(Main Axis) :项目的排列方向,由
flex-direction
决定。 -
交叉轴(Cross Axis):与主轴垂直的方向,用于控制项目的对齐。
-
-
关键术语 :
-
Main Start/End:主轴的起始 / 结束位置。
-
Cross Start/End:交叉轴的起始 / 结束位置。
-
Main Size/Cross Size:项目在主轴 / 交叉轴上占据的空间。
-
二、容器属性(6 个)
1. flex-direction
:主轴方向
控制项目排列方向,决定主轴的方向和起点。
css
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
值 | 主轴方向 | 起始位置 |
---|---|---|
row (默认) |
水平向右 | 容器左侧 |
row-reverse |
水平向左 | 容器右侧 |
column |
垂直向下 | 容器顶部 |
column-reverse |
垂直向上 | 容器底部 |
2. flex-wrap
:换行规则
控制项目在主轴上排不下时如何处理。
CSS
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
值 | 换行行为 | 第一行位置 |
---|---|---|
nowrap (默认) |
不换行,压缩项目 | 无(单行) |
wrap |
换行 | 上方(起始侧) |
wrap-reverse |
换行 | 下方(结束侧) |
3. flex-flow
:方向与换行简写
flex-direction
和 flex-wrap
的组合简写。
CSS
.container {
flex-flow: row nowrap; /* 默认值 */
}
4. justify-content
:主轴对齐方式
控制项目在主轴上的对齐和间距。
CSS
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
值 | 对齐方式 | 间距特点 |
---|---|---|
flex-start |
左对齐(主轴起始侧) | 项目间无间距 |
flex-end |
右对齐(主轴结束侧) | 项目间无间距 |
center |
居中对齐 | 项目间无间距 |
space-between |
两端对齐 | 项目间间距相等,首尾无间距 |
space-around |
项目两侧间距相等 | 项目间间距是首尾间距的 2 倍 |
space-evenly |
所有间距完全相等 | 项目间、首尾间距均相同 |
space-around |
项目两侧间距相等 | 项目间间距是首尾间距的 2 倍 |
space-evenly |
所有间距完全相等 | 项目间、首尾间距均相同 |
5. align-items
:交叉轴对齐方式
控制单行项目在交叉轴上的对齐。
css
.container {
align-items: stretch | flex-start | flex-end | center | baseline;
}
值 | 对齐方式 | 适用场景 |
---|---|---|
stretch (默认) |
拉伸填满容器 | 项目未设置高度时占满容器 |
flex-start |
交叉轴起始侧对齐 | 顶部对齐 |
flex-end |
交叉轴结束侧对齐 | 底部对齐 |
center |
交叉轴中点对齐 | 垂直居中 |
baseline |
第一行文字的基线对齐 | 文本对齐 |
6. align-content
:多轴线对齐方式
控制多行项目在交叉轴上的对齐(仅在多行时生效)。
CSS
.container {
align-content: stretch | flex-start | flex-end | center | space-between | space-around;
}
值 | 对齐方式 | 间距特点 |
---|---|---|
stretch (默认) |
拉伸填满交叉轴 | 行高平均分配 |
flex-start |
交叉轴起始侧对齐 | 行间距为 0 |
flex-end |
交叉轴结束侧对齐 | 行间距为 0 |
center |
交叉轴中点对齐 | 行间距为 0 |
space-between |
两端对齐 | 行间距相等,首尾无间距 |
space-around |
每行两侧间距相等 | 行间距是首尾间距的 2 倍 |
三、项目属性(6 个)
1. order
:排列顺序
控制项目的渲染顺序(数值越小越靠前)。
CSS
.item {
order: 0; /* 默认值 */
}
2. flex-grow
:放大比例
控制项目在主轴上分配剩余空间的能力(默认不放大)。
CSS
.item {
flex-grow: 0; /* 默认值 */
}
- 计算逻辑 : 剩余空间 = 容器宽度 - 所有项目宽度之和 每个项目增加的宽度 = (剩余空间 × 当前项目
flex-grow
) / 所有项目flex-grow
之和
3. flex-shrink
:缩小比例
控制项目在空间不足时的收缩能力(默认收缩)。
CSS
.item {
flex-shrink: 1; /* 默认值 */
}
- 计算逻辑 : 溢出空间 = 所有项目宽度之和 - 容器宽度 每个项目缩小的宽度 = (溢出空间 × 当前项目
flex-shrink
× 项目宽度) / (所有项目flex-shrink
× 项目宽度之和)
4. flex-basis
:初始大小
控制项目在分配空间前的初始大小(优先级高于 width
/height
)。
CSS
.item {
flex-basis: auto | <length> | <percentage>; /* 默认值:auto */
}
-
特殊值:
-
auto
:使用项目的width
/height
,若无则根据内容计算。 -
0
:完全忽略项目的原始尺寸,仅根据flex-grow
分配空间。
-
5. flex
:简写属性
flex-grow
, flex-shrink
, flex-basis
的组合简写(推荐使用)。
CSS
.item {
flex: 0 1 auto; /* 默认值:不放大,可缩小,初始大小为 auto */
}
- 常用简写:
值 | 扩展形式 | 效果 |
---|---|---|
auto |
1 1 auto |
可放大可缩小,按内容分配空间 |
none |
0 0 auto |
不可放大缩小,按内容固定大小 |
<number> |
<number> 1 0 |
按比例放大,如 flex: 1 |
6. align-self
:单独对齐
覆盖容器的 align-items
,单独控制项目在交叉轴上的对齐。
CSS
.item {
align-self: auto | stretch | flex-start | flex-end | center | baseline; /* 默认值:auto */
}
四、核心计算逻辑(重点)
1. 空间分配流程
-
根据
flex-basis
确定项目初始大小。 -
计算剩余空间(容器宽度 - 所有项目
flex-basis
之和)。 -
根据
flex-grow
分配剩余空间(若为正值)。 -
若空间不足,根据
flex-shrink
缩小项目(若为正值)。
2. 关键公式
-
正向自由空间(剩余空间) :
剩余空间 = 容器宽度 - 所有项目 flex-basis 之和
-
项目最终宽度 :
最终宽度 = flex-basis + (剩余空间 × flex-grow 比例) - (溢出空间 × flex-shrink 比例)
五、典型应用场景
1. 等高布局
CSS
.container {
display: flex;
}
.item {
flex: 1; /* 所有项目等宽且等高 */
}
2. 垂直居中
CSS
.container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
3. 响应式导航栏
CSS
.nav {
display: flex;
justify-content: space-between; /* 两端对齐 */
}
4. 圣杯布局(左右固定,中间自适应)
CSS
.container {
display: flex;
}
.left,
.right {
flex: 0 0 200px; /* 固定宽度 */
}
.center {
flex: 1; /* 自适应剩余空间 */
}
六、注意事项与避坑指南
-
避免混用 Flex 和 Float:
- 浮动元素会脱离文档流,导致 Flex 布局失效。
-
注意
flex-basis
与width
的优先级:flex-basis
优先级高于width
,设置flex-basis
后width
会被忽略。
-
慎用
min-width: auto
:- 项目默认
min-width: auto
,可能阻止收缩,需显式设置min-width: 0
允许缩小。
- 项目默认
-
IE 兼容性:
- IE10+ 部分支持,需添加
-ms-
前缀(如display: -ms-flexbox
)。
- IE10+ 部分支持,需添加
七、复习速记表
核心概念 | 关键细节 | 示例代码 |
---|---|---|
容器属性 | flex-direction , flex-wrap , justify-content , align-items 等 |
.container { display: flex; justify-content: center; } |
项目属性 | flex , order , align-self 等 |
.item { flex: 1; order: -1; } |
空间分配 | flex-basis → 剩余空间 → flex-grow /flex-shrink |
.item { flex-basis: 100px; flex-grow: 2; } |
典型场景 | 垂直居中、等高布局、响应式导航 | .nav { display: flex; justify-content: space-between; } |
八、总结
Flex 布局 的核心是 "通过容器和项目的属性控制一维布局 ",重点掌握 flex
简写属性(flex: 1
表示 flex-grow: 1; flex-shrink: 1; flex-basis: 0
)、justify-content
和 align-items
的对齐方式,以及空间分配的计算逻辑。通过多练习典型场景(如垂直居中和响应式布局),可快速掌握其应用技巧。
2:var()实现换肤
一、核心概念
CSS 中通过 var()
函数调用自定义属性(CSS 变量),实现样式的动态复用与切换,是前端换肤功能的核心技术。
-
自定义属性(变量) :以
--
开头定义(如--primary-color: #f00;
),可存储颜色、尺寸等任意 CSS 值,区分大小写。 -
var()
函数 :语法为var(--变量名, 默认值)
,用于引用自定义属性的值;若变量未定义,默认值生效(可选)。
二、换肤实现的核心逻辑
通过预定义多套主题变量(如默认 / 深色 / 浅色主题),再通过 JavaScript 动态修改根元素(:root
)上的变量值,使页面样式全局更新,实现一键切换主题。
三、具体实现步骤
1. 定义主题变量
在 :root
中定义全局变量(默认主题),并为其他主题定义独立变量集(通过类名区分):
CSS
/* 默认主题 */
:root {
--primary: #4285f4; /* 主色调 */
--text: #333; /* 文本色 */
--bg: #fff; /* 背景色 */
--border: #e5e7eb; /* 边框色 */
}
/* 深色主题 */
:root.dark {
--primary: #61dafb;
--text: #f3f4f6;
--bg: #1f2937;
--border: #374151;
}
/* 红色主题 */
:root.red {
--primary: #ef4444;
--text: #111827;
--bg: #fef2f2;
--border: #fecaca;
}
2. 在样式中引用变量
用 var()
替代固定值,使样式依赖变量:
CSS
body {
background-color: var(--bg);
color: var(--text);
border: 1px solid var(--border);
}
.btn {
background-color: var(--primary);
color: white;
padding: 8px 16px;
}
3. 动态切换主题(JavaScript)
通过添加 / 移除根元素的主题类名,触发变量值切换:
JavaScript
// 切换到深色主题
function setDarkTheme() {
document.documentElement.classList.add('dark');
document.documentElement.classList.remove('red'); // 移除其他主题
}
// 切换到红色主题
function setRedTheme() {
document.documentElement.classList.add('red');
document.documentElement.classList.remove('dark');
}
// 重置为默认主题
function setDefaultTheme() {
document.documentElement.classList.remove('dark', 'red');
}
四、优势与注意事项
1. 优势
-
维护高效:变量集中管理,修改一处即可全局生效,避免重复代码。
-
实时响应 :切换主题无需刷新页面,样式即时更新(可配合
transition
实现平滑过渡)。 -
扩展性强:新增主题只需添加一套变量,无需修改业务样式。
2. 注意事项
-
兼容性 :现代浏览器(Chrome 49+、Firefox 31+)支持,IE 完全不支持(需通过
postcss-css-variables
降级)。 -
变量作用域 :
:root
中定义的变量全局生效,局部选择器中定义的变量仅作用于该选择器及其子元素。 -
默认值必要性 :当变量可能未定义时,建议添加默认值(如
var(--unknown, #000)
)。
五、复习速记表
核心要素 | 关键细节 | 示例代码 |
---|---|---|
变量定义 | --变量名: 值; ,-- 开头,区分大小写 |
:root { --primary: #4285f4; } |
调用方式 | var(--变量名, 默认值) ,默认值可选 |
color: var(--text, #333); |
主题切换逻辑 | 定义多套变量 + JS 操作根元素类名 | document.documentElement.classList.add('dark') |
优势 | 维护高效、实时响应、扩展性强 | - |
兼容性 | 现代浏览器支持,IE 需降级 | - |
六、总结
var()
实现换肤的核心是 "变量集中管理 + 动态修改" :通过定义主题变量并在样式中引用,再用 JavaScript 切换变量值,实现全局样式一键更新。该方案简洁高效,是前端主题切换的首选技术,复习时需重点掌握变量定义规则、调用语法及动态切换逻辑。
3:rem+vw布局
一、核心概念
rem
与 vw
结合是实现响应式布局的经典方案,通过两者的互补特性,让元素尺寸随屏幕宽度动态适配:
-
rem
:相对单位,尺寸基于根元素(html
)的font-size
计算(如html { font-size: 16px; }
时,1rem = 16px
)。 -
vw
:视口单位,1vw 等于视口宽度的 1%(如屏幕宽度 1000px 时,1vw = 10px
)。 -
结合逻辑 :用
vw
动态设置根元素的font-size
,使rem
间接随视口宽度变化,实现 "一套样式适配多设备"。
二、实现逻辑
通过 vw
定义根元素的 font-size
,让 rem
成为 "随视口宽度变化的单位",从而使页面元素尺寸自动适配不同屏幕:
-
根元素
font-size
用vw
定义 :确保rem
的基准值随视口宽度动态变化(如html { font-size: 1vw; }
,则1rem = 1vw
)。 -
元素尺寸用
rem
定义 :所有元素的width
、height
、font-size
等均使用rem
,间接依赖视口宽度,实现响应式。
三、具体实现步骤
1. 设置根元素 font-size
(关键)
通过 vw
定义 html
的 font-size
,建立 rem
与视口宽度的关联。为简化计算,通常设置 1rem = 10px
(在标准视口下),示例:
CSS
/* 视口宽度 375px 时,1vw = 3.75px,10vw = 37.5px ≈ 设计稿 375px 下的 10px(1rem = 10px) */
html {
font-size: 10vw; /* 核心:1rem = 10vw,随视口宽度变化 */
/* 限制最大/最小值,避免极端屏幕尺寸下样式错乱 */
max-font-size: 64px; /* 最大 64px(对应视口宽度 640px 以上) */
min-font-size: 32px; /* 最小 32px(对应视口宽度 320px 以下) */
}
2. 用 rem
定义元素尺寸
以设计稿(假设宽度 375px)为例,将设计稿尺寸转换为 rem
(因 1rem = 10px
,则 375px = 37.5rem
):
CSS
/* 设计稿中宽度 100px 的元素 → 100px / 10px = 10rem */
.box {
width: 10rem; /* 随视口宽度变化,375px 屏幕上为 100px,750px 屏幕上为 200px */
height: 5rem; /* 设计稿 50px → 5rem */
font-size: 1.6rem; /* 设计稿 16px → 1.6rem */
}
/* 设计稿中页面最大宽度 750px → 750px / 10px = 75rem */
.container {
max-width: 75rem; /* 限制最大宽度,避免大屏拉伸 */
margin: 0 auto;
}
3. 配合媒体查询优化(可选)
在极端屏幕尺寸下(如小屏手机、大屏显示器),用媒体查询微调 font-size
,增强兼容性:
CSS
/* 视口宽度 ≥ 750px 时,固定 1rem = 10px(避免过大) */
@media (min-width: 750px) {
html {
font-size: 10px;
}
}
/* 视口宽度 ≤ 320px 时,固定 1rem = 8px(避免过小) */
@media (max-width: 320px) {
html {
font-size: 8px;
}
}
四、优势与注意事项
1. 优势
-
适配性强:同时兼顾不同尺寸设备(手机、平板、PC),无需为每个屏幕写单独样式。
-
计算简单 :通过
1rem = 10px
等比例设置,设计稿尺寸可直接除以 10 转换为rem
(如 100px → 10rem)。 -
灵活性高 :可通过修改根元素
font-size
统一调整页面缩放(比纯vw
更易控制)。
2. 注意事项
-
兼容性 :
rem
兼容至 IE9+,vw
兼容至 IE11+(低版本浏览器需用flexible.js
等工具降级)。 -
字体抖动 :在部分设备上,
vw
动态计算可能导致字体大小轻微抖动,可通过媒体查询固定关键尺寸。 -
缩放限制 :需设置
max-font-size
和min-font-size
,避免极端屏幕下元素过大 / 过小。
五、复习速记表
核心要素 | 定义与作用 | 关键代码示例 |
---|---|---|
rem |
相对根元素 font-size 的单位,用于元素尺寸 |
width: 10rem; (依赖 html 的 font-size ) |
vw |
视口宽度的 1%,用于动态设置根元素 font-size |
html { font-size: 10vw; } (1rem = 10vw) |
结合逻辑 | vw 驱动 rem 变化,实现响应式 |
根元素 font-size: 10vw + 元素 width: 10rem |
优势 | 适配多设备、计算简单、易控制 | - |
注意事项 | 兼容 IE11+、需限制最大 / 最小尺寸 | html { max-font-size: 64px; } |
六、总结
rem + vw
布局的核心是 "用 vw
实现根元素尺寸的动态适配,用 rem
实现元素尺寸的统一缩放 ",兼顾了响应式的灵活性和计算的便捷性,是多设备适配的高效方案。复习时需重点掌握根元素 font-size
的设置逻辑及 rem
与设计稿的换算规则。 好的,这是第三部分预览。
4:link,style,@import三种方式
一、核心概念
link
、style
、@import
是 CSS 引入和编写的三种方式,分别用于外部引入、内嵌样式和 CSS 内部导入,核心作用是将样式应用到 HTML 文档中,但在加载方式、优先级和使用场景上有显著差异:
-
link
:HTML 标签,用于从外部引入 CSS 文件(最常用的外部样式引入方式)。 -
style
:HTML 标签,用于在 HTML 文档内直接编写 CSS 代码(内嵌样式)。 -
@import
:CSS 语法规则,用于在 CSS 文件或style
标签内引入其他 CSS 文件(嵌套导入)。
二、基本用法与作用
1. link
标签(外部引入)
-
定义 :通过 HTML 的
<link>
标签引入外部 CSS 文件,是最常用的样式引入方式。 -
用法:
html<link rel="stylesheet" href="style.css">
html<link rel="stylesheet" href="desktop.css" media="(min-width: 768px)">
html<link rel="preload" href="critical.css" as="style" onload="this.rel='stylesheet'">
-
作用:将 CSS 与 HTML 分离,实现样式复用和模块化管理,适合大型项目。
2. style
标签(内嵌样式)
-
定义 :HTML 的
<style>
标签内直接编写 CSS 代码,样式仅作用于当前 HTML 文档。 -
用法:
html<style> /* 内嵌 CSS 代码 */ body { margin: 0; } .title { color: #333; } </style>
html<style media="(max-width: 767px)"> .nav { flex-direction: column; } </style>
-
作用:无需额外 HTTP 请求,适合少量 CSS 或页面专属样式(如单页应用)。
3. @import
规则(CSS 内部导入)
-
定义 :CSS 语法中的导入规则,用于在 CSS 文件或
style
标签内引入其他 CSS 文件。 -
用法:
css/* 在 CSS 文件中导入 */ @import url("reset.css"); /* 引入 reset.css */ @import "base.css"; /* 简写形式,需注意路径 */ @import url("print.css") print; /* 仅打印时生效 */ /* 在 style 标签内导入 */
-
作用:在 CSS 内部嵌套引入其他样式文件,实现样式的分层管理(如主题样式、基础样式分离)。
三、核心区别(重点考点)
维度 | link 标签 |
style 标签 |
@import 规则 |
---|---|---|---|
本质 | HTML 标签 | HTML 标签 | CSS 语法规则 |
使用位置 | HTML 文档的 <head> 中 |
HTML 文档的 <head> 中 |
CSS 文件或 style 标签内 |
加载方式 | 与 HTML 并行加载(不阻塞 HTML 解析) | 内嵌在 HTML 中,无需额外请求 | 等待当前 CSS 解析完成后串行加载(可能阻塞渲染) |
优先级 | 取决于引入顺序(后加载的覆盖先加载的) | 高于外部引入的 CSS(同权重下) | 低于引入它的 CSS 文件(被当前 CSS 覆盖) |
DOM 可见性 | 会被解析为 DOM 节点(可通过 JS 操作) | 会被解析为 DOM 节点(可通过 JS 操作) | 不会出现在 DOM 中(无法通过 JS 直接操作) |
兼容性 | 所有浏览器支持 | 所有浏览器支持 | IE5.5+ 支持,低版本 IE(≤IE5)不支持 |
四、优势与注意事项
1. link
标签
-
优势 :
-
并行加载 :不阻塞 HTML 解析,加载效率高于
@import
。 -
灵活性 :支持
rel="preload"
预加载关键 CSS,提升首屏速度;支持媒体查询动态切换样式。 -
可操作性 :可通过 JavaScript 动态修改
href
切换样式(如换肤)。
-
-
注意事项 :
- 过多
link
标签会增加 HTTP 请求数,需合理合并 CSS 文件。
- 过多
2. style
标签
-
优势 :
-
无额外请求:内嵌样式无需加载外部文件,适合少量 CSS(如页面初始化样式)。
-
优先级高:在同权重下,内嵌样式优先级高于外部引入的 CSS(便于临时覆盖样式)。
-
-
注意事项 :
-
不利于样式复用:内嵌样式仅作用于当前页面,多页面项目会导致代码冗余。
-
增大 HTML 体积 :大量 CSS 写入
style
标签会增加 HTML 文件大小,影响加载速度。
-
3. @import
规则
-
优势:
- 模块化管理 :在 CSS 内部导入其他文件,便于按功能拆分样式(如
base.css
导入reset.css
)。
- 模块化管理 :在 CSS 内部导入其他文件,便于按功能拆分样式(如
-
注意事项:
-
加载阻塞 :CSS 解析时会等待
@import
的文件加载完成,可能导致页面渲染延迟。 -
优先级限制:导入的 CSS 会被引入它的 CSS 文件覆盖,不利于样式覆盖。
-
兼容性:低版本 IE 不支持,需谨慎使用。
-
五、复习速记表
方式 | 核心特点 | 适用场景 | 避坑点 |
---|---|---|---|
link |
HTML 标签,外部引入,并行加载 | 多页面项目、大量 CSS、需预加载的场景 | 避免过多 link 标签导致请求数增加 |
style |
HTML 标签,内嵌样式,无额外请求 | 单页应用、少量 CSS、临时样式覆盖 | 大量 CSS 会增大 HTML 体积 |
@import |
CSS 规则,内部导入,串行加载 | CSS 模块化拆分(谨慎使用) | 避免在关键 CSS 中使用,防止渲染阻塞 |
六、总结
link
、style
、@import
均用于应用 CSS,但核心差异体现在 加载方式、优先级和使用场景:
-
外部样式优先用
link
(高效、灵活); -
少量专属样式用
style
(无请求开销); -
@import
因加载阻塞问题,仅在特殊模块化场景下使用(需配合性能优化)。掌握三者的区别,是实现高效样式管理和性能优化的基础。
5:css减少回流,重绘
一、核心概念
回流 (Reflow)和重绘(Repaint)是浏览器渲染页面的两个关键阶段,过度触发会导致页面卡顿,影响性能:
-
回流(Reflow) :又称 "重排",指当元素的布局属性(位置、尺寸、结构等)发生变化时,浏览器重新计算元素位置和大小并更新布局的过程(如修改
width
、height
、margin
等)。- 影响范围:可能触发父元素及后续元素的连锁回流(如移动一个元素,后续元素位置需重新计算),性能消耗大。
-
重绘(Repaint) :指当元素的外观属性(颜色、背景、阴影等)发生变化,但布局未改变时,浏览器重新绘制元素样式的过程(如修改
color
、background
等)。- 影响范围:仅涉及当前元素,性能消耗小于回流。
二、导致回流 / 重绘的常见操作
1. 触发回流的操作
-
修改布局属性 :
width
、height
、margin
、padding
、border
、display
、position
(如从static
改为absolute
)。 -
操作 DOM :添加 / 删除元素、修改 DOM 结构(如
appendChild
、innerHTML
)。 -
浏览器窗口变化 :
resize
事件、滚动页面(触发scroll
时可能计算元素位置)。 -
读取布局属性 :频繁访问
offsetWidth
、offsetHeight
、getBoundingClientRect()
等(浏览器为获取最新值会强制触发回流)。
2. 触发重绘的操作
- 修改外观属性 :
color
、background
、border-color
、box-shadow
、visibility
(仅隐藏元素,不改变布局)。
三、减少回流 / 重绘的核心措施
1. 减少回流:优先避免布局属性频繁变化
-
批量修改 DOM:
-
先将元素脱离文档流(如设置
display: none
),批量修改后再恢复显示(仅触发 2 次回流:隐藏时和显示时)。javascriptconst el = document.getElementById('box'); el.style.display = 'none'; // 脱离文档流,后续修改不触发回流 el.style.width = '200px'; el.style.height = '100px'; el.style.display = 'block'; // 恢复显示,触发 1 次回流
-
使用
DocumentFragment
批量添加元素(避免逐次appendChild
触发多次回流)。javascriptconst fragment = document.createDocumentFragment(); for (let i = 0; i < 100; i++) { const div = document.createElement('div'); fragment.appendChild(div); // 先添加到文档片段(无回流) } document.body.appendChild(fragment); // 一次性添加,仅触发 1 次回流
-
-
避免频繁访问布局属性:
-
集中读取布局属性(如
offsetWidth
),缓存结果后批量修改(避免浏览器为获取最新值强制回流)。javascript// bad:多次读取触发多次回流 el.style.width = '100px'; console.log(el.offsetWidth); // 触发回流 el.style.height = '100px'; console.log(el.offsetHeight); // 再次触发回流
javascript// good:先读取缓存,再修改 const width = el.offsetWidth; // 读取一次,触发 1 次回流 const height = el.offsetHeight; el.style.width = width + 10 + 'px'; el.style.height = height + 10 + 'px'; // 仅触发 1 次回流
-
-
使用 CSS 触发 GPU 加速:
-
将元素放入独立图层,修改
transform
或opacity
时仅触发合成(Compositing),不触发回流 / 重绘(由 GPU 处理,性能更高)。css.box { transform: translateZ(0); /* 触发 GPU 加速,放入独立图层 */ /* 后续修改 transform 或 opacity 无回流/重绘 */ }
-
2. 减少重绘:优化外观属性修改
-
合并外观属性修改:将多个外观样式合并为一个
class
,一次性切换(减少重绘次数)。css/* 定义合并后的类 */ .active { color: red; background: blue; box-shadow: 0 0 10px #000; }
javascript// 一次性添加类,仅触发 1 次重绘 el.classList.add('active');
3. 其他优化技巧
-
避免使用表格布局 :表格的
cellspacing
、cellpadding
等属性修改会触发整个表格的回流,性能较差(推荐用flex
或grid
替代)。 -
优化选择器层级 :避免过深的 CSS 选择器(如
div > ul > li > a
),减少浏览器匹配元素时的计算量(间接减少回流 / 重绘耗时)。 -
防抖 / 节流处理高频事件 :对
resize
、scroll
等高频事件,用防抖(debounce
)或节流(throttle
)限制触发频率(如 100ms 内仅执行一次)。
四、回流与重绘的区别(复习速记表)
维度 | 回流(Reflow) | 重绘(Repaint) |
---|---|---|
定义 | 元素布局属性变化,重新计算布局 | 元素外观属性变化,不改变布局 |
触发因素 | 修改 width 、margin 、DOM 结构等 |
修改 color 、background 、box-shadow 等 |
性能消耗 | 大(可能触发连锁反应) | 小(仅当前元素) |
关联性 | 回流一定会导致重绘 | 重绘不一定导致回流 |
优化重点 | 减少布局属性修改,批量操作 DOM | 合并外观属性修改,避免频繁触发 |
五、核心优化原则(复习速记)
优化方向 | 关键措施 | 示例代码 |
---|---|---|
减少回流 | 批量修改 DOM(先隐藏再显示) | el.style.display = 'none'; ... 修改 ... el.style.display = 'block' |
减少回流 | 缓存布局属性读取 | const w = el.offsetWidth; el.style.width = w + 'px' |
减少回流 | 用 transform /opacity 替代布局修改 |
el.style.transform = 'translateX(10px)' |
减少重绘 | 合并外观属性为类,一次性切换 | el.classList.add('active') |
高频事件处理 | 防抖 / 节流限制 resize /scroll 触发频率 |
window.addEventListener('resize', debounce(handleResize, 100)) |
六、总结
回流 和重绘 是浏览器渲染的必然过程,但过度触发会导致性能问题。优化核心是: "减少回流次数(优先),控制重绘频率" 。通过批量修改 DOM、缓存布局属性、利用 GPU 加速等技巧,可显著降低渲染开销,提升页面流畅度。复习时需重点区分回流与重绘的触发因素及优化措施。
6:css3硬件加速
一、核心概念
CSS3 硬件加速 (GPU 加速)是指通过特定 CSS 属性,将元素的渲染任务交由 GPU(图形处理器) 处理,而非依赖 CPU,从而提升动画流畅度和渲染性能的技术。
-
核心原理:GPU 擅长并行处理图形渲染(如矩阵运算、图层合成),通过将元素放入 独立图层,使该元素的动画 / 变换由 GPU 直接处理,减少 CPU 对布局计算(回流)和像素绘制(重绘)的消耗。
-
关键特性 :进入硬件加速的元素,修改
transform
或opacity
时,仅触发 图层合成(Compositing),不触发回流或重绘(性能开销极低)。
二、作用与优势
1. 核心作用
- 减少 CPU 负担:将复杂动画(如旋转、缩放、平移)的渲染任务转移给 GPU,避免 CPU 因频繁计算布局而卡顿。
- 提升动画流畅度 :GPU 处理渲染的效率远高于 CPU,可使动画帧率(FPS)更接近 60fps(人眼感知的 "流畅阈值")。 '- 隔离渲染影响:独立图层中的元素修改不会影响其他元素,避免连锁回流 / 重绘。
2. 与传统渲染的对比
渲染方式 | 处理主体 | 触发操作 | 性能开销 | 适用场景 |
---|---|---|---|---|
传统渲染(CPU) | CPU | 修改 width 、top 等 |
高(可能触发回流 / 重绘) | 静态布局、非动画元素 |
硬件加速(GPU) | GPU | 修改 transform 、opacity |
低(仅图层合成) | 动画元素、频繁变换的元素 |
三、触发硬件加速的 CSS 属性与方式
并非所有 CSS 属性都能触发硬件加速,只有以下属性会使浏览器将元素放入独立图层:
属性 / 方式 | 触发逻辑 | 示例代码 |
---|---|---|
transform: translateZ(0) |
通过 3D 变换强制创建独立图层(最常用方式) | .box { transform: translateZ(0); } |
transform: translate3d(x, y, z) |
3D 变换直接触发 GPU 加速 | .box { transform: translate3d(10px, 20px, 0); } |
opacity < 1 |
不透明度过低时,浏览器自动启用 GPU 加速 | .box { opacity: 0.9; } |
will-change: transform |
告知浏览器元素即将变换,提前准备 GPU 加速 | .box { will-change: transform; } |
filter (部分值) |
复杂滤镜效果(如 blur )会触发加速 |
.box { filter: blur(2px); } |
四、具体使用与注意事项
1. 正确触发硬件加速的场景
-
动画元素 :对需要频繁变换的元素(如轮播图、悬浮按钮),用
transform
替代top
/left
/margin
实现位移(避免触发回流)。css/* 推荐:用 transform 触发 GPU 加速,无回流 */ .animate { transform: translateX(100px); /* 仅触发图层合成 */ transition: transform 0.3s; } /* 不推荐:修改 left 触发回流 */ .bad-animate { left: 100px; /* 触发回流,性能差 */ transition: left 0.3s; }
-
提前声明加速需求 :对即将发生动画的元素,用
will-change
告知浏览器提前准备(避免动画开始时的卡顿)。css.nav-item { will-change: transform; /* 提前告知浏览器可能变换 */ } .nav-item:hover { transform: scale(1.1); /* 动画时 GPU 已就绪 */ }
2. 避免滥用的注意事项
-
警惕 "图层爆炸":每个独立图层会占用 GPU 内存(尤其是含大图的元素),过多图层(如超过 50-100 个)会导致内存占用激增,反而引发卡顿或崩溃。
- 解决 :仅对必要元素(如动画元素)启用加速,动画结束后移除加速属性(如
will-change: auto
)。
- 解决 :仅对必要元素(如动画元素)启用加速,动画结束后移除加速属性(如
-
避免无意义的 3D 变换 :
transform: translateZ(0)
虽能触发加速,但过度使用会导致图层冗余(如给所有元素添加该属性)。 -
注意图层合并问题:相邻的加速元素可能被浏览器自动合并为一个图层,若其中一个元素触发重绘,会导致整个合并图层重绘(抵消加速效果)。
- 解决 :通过
transform: translateZ(1px)
给相邻元素设置微小 Z 轴差异,避免合并。
- 解决 :通过
-
慎用
will-change
:will-change: transform
会让浏览器长期保留图层,占用内存,建议仅在元素即将动画时添加,动画结束后移除(如通过 JS 动态控制)。
五、硬件加速优化实践(详细措施)
-
用
transform
替代布局属性 :-
位移 :用
translate(Xpx, Ypx)
替代top
/left
/margin
; -
缩放 :用
scale(n)
替代width
/height
; -
旋转 :用
rotate(deg)
替代通过 JS 计算角度修改布局。
-
-
控制图层数量 :
- 仅对可见区域的动画元素启用加速(如滚动时,仅给当前视口内的元素添加
transform: translateZ(0)
); - 动画结束后,通过 JS 移除加速属性(如
el.style.transform = 'translateZ(0)'
改为auto
)。
- 仅对可见区域的动画元素启用加速(如滚动时,仅给当前视口内的元素添加
-
监控图层性能 :
- 用 Chrome DevTools 的 Layers 面板(More Tools → Layers)查看当前图层数量和内存占用,超过 100 个图层时需优化。
六、复习速记表
核心要素 | 关键细节 | 示例代码 |
---|---|---|
触发属性 | transform (3D 变换)、opacity < 1 、will-change |
.box { transform: translate3d(0, 0, 0); } |
核心优势 | 利用 GPU 处理渲染,减少回流 / 重绘 | 动画帧率从 30fps 提升至 60fps |
注意事项 | 避免图层爆炸(≤100 个图层)、慎用 will-change |
动画结束后移除 will-change |
适用场景 | 频繁动画元素(轮播、悬浮效果) | 按钮悬浮缩放、页面滚动动画 |
七、总结
CSS3 硬件加速 的核心是 "合理利用 GPU 处理渲染任务 ",通过 transform
等属性将元素放入独立图层,提升动画流畅度。但需注意:并非所有元素都需要加速,过度使用会导致图层爆炸和内存占用过高,需平衡性能与资源消耗。
7. 移动端实现1px
一、核心概念
移动端 "1px 问题" 指的是:在高分辨率屏幕(如 Retina 屏)上,CSS 中定义的 1px
会被渲染为多个物理像素,导致边框看起来比设计稿粗(不符合 "纤细边框" 的视觉要求)。
-
本质原因 : 屏幕的 设备像素比(DPR,Device Pixel Ratio) 导致。DPR = 物理像素 / CSS 像素,例如:
-
DPR=2(如 iPhone 8):1px CSS 像素对应 2 个物理像素(视觉上相当于 2px 粗)。
-
DPR=3(如 iPhone 13 Pro):1px CSS 像素对应 3 个物理像素(视觉上更粗)。
-
-
目标:通过技术手段让 CSS 实现的 "1px" 在高 DPR 屏幕上仅对应 1 个物理像素,还原设计稿的精细边框。
二、作用与意义
-
视觉一致性:在高清屏幕上还原设计稿的纤细边框,避免 UI 元素(如卡片、列表)因边框过粗显得臃肿。
-
提升用户体验:精细的 1px 边框符合现代设计审美,增强界面精致度(尤其在金融、电商等对 UI 要求高的场景)。
三、具体实现方法(按常用度排序)
1. transform: scale(0.5)
缩放法(推荐)
-
原理 :在高 DPR 屏幕上,先定义
2px
的边框,再通过transform: scale(0.5)
缩放到原尺寸的一半,实际占 1 个物理像素。 -
适配 DPR=2:
css.border-1px { position: relative; } .border-1px::after { content: ''; position: absolute; left: 0; bottom: 0; width: 100%; height: 2px; /* 定义 2px 边框 */ background: #000; transform: scaleY(0.5); /* 垂直方向缩放到 0.5 倍,实际占 1px 物理像素 */ transform-origin: bottom; /* 从底部开始缩放,避免偏移 */ }
-
适配多 DPR(通过媒体查询):
css.border-1px { position: relative; } .border-1px::after { content: ''; position: absolute; left: 0; bottom: 0; width: 100%; background: #000; } /* DPR=2 屏幕 */ @media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) { .border-1px::after { height: 2px; transform: scaleY(0.5); } } /* DPR=3 屏幕 */ @media (-webkit-min-device-pixel-ratio: 3), (min-device-pixel-ratio: 3) { .border-1px::after { height: 3px; transform: scaleY(calc(1/3)); /* 缩放到 1/3,对应 1 个物理像素 */ } }
2. meta
标签配合 rem
适配
-
原理 :通过设置 viewport 的
initial-scale
让 CSS 像素与物理像素一一对应(1px CSS 像素 = 1 物理像素),再用rem
定义尺寸。 -
步骤:
-
设置 viewport:
html<meta name="viewport" content="width=device-width, initial-scale=1/dpr">
(需通过 JS 动态计算
dpr
,设置initial-scale=1/dpr
,例如 DPR=2 时initial-scale=0.5
)。 -
定义
rem
基准值(如html { font-size: 100px; }
),元素边框直接用1px
:css.border { border: 1px solid #000; }
-
-
缺点:会改变整体布局的 CSS 像素映射,可能影响其他元素尺寸(需全局适配,成本较高)。
3. box-shadow
模拟细边框
-
原理 :利用阴影的
spread-radius
(扩散半径)和blur-radius
(模糊半径)模拟 1px 线条(视觉上更纤细)。 -
代码示例:
css.border-1px { box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5); /* 底部 1px 阴影 */ }
-
优点:无需定位和缩放,实现简单;
-
缺点 :阴影有模糊效果,非纯线条,精度低于
scale
方法。
4. background-image
线性渐变
-
原理 :用线性渐变绘制 1px 高的线条,通过
background-size
适配不同 DPR。 -
代码示例(DPR=2 时):
css.border-1px { background-image: linear-gradient(to bottom, #000 0%, #000 100%); background-position: bottom; background-repeat: no-repeat; background-size: 100% 1px; /* 实际占 1 物理像素 */ }
-
适配多 DPR :通过媒体查询修改
background-size
(如 DPR=3 时background-size: 100% 0.333px
)。
四、注意事项
-
边框方向处理:
- 上述方法默认实现底部边框,如需顶部、左侧或右侧边框,需调整
transform-origin
(如顶部边框用transform-origin: top
)或background-position
。 - 全边框(四周)需用伪元素绘制 4 个方向,或用
box-shadow: 0 0 0 1px #000
配合缩放。
- 上述方法默认实现底部边框,如需顶部、左侧或右侧边框,需调整
-
圆角边框特殊处理:
- 用
transform: scale
时,伪元素需设置border-radius
并同步缩放(如原圆角4px
,缩放后需设8px
再缩放到0.5
倍)。
- 用
-
性能考量:
- 优先使用
transform: scale
或box-shadow
,避免频繁使用background-image
(可能增加渲染开销)。
- 优先使用
-
兼容性:
-
transform: scale
兼容 iOS 8+、Android 4.4+,覆盖绝大多数移动端设备; -
低版本 Android(≤4.3)可能存在缩放模糊问题,需结合
meta
标签适配。
-
五、复习速记表
实现方法 | 核心原理 | 优点 | 缺点 |
---|---|---|---|
transform: scale(0.5) |
放大边框后缩放,对应 1 物理像素 | 精度高、适配多 DPR、兼容性好 | 需处理边框方向和圆角 |
meta + rem 适配 | 让 CSS 像素与物理像素一一对应 | 实现简单,全页面统一适配 | 影响整体布局,适配成本高 |
box-shadow 模拟 |
用阴影扩散半径实现细边框 | 无需定位和缩放,代码简洁 | 有模糊效果,精度低 |
background-image 渐变 |
线性渐变绘制 1px 线条 | 适配多 DPR,无缩放问题 | 渲染开销略高,方向控制复杂 |
六、总结
移动端实现真正 1px 的核心是 "适配设备像素比(DPR)" ,通过缩放、阴影或渐变让 CSS 定义的像素对应 1 个物理像素。实际开发中,transform: scale
配合媒体查询是最优方案(精度高、兼容性好、成本低),需重点掌握其边框方向和圆角处理技巧,兼顾视觉效果与性能。
8:BFC
一、核心概念
BFC(块级格式化上下文) 是一个独立的渲染区域,规定了内部的块级元素如何布局,并且与外部元素相互隔离。其核心作用是清除浮动、防止 margin 重叠等布局问题。
-
触发条件 :
-
根元素 (
<html>
); -
浮动元素 (
float
值为left
或right
); -
绝对定位元素 (
position
值为absolute
或fixed
); -
行内块元素 (
display
值为inline-block
); -
表格单元格 (
display
值为table-cell
); -
弹性元素 (
display
值为flex
或inline-flex
的直接子元素); -
网格元素 (
display
值为grid
或inline-grid
的直接子元素); -
其他 (
overflow
值不为visible
的元素)。
-
-
渲染规则 :
-
BFC内部元素的布局不受外部影响;
-
浮动元素、绝对定位元素、行内块元素会创建 BFC;
-
BFC 区域不会与浮动元素的 margin 重叠;
-
BFC 计算高度时会包含浮动元素(即清除浮动)。
-
二、作用与应用场景
1. 清除浮动
-
问题:父元素未设置高度时,浮动子元素会导致父元素高度塌陷。
-
解决:让父元素创建 BFC,计算高度时包含浮动子元素。
css.parent { overflow: hidden; /* 触发 BFC 清除浮动 */ } .child { float: left; }
2. 防止 margin 重叠
-
问题:相邻块级元素的垂直 margin 会发生重叠(取较大值)。
-
解决:将元素放入不同的 BFC 中,使其 margin 不重叠。
css.container { overflow: hidden; /* 触发 BFC */ } .box { margin: 10px 0; }
3. 自适应两栏布局
-
问题:浮动元素与普通元素相邻时,普通元素内容会环绕浮动元素。
-
解决:让普通元素创建 BFC,使其内容不与浮动元素重叠。
css.sidebar { float: left; width: 200px; } .main-content { overflow: hidden; /* 触发 BFC,不与浮动元素重叠 */ }
三、触发 BFC 的常用方式及对比
触发方式 | 原理 | 优点 | 缺点 |
---|---|---|---|
float: left/right |
浮动元素创建 BFC | 兼容性好 | 脱离文档流,需处理父元素高度塌陷 |
position: absolute/fixed |
绝对定位元素创建 BFC | 布局灵活 | 脱离文档流,可能影响其他元素 |
display: inline-block |
行内块元素创建 BFC | 不脱离文档流 | 元素间可能出现空格间隙 |
overflow: hidden |
溢出隐藏触发 BFC | 不脱离文档流,简单易用 | 内容溢出会被隐藏 |
display: flex/grid |
弹性 / 网格容器的子元素创建 BFC | 现代布局方式,功能强大 | 兼容性要求较高(IE11 部分支持) |
四、典型应用案例
1. 清除浮动的三种方案
css
/* 方案一:使用 overflow:hidden */
.parent {
overflow: hidden; /* 触发 BFC 清除浮动 */
}
/* 方案二:使用伪元素(推荐) */
.parent::after {
content: '';
display: block;
clear: both;
}
/* 方案三:使用 display: flow-root(现代浏览器) */
.parent {
display: flow-root; /* 专门用于创建 BFC 清除浮动 */
}
2. 防止 margin 重叠
CSS
.container {
overflow: hidden; /* 触发 BFC */
}
.box {
margin: 20px 0;
}
HTML
<div class="container">
<div class="box">Box 1</div>
</div>
<div class="container">
<div class="box">Box 2</div>
</div>
3. 自适应两栏布局
CSS
.sidebar {
float: left;
width: 30%;
}
.main-content {
overflow: hidden; /* 触发 BFC,不与浮动元素重叠 */
}
HTML
<div class="sidebar">侧边栏</div>
<div class="main-content">主要内容区域</div>
五、注意事项与避坑指南
-
BFC 与浮动的关系:
- 创建 BFC 的元素会包含浮动子元素(清除浮动),但自身浮动时会脱离文档流(可能导致父元素高度塌陷)。
-
避免过度使用 BFC:
- 触发 BFC 的元素会隔离内部布局,可能影响其他元素(如
overflow: hidden
会隐藏溢出内容)。
- 触发 BFC 的元素会隔离内部布局,可能影响其他元素(如
-
兼容性考量:
display: flow-root
是最直接的 BFC 创建方式,但兼容性较差(Chrome 58+、Firefox 53+),需配合前缀或降级方案。
-
margin 重叠的其他解决方案:
- 除了创建 BFC,还可通过设置
border
、padding
或flex/grid
布局避免 margin 重叠。
- 除了创建 BFC,还可通过设置
六、复习速记表
核心概念 | 触发条件 | 主要作用 | 典型应用场景 |
---|---|---|---|
BFC(块级格式化上下文) | 浮动、绝对定位、行内块、overflow:hidden 等 | 清除浮动、防止 margin 重叠、隔离布局 | 自适应两栏布局、清除浮动、防止 margin 重叠 |
触发方式 | float: left/right 、overflow: hidden 、display: inline-block 等 |
不同方式优缺点各异,需根据场景选择 | 清除浮动用 overflow:hidden 或伪元素 |
注意事项 | 避免过度使用,注意兼容性 | BFC 元素与浮动元素的区别 | 现代浏览器可用 display: flow-root |
七、总结
BFC 是 CSS 布局中的核心概念,通过创建独立 的渲染区域 解决浮动、margin 重叠等问题。核心 在于理解其触发条件和渲染规则 ,并能根据场景选择合适的触发方式(如清除浮动优先用伪元素或 display: flow-root
,防止 margin 重叠用 overflow: hidden
)。掌握 BFC 是解决复杂布局问题的基础,需重点复习其应用场景和避坑指南。
9:sticky 粘性布局
一、核心概念
position: sticky
(粘性布局)是 CSS 中一种结合了 relative
(相对定位)和 fixed
(固定定位)特性的布局方式,核心特点是:元素在滚动过程中,未达到触发阈值时表现为相对定位(随页面滚动),达到阈值后表现为固定定位(吸附在指定位置)。
-
核心逻辑 :需通过
top
/bottom
/left
/right
设定 "触发阈值"(如top: 0
),当元素滚动到距离视口边缘小于等于阈值时,自动固定;超出父元素范围后,恢复随父元素滚动。 -
与其他定位的区别:
-
relative
:始终相对自身原位置偏移,不脱离文档流。 -
fixed
:始终相对视口固定,完全脱离文档流。 -
sticky
:动态切换 "相对定位" 和 "固定定位",仅在父元素范围内生效(不脱离父元素文档流)。
-
二、作用与适用场景
1. 核心作用
-
滚动时保持关键元素可见:在页面滚动过程中,让重要元素(如导航栏、列表标题)在进入视口特定位置后固定,提升用户体验(无需反复滚动查找)。
-
兼顾布局自然性:未达到阈值时随内容滚动(不突兀),达到阈值后固定(不遮挡核心内容)。
2. 典型适用场景
-
导航栏 :滚动页面时,导航栏在顶部固定(如
top: 0
),方便用户快速切换页面。 -
列表标题:长列表中,当前分类标题在顶部固定(如通讯录的字母标题)。
-
侧边栏目录:文档页面中,侧边目录随滚动固定,方便定位当前阅读位置。
三、具体实现与代码示例
1. 基础用法(导航栏固定)
HTML
<nav class="sticky-nav">导航栏</nav>
<main>长内容区域...</main>
CSS
/* CSS */
.sticky-nav {
position: sticky; /* 启用粘性布局 */
top: 0; /* 触发阈值:距离视口顶部 0px 时固定 */
background: white;
z-index: 100; /* 避免被其他元素遮挡 */
}
- 效果 :页面滚动时,导航栏随内容向上滚动;当导航栏顶部接触视口顶部(
top: 0
)时,固定在顶部,不再随滚动移动。
2. 列表标题固定(分类列表场景)
HTML
<div class="list">
<h3 class="category-title">A</h3>
<p>列表项 A1</p>
<p>列表项 A2</p>
<h3 class="category-title">B</h3>
<p>列表项 B1</p>
<p>列表项 B2</p>
</div>
CSS
/* CSS */
.category-title {
position: sticky;
top: 20px; /* 距离视口顶部 20px 时固定 */
background: #f5f5f5;
padding: 8px;
}
- 效果:滚动列表时,当前分类标题(如 "A")随内容滚动;当距离视口顶部 20px 时固定,直到下一个分类标题("B")滚动到相同位置并 "顶掉" 它。
四、关键注意事项(避坑点)
-
必须设置触发阈值(
top
/bottom
等)sticky
生效的前提是设置top
/bottom
/left
/right
中的至少一个(否则表现为relative
)。- 示例 :
position: sticky
但未设置top
,元素始终随滚动移动,不固定。
-
父元素限制(核心坑点)
-
父元素不能有
overflow: hidden
/auto
/scroll
:若父元素设置了overflow: hidden
,sticky
会失效(父元素裁剪了滚动范围,无法触发固定)。CSS/* 错误示例:父元素有 overflow: hidden,sticky 失效 */ .parent { overflow: hidden; } .sticky-child { position: sticky; top: 0; }
-
父元素高度必须大于子元素:若父元素高度等于或小于子元素,
sticky
无法触发固定(子元素没有滚动空间)。
-
-
层级与遮挡问题
-
sticky
元素固定后,可能遮挡下方内容,需通过z-index
调整层级(确保在合理层级,不遮挡核心内容)。 -
示例 :导航栏固定后遮挡正文,可给正文添加
padding-top
(等于导航栏高度)。
-
-
兼容性
-
支持现代浏览器(Chrome 56+、Firefox 59+、Safari 6.1+、Edge 16+)。
-
低版本浏览器(如 IE 全版本)不支持,需通过 JS 模拟(监听
scroll
事件动态修改position
)。
-
五、与其他定位的对比表
定位方式 | 核心行为 | 生效范围 | 适用场景 |
---|---|---|---|
sticky |
未达阈值:相对定位;达阈值:固定定位 | 父元素范围内 | 导航栏、列表标题 |
relative |
相对自身原位置偏移,始终随滚动移动 | 文档流中 | 微调元素位置(如图标偏移) |
fixed |
始终相对视口固定,脱离文档流 | 全局视口 | 悬浮按钮、全局弹窗 |
六、复习速记表
核心要素 | 关键细节 | 示例代码 |
---|---|---|
语法与阈值 | position: sticky + top /bottom 等 |
.nav { position: sticky; top: 0; } |
生效条件 | 必须设置阈值、父元素无 overflow: hidden 、父元素高度大于子元素 |
- |
典型场景 | 导航栏固定、列表标题吸附 | 页面滚动时导航栏在顶部固定 |
常见坑点 | 父元素 overflow: hidden 导致失效、未设置阈值 |
避免父元素有 overflow: hidden |
七、总结
sticky
粘性布局 的核心是 "动态切换相对定位与固定定位" ,通过设置触发阈值(top
等),在滚动时保持关键元素可见,是提升滚动体验的高效方案。
复习重点 :掌握 sticky
的生效条件(阈值、父元素限制)、常见坑点(父元素 overflow
问题)及适用场景,这是考试和实际开发的核心考点。
10. animation 动画
一、核心概念
CSS Animation 是通过 @keyframes
定义动画序列,并应用于元素的技术,可实现复杂的多帧动画效果。与 transition
(过渡)相比,Animation 支持多关键帧、自动循环、方向控制等更丰富的特性。
-
核心组件:
-
@keyframes
:定义动画名称和关键帧(如 0%、50%、100% 时的样式)。 -
动画属性 :如
animation-name
、animation-duration
、animation-iteration-count
等,用于控制动画播放。
-
二、作用与优势
1. 核心作用
-
创建复杂动画:实现多阶段、多属性变化的动画(如元素从左到右移动并旋转)。
-
自动播放:无需交互触发(如悬停),页面加载后直接执行。
-
循环控制:支持无限循环(如轮播图、加载指示器)。
2. 与 transition
的对比
特性 | transition |
animation |
---|---|---|
触发方式 | 需要事件触发(如 :hover 、JS 修改属性) |
自动播放或通过 animation-play-state 控制 |
关键帧数量 | 仅 2 帧(开始和结束) | 支持多帧(如 0%、25%、50% 等) |
循环能力 | 不支持循环 | 支持 infinite 或指定次数循环 |
时间函数 | 仅控制整体过渡曲线(如 ease-in-out ) |
每个关键帧可单独设置时间函数 |
方向控制 | 仅支持正向 / 反向(reverse ) |
支持 normal 、reverse 、alternate 等 |
三、具体实现步骤与代码示例
1. 定义动画(@keyframes
)
CSS
/* 定义名为 fadeIn 的淡入动画 */
@keyframes fadeIn {
0% { opacity: 0; transform: translateY(20px); }
100% { opacity: 1; transform: translateY(0); }
}
/* 定义名为 pulse 的呼吸动画 */
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
2. 应用动画到元素
CSS
.element {
animation-name: fadeIn; /* 指定动画名称 */
animation-duration: 1s; /* 动画持续时间 */
animation-timing-function: ease-out; /* 时间函数 */
animation-delay: 0.5s; /* 延迟开始 */
animation-iteration-count: 2; /* 播放次数(或 infinite) */
animation-direction: alternate; /* 交替播放(正向→反向→正向...) */
animation-fill-mode: forwards; /* 动画结束后保持最后一帧状态 */
}
CSS
/* 简写形式 */
.element {
animation: fadeIn 1s ease-out 0.5s 2 alternate forwards;
}
3. 多关键帧动画示例(旋转 + 变色)
CSS
@keyframes rotateAndColor {
0% { transform: rotate(0deg); background: red; }
50% { transform: rotate(180deg); background: yellow; }
100% { transform: rotate(360deg); background: blue; }
}
.box {
animation: rotateAndColor 3s infinite linear;
}
四、关键属性详解(复习重点)
属性 | 作用 | 取值示例 |
---|---|---|
animation-name |
指定动画名称(对应 @keyframes 定义) |
fadeIn |
animation-duration |
动画持续时间(秒或毫秒) | 2s 或 2000ms |
animation-timing-function |
时间函数(控制动画速度曲线) | ease 、linear 、ease-in-out |
animation-delay |
延迟开始时间 | 0.5s |
animation-iteration-count |
播放次数 | 2 、infinite |
animation-direction |
播放方向 | normal 、reverse 、alternate |
animation-fill-mode |
动画前后的状态保持 | forwards (停在最后一帧)、both |
animation-play-state |
控制动画暂停 / 播放 | running 、paused |
五、应用场景与注意事项
1. 典型应用场景
-
加载指示器 :如旋转的加载圈(
infinite
循环)。 -
提示动画:如按钮点击后的缩放反馈(单次播放)。
-
元素入场 / 退场 :如淡入淡出、滑入滑出(结合
animation-fill-mode
)。
2. 性能优化
-
优先使用
transform
和opacity
:这两个属性仅触发合成层(Compositing),性能开销远低于修改width
、top
等(避免回流 / 重绘)。CSS/* 推荐:仅触发合成层 */ @keyframes move { 0% { transform: translateX(0); } 100% { transform: translateX(100px); } } /* 不推荐:触发回流/重绘 */ @keyframes moveBad { 0% { left: 0; } 100% { left: 100px; } }
-
控制动画元素数量:大量复杂动画会消耗性能,避免在同一页面使用过多动画。
3. 兼容性处理
-
主流浏览器(Chrome 43+、Firefox 16+、Safari 9+)均支持,但需添加前缀(如
-webkit-
):CSS@-webkit-keyframes fadeIn { /* ... */ } @keyframes fadeIn { /* ... */ } .element { -webkit-animation: fadeIn 1s; animation: fadeIn 1s; }
-
低版本浏览器(如 IE10-)不支持,需降级为
transition
或用 JS 实现。
六、复习速记表
核心要素 | 关键细节 | 示例代码 |
---|---|---|
定义动画 | @keyframes 名称 { 0% { ... } 100% { ... } } |
@keyframes fade { 0% { opacity: 0; } } |
应用动画 | animation: 名称 持续时间 时间函数 ... |
.box { animation: fade 1s ease; } |
关键属性 | duration 、iteration-count 、direction 、fill-mode |
.box { animation: fade 2s infinite alternate; } |
性能优化 | 优先使用 transform /opacity |
@keyframes move { transform: translateX(100px); } |
七、总结
CSS Animation 的核心是 "通过 @keyframes
定义多帧动画序列,并通过动画属性控制播放"。掌握关键属性(如 iteration-count
、fill-mode
)和性能优化(优先使用 transform
)是考点重点。与 transition
对比记忆,明确各自适用场景(简单过渡用 transition
,复杂多帧动画用 animation
)。
最后
本文系统梳理了从 Flex 布局、BFC 到硬件加速等 10 个 CSS 核心模块,希望能帮你构建一个清晰的知识体系,无论是在项目开发还是面试中都能游刃有余。
CSS 的学习永无止境,但掌握这些核心基础是关键的第一步。下一节,我们将进入另一个前端面试的重头戏------ Vue 原理,敬请期待!
觉得有用的话点赞收藏呀~你在学习 CSS 时,哪个属性或概念曾让你最头疼?欢迎在评论区分享你的故事!
更多
💻 Vue3 多端统一开发框架:vue3-multi-platform
📊 HuggingFaceAI论文智能分析系统:ai-paper-analyzer