CSS3 核心
前言
CSS3 是 Cascading Style Sheets 的第三个版本,为网页样式设计带来了革命性的变化。它引入了模块化的架构,新增了丰富的选择器、布局模式、动画效果和响应式设计能力。本文档全面梳理 CSS3 的核心知识点,从基础盒模型到现代布局技术,帮助开发者系统掌握 CSS3。
一、CSS 盒模型
1.1 盒模型基础
CSS 盒模型(Box Model)是所有布局的基石。每个 HTML 元素都可以看作一个矩形盒子,由以下四部分组成:
- content(内容区):显示文本或图像的区域
- padding(内边距):内容区与边框之间的透明区域
- border(边框):围绕 padding 的边框线
- margin(外边距):盒子与其他元素之间的间距
1.2 content-box vs border-box
box-sizing 属性决定了元素的 width/height 如何计算:
| 属性值 | 含义 | 总宽度计算 |
|---|---|---|
content-box(默认) | width 仅作用于内容区 | width + padding + border |
border-box | width 包含 content + padding + border | width |
/* 全局推荐设置 */
*, *::before, *::after {
box-sizing: border-box;
}使用 border-box 可以显著简化布局计算,避免因添加 padding 或 border 而导致容器溢出。
1.3 margin 折叠
当两个垂直方向的块级元素的外边距相遇时,它们会折叠(collapse)成一个外边距,取两者中的较大值。
折叠规则:
- 相邻的垂直兄弟元素之间的 margin 会折叠
- 父元素与第一个/最后一个子元素之间(没有 border、padding、BFC 隔断时)的 margin 会折叠
- 空的块级元素(没有内容、border、padding、height)自身的 margin-top 和 margin-bottom 会折叠
避免 margin 折叠的方法:
- 给父元素添加
overflow: hidden触发 BFC - 使用
padding代替margin - 使用 Flexbox 或 Grid 布局(它们内部不会发生 margin 折叠)
二、Flexbox 布局
Flexbox(弹性盒布局)是一维布局模型,擅长处理行或列方向上的元素排列。
2.1 主轴与交叉轴
Flexbox 包含两个核心轴:
- 主轴(main axis):由
flex-direction决定,默认为水平方向(row) - 交叉轴(cross axis):垂直于主轴的轴
.container {
display: flex;
flex-direction: row; /* 主轴:水平 */
flex-direction: column; /* 主轴:垂直 */
}2.2 容器属性
| 属性 | 作用 | 常用值 |
|---|---|---|
justify-content | 主轴上的对齐方式 | flex-start, center, flex-end, space-between, space-around, space-evenly |
align-items | 交叉轴上的对齐方式 | stretch, flex-start, center, flex-end, baseline |
flex-wrap | 是否换行 | nowrap, wrap, wrap-reverse |
align-content | 多行时交叉轴上的对齐方式 | stretch, flex-start, center, space-between |
2.3 项目属性
flex 属性是 flex-grow、flex-shrink、flex-basis 的简写:
.item {
flex: 1; /* 等效于 flex: 1 1 0% */
flex: 1 1 200px; /* 可增长、可收缩、基准 200px */
flex: 0 0 auto; /* 不增长、不收缩、按内容尺寸 */
}| 属性 | 含义 |
|---|---|
flex-grow | 剩余空间的分配比例,默认为 0 |
flex-shrink | 空间不足时的收缩比例,默认为 1 |
flex-basis | 项目在分配空间前的基准尺寸 |
2.4 对齐方式详解
/* 水平垂直居中 */
.container {
display: flex;
justify-content: center;
align-items: center;
}
/* 自适应导航栏 */
.nav {
display: flex;
gap: 1rem;
}
.nav .spacer {
margin-left: auto; /* 将后面的项目推到右侧 */
}三、Grid 布局
CSS Grid 是二维布局模型,可以同时处理行和列,是最强大的 CSS 布局方案。
3.1 网格容器
.container {
display: grid;
grid-template-columns: 200px 1fr 2fr; /* 三列:固定 + 等分 + 2倍等分 */
grid-template-rows: auto 300px; /* 两行:自适应 + 固定 */
gap: 16px; /* 简写 grid-row-gap 和 grid-column-gap */
}3.2 fr 单位
fr(fraction)是 Grid 特有的弹性单位,表示剩余空间的比例分配:
/* 三列等宽 */
grid-template-columns: 1fr 1fr 1fr;
/* 侧边栏固定 + 主内容弹性 */
grid-template-columns: 240px 1fr;
/* 圣杯布局 */
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;3.3 grid-template-areas 与 grid-area
通过命名区域实现直观的布局:
.container {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }3.4 auto-fit 与 auto-fill
这两个关键字用于自动填充网格轨道:
/* auto-fill:尽可能多地创建轨道,即使它们是空的 */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* auto-fit:与 auto-fill 类似,但空轨道会被折叠 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));区别: auto-fill 会保留空轨道的空间,auto-fit 会将空轨道折叠为 0,让已有项目自动扩展。
3.5 Grid 实战示例
/* 响应式图片画廊 */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
.gallery img {
width: 100%;
height: 250px;
object-fit: cover;
}四、CSS 定位
4.1 position 属性一览
| 属性值 | 定位基准 | 是否脱离文档流 | 特点 |
|---|---|---|---|
static | 默认值 | 否 | 正常文档流 |
relative | 元素自身原位置 | 否 | 保留原空间,top/left 偏移 |
absolute | 最近的定位祖先(非 static) | 是 | 相对于定位祖先偏移 |
fixed | 视口(viewport) | 是 | 固定不动,常用于悬浮导航 |
sticky | 滚动容器 + 最近可滚动祖先 | 否 | 相对与固定之间切换 |
4.2 定位示例
/* relative - 相对自身偏移 */
.badge {
position: relative;
top: -4px;
left: 4px;
}
/* absolute - 相对于父容器定位 */
.card {
position: relative;
}
.card .tag {
position: absolute;
top: 8px;
right: 8px;
}
/* fixed - 固定导航栏 */
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
}
/* sticky - 吸顶效果 */
.section-header {
position: sticky;
top: 0;
background: white;
z-index: 10;
}4.3 z-index 与层叠上下文
z-index 仅在定位元素(非 static)上生效。层叠上下文(stacking context)是 z-index 的管辖范围,以下属性会创建新的层叠上下文:
position: relative/absolute且z-index不是 autoopacity小于 1transform、filter、perspective不为 noneisolation: isolate
五、CSS 动画
5.1 transition(过渡)
过渡用于元素从一种样式平滑变化到另一种样式:
.button {
background: blue;
color: white;
transition: all 0.3s ease;
}
.button:hover {
background: darkblue;
transform: translateY(-2px);
}过渡属性分解:
transition: property duration timing-function delay;
/* 示例 */
transition: transform 0.3s ease-in-out, background-color 0.2s linear;常用的 timing-function:
ease:慢-快-慢(默认)linear:匀速ease-in:慢速开始ease-out:慢速结束ease-in-out:两端慢cubic-bezier(n, n, n, n):自定义贝塞尔曲线
5.2 transform(变换)
transform: translateX(50px); /* 平移 */
transform: scale(1.5); /* 缩放 */
transform: rotate(45deg); /* 旋转 */
transform: skew(10deg, 5deg); /* 倾斜 */
transform-origin: center center; /* 变换原点 */5.3 @keyframes 与 animation
/* 定义关键帧 */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
/* 应用动画 */
.element {
animation: fadeIn 0.5s ease-out forwards;
}
.element.pulse {
animation: pulse 2s ease-in-out infinite;
}animation 属性简写:
animation: name duration timing-function delay iteration-count direction fill-mode play-state;
/* 示例 */
animation: slideIn 0.3s ease-out 0s 1 normal forwards running;| 属性 | 含义 |
|---|---|
animation-name | @keyframes 名称 |
animation-duration | 持续时间 |
animation-timing-function | 缓动函数 |
animation-delay | 延迟时间 |
animation-iteration-count | 播放次数(infinite 无限) |
animation-direction | 方向(normal, reverse, alternate) |
animation-fill-mode | 填充模式(none, forwards, backwards, both) |
animation-play-state | 播放状态(running, paused) |
5.4 性能优化建议
- 优先使用
transform和opacity进行动画,它们由 GPU 合成 - 避免对
width、height、top、left等几何属性做动画 - 使用
will-change提示浏览器进行优化 - 合理使用
requestAnimationFrame替代setTimeout/setInterval
六、响应式设计
6.1 媒体查询
/* 手机(默认) */
.container { padding: 16px; }
/* 平板 >= 768px */
@media (min-width: 768px) {
.container { padding: 24px; }
}
/* 桌面 >= 1024px */
@media (min-width: 1024px) {
.container { padding: 32px; }
}
/* 大屏 >= 1440px */
@media (min-width: 1440px) {
.container { max-width: 1200px; margin: 0 auto; }
}其他常用媒体特性:
/* 横屏/竖屏 */
@media (orientation: landscape) { ... }
@media (orientation: portrait) { ... }
/* 偏好检测 */
@media (prefers-color-scheme: dark) { ... } /* 深色模式 */
@media (prefers-reduced-motion: reduce) { ... } /* 减少动效 */6.2 rem 与 em
rem:相对于根元素(html)的font-size,全局一致em:相对于父元素的font-size,会级联累积
html { font-size: 16px; }
/* 1rem = 16px */
.title { font-size: 2rem; } /* 32px */
.desc { font-size: 1rem; } /* 16px */
/* em 会叠加 */
.parent { font-size: 1.2em; } /* 19.2px */
.parent .child { font-size: 1.2em; } /* 23.04px(叠加) */6.3 vw / vh / vmin / vmax
| 单位 | 含义 |
|---|---|
vw | 视口宽度的 1% |
vh | 视口高度的 1% |
vmin | vw 与 vh 中较小者 |
vmax | vw 与 vh 中较大者 |
/* 全屏英雄区域 */
.hero {
height: 100vh;
width: 100vw;
}
/* 自适应字体 */
h1 { font-size: calc(1rem + 3vw); }
/* 防止内容被手机地址栏遮挡 */
.content {
min-height: 100dvh; /* dynamic viewport height */
}6.4 clamp() 函数
clamp() 限制一个值在最小值和最大值之间:
/* 响应式字体:1rem ~ 3rem 之间,基于视口宽度 */
h1 {
font-size: clamp(1.5rem, 2.5vw + 1rem, 3rem);
}
/* 响应式 padding */
.card {
padding: clamp(1rem, 3vw, 2rem);
}
/* 响应式宽度 */
.container {
width: clamp(320px, 80vw, 1200px);
}6.5 容器查询(Container Queries)
容器查询允许根据父容器的大小而非视口来调整样式,是比媒体查询更精细的响应式方案:
/* 定义容器 */
.card-container {
container-type: inline-size;
container-name: card;
}
/* 基于容器宽度的样式 */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}容器查询单位:
@container (min-width: 500px) {
.title {
font-size: 3cqw; /* 容器宽度的 3% */
padding: 2cqi; /* 容器内联尺寸的 2% */
margin: 1cqb; /* 容器块向尺寸的 1% */
height: 10cqmin; /* 容器较小尺寸的 10% */
}
}七、CSS 自定义属性与 calc()
7.1 CSS 变量(自定义属性)
CSS 自定义属性允许在样式表中存储和复用值:
:root {
--primary-color: #3498db;
--text-color: #333;
--spacing-unit: 8px;
--border-radius: 4px;
--max-width: 1200px;
}
.button {
background: var(--primary-color);
color: white;
padding: calc(var(--spacing-unit) * 2) calc(var(--spacing-unit) * 3);
border-radius: var(--border-radius);
}作用域与覆盖:
.card {
--card-bg: white;
--card-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.card.dark {
--card-bg: #1a1a2e;
--card-shadow: 0 2px 8px rgba(0,0,0,0.4);
}7.2 calc() 函数
calc() 允许在 CSS 中执行数学运算,混合不同单位:
/* 混合单位运算 */
.sidebar {
width: calc(100% - 240px);
}
/* 复杂计算 */
.card {
width: calc((100% / 3) - 20px);
}
/* 结合 CSS 变量 */
.element {
padding: calc(var(--spacing-unit) * 3);
font-size: calc(1rem + 0.5vw);
top: calc(50% - 20px);
}calc() 使用规则:
- 支持
+、-、*、/ +和-两侧必须加空格- 可以混合不同的 CSS 单位
- 支持嵌套使用
八、最佳实践与性能优化
8.1 选择器优化
- 避免使用通配选择器
* - 减少选择器嵌套层级(不超过 3 层)
- 使用类选择器代替标签选择器
- 避免使用
!important(除非覆盖第三方样式)
8.2 布局策略
- 默认使用 Flexbox 处理一维布局
- 使用 Grid 处理二维布局
- 优先使用
gap代替margin做间距 - 使用
min-height: 100vh代替height: 100vh避免内容溢出
8.3 动画性能
- 仅对
transform和opacity做动画 - 使用
will-change提示浏览器预优化 transform: translateZ(0)触发 GPU 加速(但慎用,会占用显存)
8.4 响应式策略
- 移动优先(Mobile First):先写基础样式,再用
min-width媒体查询逐步增强 - 使用
clamp()实现自适应尺寸 - 使用 CSS 变量管理主题和断点值
- 考虑容器查询提升组件复用性
8.5 代码组织
/* 推荐:按功能组织 CSS */
/* 1. 重置/基础样式 */
/* 2. CSS 变量 */
/* 3. 布局组件 */
/* 4. UI 组件 */
/* 5. 工具类 */8.6 其他优化建议
- 使用 CSS 压缩工具减少文件体积
- 提取公共样式,避免重复声明
- 使用
content-visibility: auto优化长页面渲染性能 - 避免使用
@import,改用<link>加载样式 - 使用现代 CSS 特性(Grid、Flexbox)替代老旧方案(float、table)
参考资源
Demo 演示
以下是一个结合 Grid 布局和 Flexbox 的实际演示页面: