CSS
一、CSS 选择器与优先级
1. CSS 选择器类型及优先级计算
问题:CSS 选择器有哪些类型?优先级如何计算?哪些属性可以继承?
答案: CSS 选择器类型:
-
基础选择器:
- 元素选择器:
p { } - 类选择器:
.class { } - ID选择器:
#id { } - 通配符选择器:
* { }
- 元素选择器:
-
属性选择器:
[attr]:具有指定属性[attr=value]:属性等于特定值[attr^=value]:属性以特定值开头[attr$=value]:属性以特定值结尾[attr*=value]:属性包含特定值
-
伪类选择器:
- 状态伪类:
:hover,:focus,:active,:visited,:checked - 结构伪类:
:first-child,:last-child,:nth-child(n),:nth-of-type(n) - 表单伪类:
:required,:optional,:valid,:invalid
- 状态伪类:
-
伪元素选择器:
::before,::after:生成内容::first-line,::first-letter:文本首行/首字母::selection:用户选中部分
-
组合选择器:
- 后代选择器:
div p - 子元素选择器:
div > p - 相邻兄弟选择器:
h1 + p - 通用兄弟选择器:
h1 ~ p - 并集选择器:
h1, h2, h3
- 后代选择器:
优先级计算规则: 优先级由4个级别组成(a, b, c, d):
- a:行内样式(1,0,0,0)
- b:ID选择器数量(0,1,0,0)
- c:类/属性/伪类选择器数量
- d:元素/伪元素选择器数量
计算示例:
#header .nav li.active a:hover { }
/* 计算:0,1,3,2 → 优先级:0,1,3,2 */
body div#main .content p { }
/* 计算:0,1,1,3 → 优先级:0,1,1,3 */
!important 规则:
p { color: red !important; } /* 最高优先级 */
可继承属性:
- 文本相关:
color,font-family,font-size,font-weight,line-height,text-align,text-indent - 列表相关:
list-style-type,list-style-image - 表格相关:
border-collapse,border-spacing - 其他:
visibility,cursor,direction,letter-spacing,word-spacing
不可继承属性:
- 盒模型属性:
width,height,margin,padding,border - 定位属性:
position,top,left,float,display - 背景属性:
background,background-color,background-image
代码示例:
/* 优先级演示 */
#header .nav a { color: blue; } /* 0,1,1,1 */
.header nav a { color: green; } /* 0,0,2,1 */
nav a { color: red; } /* 0,0,0,2 */
a { color: black; } /* 0,0,0,1 */
/* 继承演示 */
.parent {
color: #333;
font-family: Arial;
line-height: 1.5;
}
.child {
/* 自动继承父级的 color, font-family, line-height */
border: 1px solid #ccc; /* 需明确设置 */
}
补充说明:
- 避免过度使用ID选择器和!important
- 使用类选择器提高可复用性
- 合理使用继承减少代码重复
- 了解CSS层叠规则:重要性 > 来源 > 优先级 > 位置
二、盒模型
2. 盒模型详解与 box-sizing
问题:CSS 盒模型是什么?包含哪些部分?W3C标准盒模型与IE盒模型区别?box-sizing属性的作用?
答案: 盒模型定义:CSS将每个元素视为一个矩形盒子,包含内容、内边距、边框、外边距。
盒模型组成:
- 内容区域:width × height
- 内边距:padding
- 边框:border
- 外边距:margin
两种盒模型对比:
| 模型 | 计算方式 | 总宽度公式 | 特点 |
|---|---|---|---|
| W3C标准盒模型 (content-box) | width仅包含内容 | 总宽度 = width + padding + border + margin | 默认值,符合CSS标准 |
| IE盒模型 (border-box) | width包含内容+padding+border | 总宽度 = width + margin | 更直观,易于布局控制 |
可视化表示:
/* content-box (默认) */
元素总宽度 = width(200) + padding(20×2) + border(2×2) + margin(10×2) = 264px
内容宽度 = 200px
/* border-box */
元素总宽度 = width(200) + margin(10×2) = 220px
内容宽度 = 200 - padding(20×2) - border(2×2) = 156px
box-sizing 属性:
/* 默认值:标准盒模型 */
.element {
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 2px solid;
/* 实际宽度 = 200 + 40 + 4 = 244px */
}
/* border-box:IE盒模型 */
.element {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 2px solid;
/* 实际宽度 = 200px,内容宽度 = 200 - 40 - 4 = 156px */
}
/* 全局设置 */
* {
box-sizing: border-box;
}
盒模型计算示例:
div {
width: 300px;
height: 200px;
padding: 20px;
border: 5px solid #333;
margin: 15px;
box-sizing: border-box;
}
/* 计算:
内容宽度 = 300 - (20×2) - (5×2) = 250px
内容高度 = 200 - (20×2) - (5×2) = 150px
总宽度 = 300 + (15×2) = 330px
总高度 = 200 + (15×2) = 230px
*/
实际应用场景:
- 栅格系统:
.grid-item {
box-sizing: border-box;
float: left;
width: 33.33%;
padding: 15px;
/* 精确的三栏布局,不考虑padding影响 */
}
- 表单元素:
input, textarea, select {
box-sizing: border-box;
width: 100%;
padding: 8px 12px;
border: 1px solid #ddd;
/* 宽度包含padding和border,避免溢出 */
}
- 响应式设计:
.container {
box-sizing: border-box;
max-width: 1200px;
padding: 0 20px;
margin: 0 auto;
/* 容器宽度包含padding,便于响应式计算 */
}
浏览器兼容性:
- IE8+ 支持
box-sizing: border-box - 现代浏览器完全支持
- 建议使用前缀增强兼容性:
.element {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
最佳实践:
- 全局设置:
/* 重置盒模型 */
*, *::before, *::after {
box-sizing: border-box;
}
/* 特殊情况使用content-box */
img, video, iframe {
box-sizing: content-box;
}
- Flexbox和Grid布局:
/* 默认使用border-box更直观 */
.container {
display: flex;
box-sizing: border-box;
}
.item {
flex: 1;
padding: 20px;
/* 宽度计算包含padding */
}
- CSS自定义属性:
:root {
--box-model: border-box;
}
.element {
box-sizing: var(--box-model);
}
常见问题解决:
- 元素溢出:
/* 问题:padding使元素溢出容器 */
.container { width: 100%; }
/* 解决方案:使用border-box */
.container {
width: 100%;
box-sizing: border-box;
padding: 20px;
}
- 等宽布局:
/* 传统方案:计算复杂 */
.col {
float: left;
width: 25%; /* 期望25% */
padding: 10px; /* 破坏宽度 */
border: 1px solid;
}
/* border-box方案:简单直观 */
.col {
float: left;
width: 25%;
box-sizing: border-box;
padding: 10px; /* 包含在25%内 */
border: 1px solid;
}
- 响应式图片:
img {
max-width: 100%;
height: auto;
box-sizing: content-box; /* 图片通常使用content-box */
}
性能考虑:
box-sizing不会影响渲染性能- 重排/重绘优化:减少盒模型属性变更
- 硬件加速:使用transform替代width/height动画
补充说明:
- 理解盒模型是CSS布局的基础
- 根据项目需求选择合适的盒模型
- 使用开发者工具检查盒模型计算
- 结合现代布局技术(Flexbox/Grid)使用
三、Flexbox 布局
3. Flex 布局原理与应用
问题:Flex 布局的原理及使用场景?Flex 容器和项目属性有哪些?Flex 布局是如何工作的?
答案: Flexbox 概述:Flexible Box布局模型,用于一维布局(行或列),提供更有效的方式分配容器内项目的空间。
核心概念:
- Flex容器:
display: flex或display: inline-flex - Flex项目:容器的直接子元素
- 主轴:项目的排列方向(默认水平)
- 交叉轴:与主轴垂直的方向
Flex容器属性:
- display:
.container {
display: flex; /* 块级Flex容器 */
display: inline-flex; /* 行内Flex容器 */
}
- flex-direction(主轴方向):
.container {
flex-direction: row; /* 默认:水平方向,起点在左端 */
flex-direction: row-reverse; /* 水平方向,起点在右端 */
flex-direction: column; /* 垂直方向,起点在上端 */
flex-direction: column-reverse; /* 垂直方向,起点在下端 */
}
- flex-wrap(换行):
.container {
flex-wrap: nowrap; /* 默认:不换行 */
flex-wrap: wrap; /* 换行,第一行在上方 */
flex-wrap: wrap-reverse; /* 换行,第一行在下方 */
}
- flex-flow(简写):
.container {
flex-flow: row nowrap; /* flex-direction 和 flex-wrap 的简写 */
}
- justify-content(主轴对齐):
.container {
justify-content: flex-start; /* 默认:起点对齐 */
justify-content: flex-end; /* 终点对齐 */
justify-content: center; /* 居中对齐 */
justify-content: space-between; /* 两端对齐,项目间间隔相等 */
justify-content: space-around; /* 每个项目两侧间隔相等 */
justify-content: space-evenly; /* 项目与项目、项目与边框间隔相等 */
}
- align-items(交叉轴对齐):
.container {
align-items: stretch; /* 默认:拉伸占满容器高度 */
align-items: flex-start; /* 起点对齐 */
align-items: flex-end; /* 终点对齐 */
align-items: center; /* 居中对齐 */
align-items: baseline; /* 基线对齐 */
}
- align-content(多行对齐):
.container {
align-content: stretch; /* 默认:拉伸占满容器 */
align-content: flex-start; /* 起点对齐 */
align-content: flex-end; /* 终点对齐 */
align-content: center; /* 居中对齐 */
align-content: space-between; /* 两端对齐 */
align-content: space-around; /* 每个项目两侧间隔相等 */
}
Flex项目属性:
- order(排序):
.item {
order: 0; /* 默认:按照HTML顺序 */
order: 1; /* 数值越大,排列越靠后 */
}
- flex-grow(放大比例):
.item {
flex-grow: 0; /* 默认:不放大 */
flex-grow: 1; /* 有剩余空间时,项目放大 */
}
- flex-shrink(缩小比例):
.item {
flex-shrink: 1; /* 默认:空间不足时,项目缩小 */
flex-shrink: 0; /* 空间不足时,不缩小 */
}
- flex-basis(基准大小):
.item {
flex-basis: auto; /* 默认:项目原本大小 */
flex-basis: 100px; /* 设置基准宽度 */
flex-basis: 50%; /* 百分比基准 */
flex-basis: 0; /* 无内容影响的基础大小 */
}
- flex(简写):
.item {
flex: none; /* 0 0 auto,不伸缩 */
flex: auto; /* 1 1 auto,自动填充 */
flex: 1; /* 1 1 0%,等分剩余空间 */
flex: 0 0 200px; /* 固定200px,不伸缩 */
}
- align-self(项目自身对齐):
.item {
align-self: auto; /* 默认:继承align-items */
align-self: flex-start; /* 起点对齐 */
align-self: flex-end; /* 终点对齐 */
align-self: center; /* 居中对齐 */
align-self: stretch; /* 拉伸 */
}
Flex布局工作原理:
-
分配空间:
- 计算剩余空间 = 容器大小 - 所有项目flex-basis总和
- 根据flex-grow分配剩余空间
- 空间不足时根据flex-shrink缩小项目
-
对齐项目:
- 主轴对齐:justify-content
- 交叉轴对齐:align-items / align-self
- 多行对齐:align-content
常见布局模式:
- 水平居中:
.container {
display: flex;
justify-content: center;
}
- 垂直居中:
.container {
display: flex;
align-items: center;
}
- 完全居中:
.container {
display: flex;
justify-content: center;
align-items: center;
}
- 圣杯布局:
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.header {
flex: 0 0 auto;
}
.main {
flex: 1 0 auto;
display: flex;
}
.content {
flex: 1;
}
.sidebar {
flex: 0 0 200px;
}
.footer {
flex: 0 0 auto;
}
- 等分导航:
.nav {
display: flex;
}
.nav-item {
flex: 1;
text-align: center;
}
- 流式布局:
.container {
display: flex;
flex-wrap: wrap;
}
.item {
flex: 1 0 200px; /* 最小200px,自动换行 */
margin: 10px;
}
- 输入组:
.input-group {
display: flex;
}
.input-group input {
flex: 1;
}
.input-group button {
flex: 0 0 auto;
}
使用场景:
- 导航栏:水平/垂直导航,响应式菜单
- 卡片布局:等高卡片,流式排列
- 表单布局:标签对齐,按钮组
- 媒体对象:图片+文字组合
- 网格系统:响应式栅格
- 居中内容:水平和垂直居中
- 页面布局:头部、内容、页脚
Flexbox vs 传统布局:
| 需求 | 传统方案 | Flexbox方案 |
|---|---|---|
| 垂直居中 | 定位 + transform | align-items: center |
| 等分布局 | float + 计算宽度 | flex: 1 |
| 等高列 | JS计算高度 | align-items: stretch |
| 顺序控制 | 修改HTML | order属性 |
| 自适应空间 | 媒体查询 | flex-grow/flex-shrink |
浏览器兼容性:
- IE10+ 部分支持(需-ms-前缀)
- IE11+ 较好支持
- 现代浏览器完全支持
- 前缀使用:
.container {
display: -webkit-flex; /* Safari */
display: -ms-flexbox; /* IE10 */
display: flex; /* 标准 */
}
性能考虑:
- Flexbox渲染性能优于传统浮动布局
- 避免过度嵌套Flex容器
- 使用flex-basis替代width/height
- 硬件加速优化动画
补充说明:
- 理解主轴和交叉轴概念
- 合理使用flex简写属性
- 结合Grid布局实现复杂二维布局
- 使用开发者工具调试Flexbox
四、Grid 布局
4. Grid 布局特点与应用场景
问题:Grid 布局的特点和应用场景是什么?Grid 布局如何工作?
答案: CSS Grid 概述:二维网格布局系统,可同时处理行和列,适合复杂布局。
核心概念:
- Grid容器:
display: grid或display: inline-grid - Grid项目:容器的直接子元素
- 网格线:划分网格的线条
- 网格轨道:行或列
- 网格单元格:行和列的交叉区域
- 网格区域:一个或多个单元格组成的矩形区域
Grid容器属性:
- grid-template-columns / grid-template-rows:
.container {
/* 定义3列:100px 自适应 200px */
grid-template-columns: 100px 1fr 200px;
/* 定义2行:100px 自适应 */
grid-template-rows: 100px 1fr;
/* repeat()函数 */
grid-template-columns: repeat(3, 1fr); /* 3等分 */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* 命名网格线 */
grid-template-columns: [start] 1fr [middle] 1fr [end];
}
- grid-template-areas:
.container {
grid-template-areas:
"header header header"
"sidebar content content"
"footer footer footer";
}
.item-header { grid-area: header; }
.item-sidebar { grid-area: sidebar; }
.item-content { grid-area: content; }
.item-footer { grid-area: footer; }
- grid-template(简写):
.container {
grid-template:
"header header" 80px
"sidebar content" 1fr
"footer footer" 60px
/ 200px 1fr; /* 列定义 */
}
- gap(间距):
.container {
gap: 20px; /* 行和列间距20px */
row-gap: 10px; /* 行间距 */
column-gap: 15px; /* 列间距 */
}
- justify-items / align-items:
.container {
justify-items: stretch; /* 默认:水平拉伸 */
align-items: stretch; /* 默认:垂直拉伸 */
justify-items: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
- justify-content / align-content:
.container {
justify-content: start; /* 水平对齐 */
align-content: start; /* 垂直对齐 */
}
- grid-auto-columns / grid-auto-rows:
.container {
grid-auto-rows: 100px; /* 隐式行高 */
grid-auto-columns: 1fr; /* 隐式列宽 */
}
- grid-auto-flow:
.container {
grid-auto-flow: row; /* 默认:按行排列 */
grid-auto-flow: column; /* 按列排列 */
grid-auto-flow: dense; /* 密集排列,填充空白 */
}
Grid项目属性:
- grid-column / grid-row:
.item {
/* 跨2列 */
grid-column: span 2;
/* 指定位置:从第2列到第4列 */
grid-column: 2 / 4;
/* 命名网格线 */
grid-column: start / middle;
/* 简写 */
grid-area: 1 / 1 / 3 / 3; /* row-start / column-start / row-end / column-end */
}
- grid-area:
.item {
/* 指定区域 */
grid-area: 2 / 2 / 4 / 4;
/* 使用命名区域 */
grid-area: content;
}
- justify-self / align-self:
.item {
justify-self: start; /* 项目水平对齐 */
align-self: center; /* 项目垂直对齐 */
}
Grid布局特点:
- 二维布局:同时控制行和列
- 精确控制:任意项目可放置在任何位置
- 响应式设计:易于创建响应式网格
- 区域命名:直观的布局定义
- 对齐控制:强大的对齐功能
- 间距控制:内置gap属性
应用场景:
- 网页整体布局:
.container {
display: grid;
grid-template:
"header header header" 80px
"nav main aside" 1fr
"footer footer footer" 60px
/ 200px 1fr 200px;
min-height: 100vh;
}
- 卡片网格:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
- 表单布局:
.form {
display: grid;
grid-template-columns: 120px 1fr;
gap: 15px;
align-items: center;
}
.form label {
text-align: right;
}
- 杂志式布局:
.magazine {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 200px);
gap: 10px;
}
.featured {
grid-column: span 2;
grid-row: span 2;
}
- 仪表盘:
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
Grid vs Flexbox:
| 特性 | Grid | Flexbox |
|---|---|---|
| 维度 | 二维(行和列) | 一维(行或列) |
| 方向 | 同时控制行列 | 单一方向 |
| 对齐 | 更强大的对齐控制 | 基本的对齐功能 |
| 定位 | 任意定位项目 | 顺序流排列 |
| 使用场景 | 整体布局、复杂网格 | 组件内部、一维布局 |
实际项目示例:
示例1:响应式网格系统:
.grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 20px;
}
.col-4 { grid-column: span 4; }
.col-6 { grid-column: span 6; }
.col-12 { grid-column: span 12; }
/* 响应式 */
@media (max-width: 768px) {
.col-4, .col-6 { grid-column: span 12; }
}
示例2:瀑布流布局:
.masonry {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: 50px; /* 基础行高 */
gap: 15px;
}
.item {
/* 随机高度效果 */
grid-row: span var(--row-span, 2); /* 自定义属性控制 */
}
示例3:棋盘布局:
.chessboard {
display: grid;
grid-template-columns: repeat(8, 60px);
grid-template-rows: repeat(8, 60px);
gap: 0;
}
.square {
width: 60px;
height: 60px;
}
.square:nth-child(16n + 1),
.square:nth-child(16n + 3),
.square:nth-child(16n + 5),
.square:nth-child(16n + 7),
.square:nth-child(16n + 10),
.square:nth-child(16n + 12),
.square:nth-child(16n + 14),
.square:nth-child(16n + 16) {
background: #000;
}
浏览器兼容性:
- IE10-11:部分支持(旧语法)
- Edge 16+、Chrome 57+、Firefox 52+、Safari 10.1+:完全支持
- 前缀使用:
.container {
display: -ms-grid; /* IE10-11 */
display: grid; /* 标准 */
}
性能优化:
- 避免过度复杂的网格定义
- 使用
grid-template-areas提高可读性 - 结合CSS自定义属性动态调整网格
- 考虑移动端性能
补充说明:
- Grid适合整体页面布局
- Flexbox适合组件内部布局
- 两者可结合使用
- 使用开发者工具调试网格线
- 学习Grid命名和区域功能提高效率
五、响应式设计
5. 响应式设计实现方法
问题:如何实现移动端适配?响应式设计如何实现?媒体查询的使用方法?
答案: 响应式设计原则:
- 移动优先:先设计移动端,再逐步增强
- 流体网格:使用百分比而非固定宽度
- 弹性图片:图片随容器缩放
- 媒体查询:根据设备特性应用不同样式
核心实现方法:
1. 媒体查询:
/* 基础样式(移动端) */
body { font-size: 14px; }
/* 平板设备 */
@media (min-width: 768px) {
body { font-size: 16px; }
}
/* 桌面设备 */
@media (min-width: 1024px) {
body { font-size: 18px; }
}
/* 断点系统 */
/* 移动端:< 768px */
/* 平板:768px - 1023px */
/* 桌面:≥ 1024px */
2. 视口设置:
<meta name="viewport" content="width=device-width, initial-scale=1">
3. 流体网格:
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
.col {
float: left;
width: 100%; /* 移动端:单列 */
}
@media (min-width: 768px) {
.col { width: 50%; } /* 平板:双列 */
}
@media (min-width: 1024px) {
.col { width: 25%; } /* 桌面:四列 */
}
4. 弹性图片:
img, video {
max-width: 100%;
height: auto;
}
/* 背景图片响应式 */
.banner {
background-image: url('banner-small.jpg');
background-size: cover;
}
@media (min-width: 768px) {
.banner {
background-image: url('banner-medium.jpg');
}
}
@media (min-width: 1200px) {
.banner {
background-image: url('banner-large.jpg');
}
}
5. 断点定义策略:
// 常用断点
$breakpoints: (
'xs': 320px, // 小手机
'sm': 576px, // 大手机
'md': 768px, // 平板
'lg': 992px, // 小桌面
'xl': 1200px, // 大桌面
'xxl': 1400px // 超大桌面
);
// 混合宏
@mixin respond-to($breakpoint) {
@if map-has-key($breakpoints, $breakpoint) {
@media (min-width: map-get($breakpoints, $breakpoint)) {
@content;
}
}
}
// 使用
.container {
padding: 1rem;
@include respond-to('md') {
padding: 2rem;
}
}
6. 响应式布局技术:
Flexbox响应式:
.container {
display: flex;
flex-wrap: wrap;
}
.item {
flex: 1 0 100%; /* 移动端:单列 */
}
@media (min-width: 768px) {
.item {
flex: 1 0 50%; /* 平板:双列 */
}
}
@media (min-width: 1024px) {
.item {
flex: 1 0 25%; /* 桌面:四列 */
}
}
Grid响应式:
.container {
display: grid;
grid-template-columns: 1fr; /* 移动端:单列 */
gap: 20px;
}
@media (min-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr); /* 平板:双列 */
}
}
@media (min-width: 1024px) {
.container {
grid-template-columns: repeat(3, 1fr); /* 桌面:三列 */
}
}
7. 响应式字体:
/* 基础字体 */
body { font-size: 14px; }
/* 视口单位 */
h1 {
font-size: clamp(1.5rem, 5vw, 3rem);
}
/* 媒体查询调整 */
@media (min-width: 768px) {
body { font-size: 16px; }
h1 { font-size: 2.5rem; }
}
@media (min-width: 1200px) {
body { font-size: 18px; }
h1 { font-size: 3rem; }
}
8. 响应式图片技术:
srcset 和 sizes:
<img src="image-800.jpg"
srcset="image-400.jpg 400w,
image-800.jpg 800w,
image-1200.jpg 1200w"
sizes="(max-width: 480px) 400px,
(max-width: 1024px) 800px,
1200px"
alt="响应式图片">
picture 元素:
<picture>
<source media="(min-width: 1200px)"
srcset="large.jpg">
<source media="(min-width: 768px)"
srcset="medium.jpg">
<source media="(max-width: 767px)"
srcset="small.jpg">
<img src="fallback.jpg" alt="描述">
</picture>
9. 响应式表格:
/* 移动端表格:转为块状 */
@media (max-width: 767px) {
table.responsive {
display: block;
}
table.responsive thead {
display: none;
}
table.responsive tbody,
table.responsive tr,
table.responsive td {
display: block;
}
table.responsive td {
padding: 10px;
border: none;
border-bottom: 1px solid #eee;
position: relative;
padding-left: 50%;
}
table.responsive td::before {
content: attr(data-label);
position: absolute;
left: 10px;
width: 45%;
padding-right: 10px;
font-weight: bold;
text-align: left;
}
}
10. 响应式导航:
汉堡菜单模式:
/* 移动端:隐藏菜单,显示汉堡按钮 */
.nav-menu {
display: none;
}
.menu-toggle {
display: block;
}
/* 桌面端:显示菜单,隐藏汉堡按钮 */
@media (min-width: 768px) {
.nav-menu {
display: flex;
}
.menu-toggle {
display: none;
}
}
/* 汉堡按钮样式 */
.hamburger {
width: 30px;
height: 3px;
background: #333;
position: relative;
}
.hamburger::before,
.hamburger::after {
content: '';
position: absolute;
width: 30px;
height: 3px;
background: #333;
}
.hamburger::before { top: -8px; }
.hamburger::after { top: 8px; }
11. 响应式实用类:
/* 显示/隐藏类 */
.hidden-mobile {
display: none;
}
.hidden-desktop {
display: block;
}
@media (min-width: 768px) {
.hidden-mobile {
display: block;
}
.hidden-desktop {
display: none;
}
}
/* 间距调整 */
.p-1 { padding: 0.5rem; }
.p-2 { padding: 1rem; }
@media (min-width: 768px) {
.p-md-3 { padding: 1.5rem; }
.p-md-4 { padding: 2rem; }
}
12. 响应式设计测试要点:
-
设备测试:
- 真实设备测试
- 模拟器测试
- 浏览器开发者工具
-
断点测试:
- 检查每个断点的布局
- 过渡区域测试
- 横屏/竖屏测试
-
性能测试:
- 移动端加载速度
- 图片优化
- 代码分割
-
可用性测试:
- 触摸目标大小
- 字体可读性
- 导航易用性
13. 现代响应式技术:
容器查询:
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: flex;
flex-direction: row;
}
}
CSS自定义属性:
:root {
--base-font-size: 14px;
--container-width: 100%;
}
@media (min-width: 768px) {
:root {
--base-font-size: 16px;
--container-width: 720px;
}
}
.container {
width: var(--container-width);
font-size: var(--base-font-size);
}
补充说明:
- 移动优先设计简化开发流程
- 使用相对单位(em, rem, %, vw, vh)
- 测试所有目标设备
- 关注核心性能指标(LCP, FID, CLS)
- 渐进增强,优雅降级
六、CSS 动画与过渡
6. animation、transition、transform 区别与应用
问题:CSS 动画与过渡的区别?如何使用 CSS3 实现动画?animation、transition、transform 有什么区别?
答案: 三者的核心区别:
| 特性 | transition | transform | animation |
|---|---|---|---|
| 作用 | 状态过渡 | 元素变换 | 复杂动画 |
| 触发 | 需要事件触发 | 立即应用 | 自动或触发 |
| 控制 | 简单过渡 | 静态变换 | 多关键帧 |
| 循环 | 不支持循环 | 不支持循环 | 支持循环 |
| 关键帧 | 仅开始结束 | 无关键帧 | 多关键帧 |
| 性能 | 优秀 | 优秀(硬件加速) | 优秀 |
详细说明:
1. transition(过渡):
.element {
/* 定义过渡 */
transition: property duration timing-function delay;
/* 示例:所有属性过渡0.3秒 */
transition: all 0.3s ease;
/* 多个属性不同过渡 */
transition:
width 0.3s ease,
height 0.5s ease-in-out,
opacity 0.2s linear;
}
.element:hover {
width: 200px; /* 触发过渡 */
opacity: 0.8;
}
可过渡属性:
- 尺寸:width, height, max-width, etc.
- 颜色:color, background-color, border-color
- 位置:top, left, right, bottom
- 变换:transform
- 其他:opacity, visibility, box-shadow
2. transform(变换):
.element {
/* 2D变换 */
transform: translate(100px, 50px); /* 位移 */
transform: rotate(45deg); /* 旋转 */
transform: scale(1.5); /* 缩放 */
transform: skew(20deg, 10deg); /* 倾斜 */
/* 3D变换 */
transform: translate3d(0, 0, 100px);
transform: rotate3d(1, 1, 1, 45deg);
transform: scale3d(1.5, 1.5, 1.5);
/* 多重变换 */
transform: translate(50px, 50px) rotate(45deg) scale(1.2);
/* 变换原点 */
transform-origin: 0 0; /* 左上角 */
transform-origin: center; /* 中心 */
}
3. animation(动画):
/* 定义关键帧 */
@keyframes slide-in {
0% {
transform: translateX(-100%);
opacity: 0;
}
60% {
transform: translateX(20px);
}
100% {
transform: translateX(0);
opacity: 1;
}
}
/* 应用动画 */
.element {
animation-name: slide-in;
animation-duration: 0.5s;
animation-timing-function: ease-out;
animation-delay: 0.2s;
animation-iteration-count: 1;
animation-direction: normal;
animation-fill-mode: forwards;
animation-play-state: running;
/* 简写 */
animation: slide-in 0.5s ease-out 0.2s 1 normal forwards;
}
/* 多个动画 */
.element {
animation:
slide-in 0.5s ease-out,
fade-in 0.3s ease-in;
}
动画属性详解:
- animation-name:关键帧名称
- animation-duration:动画时长
- animation-timing-function:时间函数
- linear:匀速
- ease:慢快慢(默认)
- ease-in:慢开始
- ease-out:慢结束
- ease-in-out:慢开始慢结束
- cubic-bezier:贝塞尔曲线
- animation-delay:延迟开始
- animation-iteration-count:重复次数
- 数字:1, 2, 3
- infinite:无限循环
- animation-direction:播放方向
- normal:正常播放
- reverse:反向播放
- alternate:交替播放
- alternate-reverse:反向交替
- animation-fill-mode:动画前后样式
- none:默认
- forwards:保留最后帧
- backwards:应用第一帧
- both:前后都应用
- animation-play-state:播放状态
- running:运行中
- paused:暂停
性能优化:
- 使用transform和opacity:
/* 性能好(硬件加速) */
.element {
transform: translateX(100px);
opacity: 0.5;
}
/* 性能差(触发重排) */
.element {
left: 100px;
width: 200px;
}
- will-change 提示:
.element {
will-change: transform, opacity;
}
- 减少动画数量:
/* 避免过多同时动画 */
.container:hover .element {
animation: bounce 0.3s;
}
实际应用示例:
示例1:按钮悬停效果:
.btn {
background: #4285f4;
color: white;
padding: 12px 24px;
border: none;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
}
.btn:hover {
background: #3367d6;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.btn:active {
transform: translateY(0);
transition-duration: 0.1s;
}
示例2:加载动画:
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid rgba(0,0,0,0.1);
border-left-color: #4285f4;
border-radius: 50%;
animation: spin 1s linear infinite;
}
示例3:卡片入场动画:
@keyframes card-enter {
0% {
opacity: 0;
transform: translateY(30px) scale(0.95);
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.card {
animation: card-enter 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
animation-fill-mode: backwards;
}
/* 交错动画 */
.card:nth-child(1) { animation-delay: 0.1s; }
.card:nth-child(2) { animation-delay: 0.2s; }
.card:nth-child(3) { animation-delay: 0.3s; }
示例4:打字机效果:
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
@keyframes blink-caret {
from, to { border-color: transparent; }
50% { border-color: #000; }
}
.typewriter {
overflow: hidden;
border-right: 3px solid;
white-space: nowrap;
animation:
typing 3.5s steps(40, end),
blink-caret 0.75s step-end infinite;
}
示例5:3D翻转卡片:
.card {
width: 200px;
height: 300px;
perspective: 1000px;
}
.card-inner {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.8s;
}
.card:hover .card-inner {
transform: rotateY(180deg);
}
.card-front,
.card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.card-back {
transform: rotateY(180deg);
}
浏览器兼容性:
- transform:IE9+(需-ms-前缀)
- transition:IE10+
- animation:IE10+
- 3D变换:IE10+(部分支持)
前缀使用:
.element {
-webkit-transform: translateX(100px);
-ms-transform: translateX(100px);
transform: translateX(100px);
-webkit-transition: all 0.3s;
transition: all 0.3s;
-webkit-animation: slide-in 0.5s;
animation: slide-in 0.5s;
}
最佳实践:
- 移动端优化:
/* 减少移动端动画 */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
- 性能监测:
// 检测动画性能
const element = document.querySelector('.animated');
element.addEventListener('animationstart', () => {
console.time('animation');
});
element.addEventListener('animationend', () => {
console.timeEnd('animation');
});
- GPU加速:
.element {
transform: translateZ(0); /* 触发GPU加速 */
will-change: transform; /* 性能提示 */
}
补充说明:
- CSS动画性能优于JavaScript动画 3D变换需要硬件支持
- 复杂动画考虑使用Web Animations API
- 测试动画在不同设备的性能表现