CSS 技术指南
目录
点击展开目录
CSS概述
什么是CSS
CSS(Cascading Style Sheets,层叠样式表)是用于描述 HTML 文档外观和格式的样式表语言。
CSS 的作用:
- 分离内容与表现:HTML 负责结构,CSS 负责样式
- 统一样式管理:一处修改,全站生效
- 丰富的视觉效果:布局、颜色、动画等
- 响应式设计:适配不同设备
CSS 基本语法:
选择器 {
属性: 值;
属性: 值;
}
/* 示例 */
h1 {
color: #333;
font-size: 24px;
margin-bottom: 16px;
}
CSS发展历史
| 版本 | 年份 | 主要特性 |
|---|---|---|
| CSS1 | 1996 | 基础样式:字体、颜色、边距 |
| CSS2 | 1998 | 定位、z-index、媒体类型 |
| CSS2.1 | 2011 | 修正和完善 CSS2 |
| CSS3 | 2011+ | 模块化,持续更新 |
CSS3 主要模块:
- 选择器(Selectors Level 3/4)
- 盒模型(Box Model)
- 背景和边框(Backgrounds and Borders)
- 文本效果(Text Effects)
- 2D/3D 变换(Transforms)
- 动画(Animations)
- 弹性盒(Flexbox)
- 网格布局(Grid)
- 媒体查询(Media Queries)
CSS引入方式
| 方式 | 语法 | 优先级 | 适用场景 |
|---|---|---|---|
| 内联样式 | style="..." | 最高 | 临时样式、JS 动态修改 |
| 内部样式 | <style>...</style> | 中 | 单页面特定样式 |
| 外部样式 | <link href="..."> | 中 | 推荐,便于维护 |
| @import | @import url(...) | 中 | 模块化导入 |
<!-- 内联样式 -->
<p style="color: red; font-size: 16px;">文本</p>
<!-- 内部样式 -->
<head>
<style>
p { color: red; }
</style>
</head>
<!-- 外部样式(推荐) -->
<head>
<link rel="stylesheet" href="styles.css">
</head>
<!-- @import(在 CSS 文件中) -->
<style>
@import url('base.css');
@import url('theme.css');
</style>
外部样式 vs @import:
| 特性 | <link> | @import |
|---|---|---|
| 加载时机 | 并行加载 | 串行加载 |
| 兼容性 | 所有浏览器 | CSS2.1+ |
| 性能 | 更好 | 较差 |
| 推荐 | ✅ | 仅用于 CSS 模块化 |
CSS工作原理
浏览器渲染流程:
布局"] F --> G["Paint
绘制"] G --> H["Composite
合成"] style A fill:#e3f2fd,stroke:#1976d2 style C fill:#fff3e0,stroke:#f57c00 style E fill:#e8f5e9,stroke:#388e3c style H fill:#fce4ec,stroke:#c2185b
层叠规则(Cascade):
- 来源优先级:用户
!important> 作者!important> 作者样式 > 用户样式 > 浏览器默认 - 选择器优先级:内联 > ID > 类/伪类/属性 > 元素/伪元素
- 源码顺序:后声明的覆盖先声明的
继承(Inheritance):
/* 可继承属性 */
body {
font-family: Arial; /* 继承 */
color: #333; /* 继承 */
line-height: 1.5; /* 继承 */
}
/* 不可继承属性 */
div {
border: 1px solid; /* 不继承 */
margin: 10px; /* 不继承 */
padding: 10px; /* 不继承 */
}
/* 强制继承 */
.child {
border: inherit;
}
/* 重置为初始值 */
.reset {
all: initial;
}
/* 重置为继承值 */
.inherit-all {
all: inherit;
}
常见可继承属性:
| 类型 | 属性 |
|---|---|
| 字体 | font-family, font-size, font-weight, font-style |
| 文本 | color, line-height, text-align, text-indent |
| 列表 | list-style, list-style-type |
| 其他 | visibility, cursor |
选择器
基础选择器
| 选择器 | 语法 | 说明 | 示例 |
|---|---|---|---|
| 通配符 | * | 选择所有元素 | * { margin: 0; } |
| 元素选择器 | element | 选择指定标签 | p { color: red; } |
| 类选择器 | .class | 选择指定类名 | .btn { padding: 10px; } |
| ID选择器 | #id | 选择指定ID | #header { height: 60px; } |
| 属性选择器 | [attr] | 选择有指定属性的元素 | [disabled] { opacity: 0.5; } |
属性选择器详解:
| 选择器 | 说明 | 示例 |
|---|---|---|
[attr] | 有该属性 | [required] |
[attr=value] | 属性值等于 | [type="text"] |
[attr~=value] | 属性值包含单词 | [class~="btn"] |
| `[attr | =value]` | 属性值以 value 或 value- 开头 |
[attr^=value] | 属性值以 value 开头 | [href^="https"] |
[attr$=value] | 属性值以 value 结尾 | [href$=".pdf"] |
[attr*=value] | 属性值包含 value | [href*="example"] |
组合选择器
| 选择器 | 语法 | 说明 | 示例 |
|---|---|---|---|
| 后代选择器 | A B | A 内部所有 B | div p |
| 子选择器 | A > B | A 的直接子元素 B | ul > li |
| 相邻兄弟 | A + B | A 后紧邻的 B | h1 + p |
| 通用兄弟 | A ~ B | A 后所有同级 B | h1 ~ p |
| 并集选择器 | A, B | A 或 B | h1, h2, h3 |
| 交集选择器 | A.B | 同时满足 A 和 B | p.intro |
/* 后代选择器 - 选择 nav 内所有 a */
nav a { text-decoration: none; }
/* 子选择器 - 只选择直接子元素 */
ul > li { list-style: none; }
/* 相邻兄弟 - 紧跟在 h2 后的 p */
h2 + p { font-size: 1.2em; }
/* 通用兄弟 - h2 后所有同级 p */
h2 ~ p { color: gray; }
伪类选择器
状态伪类:
| 伪类 | 说明 |
|---|---|
:hover | 鼠标悬停 |
:active | 激活状态(点击时) |
:focus | 获得焦点 |
:visited | 已访问的链接 |
:link | 未访问的链接 |
:checked | 选中的表单元素 |
:disabled | 禁用的表单元素 |
:enabled | 启用的表单元素 |
结构伪类:
| 伪类 | 说明 |
|---|---|
:first-child | 第一个子元素 |
:last-child | 最后一个子元素 |
:nth-child(n) | 第 n 个子元素 |
:nth-last-child(n) | 倒数第 n 个子元素 |
:first-of-type | 同类型第一个 |
:last-of-type | 同类型最后一个 |
:nth-of-type(n) | 同类型第 n 个 |
:only-child | 唯一子元素 |
:empty | 没有子元素 |
:root | 文档根元素 |
nth-child 表达式:
/* 选择奇数项 */
li:nth-child(odd) { background: #f5f5f5; }
li:nth-child(2n+1) { background: #f5f5f5; }
/* 选择偶数项 */
li:nth-child(even) { background: #fff; }
li:nth-child(2n) { background: #fff; }
/* 选择前3个 */
li:nth-child(-n+3) { font-weight: bold; }
/* 从第4个开始 */
li:nth-child(n+4) { color: gray; }
/* 每3个选1个 */
li:nth-child(3n) { border-bottom: 1px solid; }
其他常用伪类:
| 伪类 | 说明 |
|---|---|
:not(selector) | 否定选择器 |
:is(selector) | 匹配列表中任一选择器 |
:where(selector) | 同 :is,但优先级为 0 |
:has(selector) | 包含指定子元素的父元素 |
:focus-within | 自身或后代获得焦点 |
:focus-visible | 键盘焦点(非鼠标) |
/* :not - 排除特定元素 */
input:not([type="submit"]) { border: 1px solid #ccc; }
/* :is - 简化选择器 */
:is(h1, h2, h3) { font-family: serif; }
/* :has - 父选择器(CSS4) */
article:has(img) { padding: 20px; }
伪元素选择器
伪元素用于创建不存在于 DOM 中的虚拟元素,或选择元素的特定部分。
| 伪元素 | 说明 | 用途 |
|---|---|---|
::before | 元素内容前插入 | 装饰、图标 |
::after | 元素内容后插入 | 装饰、清除浮动 |
::first-letter | 首字母 | 首字下沉效果 |
::first-line | 首行 | 首行特殊样式 |
::selection | 选中的文本 | 自定义选中样式 |
::placeholder | 占位符文本 | 表单占位符样式 |
::marker | 列表标记 | 自定义列表符号 |
::before 和 ::after 使用:
/* 必须有 content 属性 */
.quote::before {
content: '"';
font-size: 2em;
color: #ccc;
}
.quote::after {
content: '"';
font-size: 2em;
color: #ccc;
}
/* 清除浮动 */
.clearfix::after {
content: '';
display: block;
clear: both;
}
/* 添加图标 */
.external-link::after {
content: ' ↗';
font-size: 0.8em;
}
/* 使用 attr() 获取属性值 */
a[href]::after {
content: ' (' attr(href) ')';
}
其他伪元素示例:
/* 首字下沉 */
p::first-letter {
font-size: 3em;
float: left;
line-height: 1;
margin-right: 10px;
}
/* 首行样式 */
p::first-line {
font-weight: bold;
color: #333;
}
/* 选中文本样式 */
::selection {
background: #007bff;
color: white;
}
/* 占位符样式 */
input::placeholder {
color: #999;
font-style: italic;
}
/* 列表标记 */
li::marker {
color: #007bff;
font-weight: bold;
}
选择器优先级
优先级计算规则:
| 选择器类型 | 权重值 | 示例 |
|---|---|---|
| 内联样式 | 1000 | style="..." |
| ID选择器 | 100 | #id |
| 类/伪类/属性 | 10 | .class, :hover, [attr] |
| 元素/伪元素 | 1 | div, ::before |
| 通配符/组合符 | 0 | *, >, +, ~ |
优先级计算示例:
/* 优先级: 0-0-1-1 = 11 */
div p { }
/* 优先级: 0-0-1-2 = 12 */
div p.intro { }
/* 优先级: 0-1-0-1 = 101 */
#content p { }
/* 优先级: 0-1-1-1 = 111 */
#content p.intro { }
/* 优先级: 0-1-2-1 = 121 */
#content p.intro:hover { }
优先级规则:
style属性"] B --> C["ID选择器
#id"] C --> D["类/伪类/属性
.class :hover [attr]"] D --> E["元素/伪元素
div ::before"] E --> F["通配符
*"] end style A fill:#f44336,stroke:#333,color:#fff style B fill:#ff9800,stroke:#333 style C fill:#ffeb3b,stroke:#333 style D fill:#4caf50,stroke:#333,color:#fff style E fill:#2196f3,stroke:#333,color:#fff
!important 使用注意:
- 尽量避免使用
!important - 只在覆盖第三方库样式时使用
- 多个
!important仍按优先级规则比较 - 内联样式的
!important优先级最高
盒模型
标准盒模型
CSS 盒模型是网页布局的基础,每个元素都被视为一个矩形盒子。
盒模型组成:
外边距"] B["border
边框"] C["padding
内边距"] D["content
内容区"] end A --> B --> C --> D style A fill:#ffccbc,stroke:#333 style B fill:#fff9c4,stroke:#333 style C fill:#c8e6c9,stroke:#333 style D fill:#bbdefb,stroke:#333
标准盒模型(content-box):
元素总宽度 = width + padding-left + padding-right + border-left + border-right
元素总高度 = height + padding-top + padding-bottom + border-top + border-bottom
| 属性 | 说明 |
|---|---|
| width/height | 只包含内容区域 |
| padding | 内边距,在内容和边框之间 |
| border | 边框 |
| margin | 外边距,元素与其他元素的间距 |
IE盒模型
IE盒模型(border-box):
元素总宽度 = width(包含 padding 和 border)
元素总高度 = height(包含 padding 和 border)
box-sizing 属性:
| 值 | 说明 | 推荐 |
|---|---|---|
content-box | 标准盒模型(默认) | 传统方式 |
border-box | IE盒模型 | 推荐使用 |
/* 推荐:全局使用 border-box */
*, *::before, *::after {
box-sizing: border-box;
}
/* 或者继承方式 */
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
两种盒模型对比:
| 特性 | content-box | border-box |
|---|---|---|
| width 含义 | 仅内容宽度 | 内容+padding+border |
| 计算复杂度 | 需要额外计算 | 直观简单 |
| 响应式布局 | 不便 | 方便 |
| 使用场景 | 默认行为 | 现代布局推荐 |
margin与padding
margin 属性:
/* 四个方向 */
margin: 10px; /* 上右下左都是 10px */
margin: 10px 20px; /* 上下 10px,左右 20px */
margin: 10px 20px 30px; /* 上 10px,左右 20px,下 30px */
margin: 10px 20px 30px 40px; /* 上 右 下 左(顺时针) */
/* 单独设置 */
margin-top: 10px;
margin-right: 20px;
margin-bottom: 30px;
margin-left: 40px;
/* 水平居中 */
margin: 0 auto;
margin 特殊行为:
| 行为 | 说明 |
|---|---|
| 外边距折叠 | 相邻垂直 margin 会合并,取较大值 |
| 负 margin | 可以使元素重叠或移动 |
| auto | 水平方向可实现居中 |
外边距折叠(Margin Collapsing):
/* 两个相邻元素的 margin 会折叠 */
.box1 { margin-bottom: 20px; }
.box2 { margin-top: 30px; }
/* 实际间距是 30px,不是 50px */
/* 解决方法 */
/* 1. 使用 padding 代替 */
/* 2. 添加 border 或 padding */
/* 3. 使用 BFC */
/* 4. 使用 Flexbox 或 Grid */
padding 属性:
/* 语法同 margin */
padding: 10px;
padding: 10px 20px;
padding: 10px 20px 30px 40px;
/* 单独设置 */
padding-top: 10px;
padding-right: 20px;
padding-bottom: 30px;
padding-left: 40px;
margin vs padding:
| 特性 | margin | padding |
|---|---|---|
| 位置 | 边框外部 | 边框内部 |
| 背景 | 不显示背景 | 显示背景 |
| 负值 | 支持 | 不支持 |
| 折叠 | 会折叠 | 不会折叠 |
| 用途 | 元素间距 | 内容与边框间距 |
边框与圆角
border 属性:
/* 简写 */
border: 1px solid #333;
/* 分开设置 */
border-width: 1px;
border-style: solid;
border-color: #333;
/* 单边设置 */
border-top: 2px dashed red;
border-right: none;
border-bottom: 1px solid #ccc;
border-left: 3px double blue;
border-style 值:
| 值 | 说明 |
|---|---|
none | 无边框 |
solid | 实线 |
dashed | 虚线 |
dotted | 点线 |
double | 双线 |
groove | 凹槽 |
ridge | 凸起 |
inset | 内嵌 |
outset | 外凸 |
border-radius 圆角:
/* 四个角相同 */
border-radius: 10px;
/* 对角设置 */
border-radius: 10px 20px; /* 左上右下 / 右上左下 */
/* 四个角分别设置 */
border-radius: 10px 20px 30px 40px; /* 左上 右上 右下 左下 */
/* 椭圆圆角 */
border-radius: 10px / 20px; /* 水平半径 / 垂直半径 */
/* 圆形 */
border-radius: 50%;
/* 单独设置 */
border-top-left-radius: 10px;
border-top-right-radius: 20px;
border-bottom-right-radius: 30px;
border-bottom-left-radius: 40px;
盒子阴影
box-shadow 语法:
box-shadow: h-offset v-offset blur spread color inset;
| 参数 | 说明 | 必需 |
|---|---|---|
| h-offset | 水平偏移(正值向右) | ✅ |
| v-offset | 垂直偏移(正值向下) | ✅ |
| blur | 模糊半径 | ❌ |
| spread | 扩展半径 | ❌ |
| color | 阴影颜色 | ❌ |
| inset | 内阴影 | ❌ |
常用阴影效果:
/* 基础阴影 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
/* 悬浮效果 */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1),
0 2px 4px rgba(0, 0, 0, 0.06);
/* 内阴影 */
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
/* 多重阴影 */
box-shadow: 0 1px 3px rgba(0,0,0,0.12),
0 1px 2px rgba(0,0,0,0.24);
/* 发光效果 */
box-shadow: 0 0 20px rgba(0, 123, 255, 0.5);
/* 立体按钮 */
.btn {
box-shadow: 0 4px 0 #0056b3;
}
.btn:active {
box-shadow: 0 2px 0 #0056b3;
transform: translateY(2px);
}
布局方式
文档流与定位
文档流(Normal Flow):
元素默认按照文档流排列:
- 块级元素:从上到下,独占一行
- 行内元素:从左到右,一行排满换行
display 属性:
| 值 | 说明 |
|---|---|
block | 块级元素 |
inline | 行内元素 |
inline-block | 行内块元素 |
none | 隐藏元素(不占空间) |
flex | 弹性容器 |
grid | 网格容器 |
contents | 只保留子元素 |
position 定位:
| 值 | 说明 | 参照物 |
|---|---|---|
static | 默认值,正常文档流 | - |
relative | 相对定位 | 自身原位置 |
absolute | 绝对定位 | 最近定位祖先 |
fixed | 固定定位 | 视口 |
sticky | 粘性定位 | 滚动容器 |
/* 相对定位 - 相对自身偏移,保留原位置 */
.relative {
position: relative;
top: 10px;
left: 20px;
}
/* 绝对定位 - 脱离文档流 */
.absolute {
position: absolute;
top: 0;
right: 0;
}
/* 固定定位 - 相对视口 */
.fixed-header {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
/* 粘性定位 - 滚动到阈值时固定 */
.sticky-nav {
position: sticky;
top: 0;
}
z-index 层叠:
/* 只对定位元素有效 */
.modal {
position: fixed;
z-index: 1000;
}
.overlay {
position: fixed;
z-index: 999;
}
Flexbox弹性布局
Flexbox 是一种一维布局模型,用于在容器中分配空间和对齐项目。
Flex 容器与项目:
弹性容器"] B["Flex Item 1"] C["Flex Item 2"] D["Flex Item 3"] A --> B A --> C A --> D end subgraph "轴线概念" E["Main Axis 主轴
→ 项目排列方向"] F["Cross Axis 交叉轴
↓ 垂直于主轴"] end style A fill:#e3f2fd,stroke:#1976d2 style B fill:#fff3e0,stroke:#f57c00 style C fill:#fff3e0,stroke:#f57c00 style D fill:#fff3e0,stroke:#f57c00
容器属性(父元素):
| 属性 | 说明 | 常用值 |
|---|---|---|
display | 定义 Flex 容器 | flex, inline-flex |
flex-direction | 主轴方向 | row, column, row-reverse, column-reverse |
flex-wrap | 是否换行 | nowrap, wrap, wrap-reverse |
justify-content | 主轴对齐 | flex-start, center, flex-end, space-between, space-around, space-evenly |
align-items | 交叉轴对齐 | stretch, flex-start, center, flex-end, baseline |
align-content | 多行对齐 | 同 justify-content |
gap | 项目间距 | 10px, 10px 20px |
flex-direction 主轴方向:
.container {
display: flex;
/* 水平从左到右(默认) */
flex-direction: row;
/* 水平从右到左 */
flex-direction: row-reverse;
/* 垂直从上到下 */
flex-direction: column;
/* 垂直从下到上 */
flex-direction: column-reverse;
}
justify-content 主轴对齐:
.container {
display: flex;
/* 起点对齐 */
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 {
display: flex;
/* 拉伸填满(默认) */
align-items: stretch;
/* 起点对齐 */
align-items: flex-start;
/* 终点对齐 */
align-items: flex-end;
/* 居中 */
align-items: center;
/* 基线对齐 */
align-items: baseline;
}
项目属性(子元素):
| 属性 | 说明 | 默认值 |
|---|---|---|
order | 排列顺序 | 0 |
flex-grow | 放大比例 | 0 |
flex-shrink | 缩小比例 | 1 |
flex-basis | 初始大小 | auto |
flex | 简写属性 | 0 1 auto |
align-self | 单独对齐 | auto |
flex 简写属性:
/* flex: grow shrink basis */
.item {
/* 不放大,可缩小,自动宽度 */
flex: 0 1 auto; /* 默认值 */
/* 等比放大 */
flex: 1; /* 等同于 flex: 1 1 0% */
/* 固定宽度,不伸缩 */
flex: 0 0 200px;
/* 常用简写 */
flex: auto; /* 1 1 auto */
flex: none; /* 0 0 auto */
flex: 1; /* 1 1 0% */
}
常见 Flex 布局模式:
/* 水平垂直居中 */
.center {
display: flex;
justify-content: center;
align-items: center;
}
/* 两端对齐导航 */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
/* 等宽列 */
.equal-columns {
display: flex;
}
.equal-columns > * {
flex: 1;
}
/* 固定侧边栏 + 自适应内容 */
.layout {
display: flex;
}
.sidebar {
flex: 0 0 250px;
}
.content {
flex: 1;
}
/* 底部固定 */
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.main {
flex: 1;
}
.footer {
flex-shrink: 0;
}
Grid网格布局
Grid 是一种二维布局系统,可以同时处理行和列。
Grid 基本概念:
网格容器"] B["Grid Item
网格项目"] C["Grid Line
网格线"] D["Grid Track
网格轨道(行/列)"] E["Grid Cell
网格单元格"] F["Grid Area
网格区域"] end style A fill:#e8f5e9,stroke:#388e3c style B fill:#fff3e0,stroke:#f57c00 style C fill:#fce4ec,stroke:#c2185b style D fill:#e3f2fd,stroke:#1976d2 style E fill:#f3e5f5,stroke:#7b1fa2 style F fill:#fff8e1,stroke:#ffa000
容器属性:
| 属性 | 说明 | 示例 |
|---|---|---|
display | 定义 Grid 容器 | grid, inline-grid |
grid-template-columns | 定义列 | 200px 1fr 1fr |
grid-template-rows | 定义行 | 100px auto 100px |
grid-template-areas | 定义区域 | 命名区域 |
gap | 间距 | 10px, 10px 20px |
justify-items | 单元格水平对齐 | start, center, end, stretch |
align-items | 单元格垂直对齐 | 同上 |
justify-content | 网格水平对齐 | start, center, end, space-between |
align-content | 网格垂直对齐 | 同上 |
定义网格轨道:
.grid {
display: grid;
/* 固定宽度 */
grid-template-columns: 200px 300px 200px;
/* 弹性单位 fr */
grid-template-columns: 1fr 2fr 1fr;
/* 混合使用 */
grid-template-columns: 200px 1fr 1fr;
/* repeat() 函数 */
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(4, 100px);
/* auto-fill 自动填充 */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* auto-fit 自动适应 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* minmax() 最小最大值 */
grid-template-columns: minmax(100px, 200px) 1fr;
}
grid-template-areas 区域布局:
.layout {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 60px 1fr 60px;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
gap: 10px;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
项目属性:
| 属性 | 说明 | 示例 |
|---|---|---|
grid-column | 列位置 | 1 / 3, span 2 |
grid-row | 行位置 | 1 / 3, span 2 |
grid-area | 区域名称或位置 | header, 1 / 1 / 2 / 4 |
justify-self | 单独水平对齐 | start, center, end |
align-self | 单独垂直对齐 | 同上 |
项目定位:
.item {
/* 从第1列线到第3列线 */
grid-column: 1 / 3;
/* 跨越2列 */
grid-column: span 2;
/* 从第1行线到第3行线 */
grid-row: 1 / 3;
/* 简写:row-start / column-start / row-end / column-end */
grid-area: 1 / 1 / 3 / 3;
}
Grid vs Flexbox 对比:
| 特性 | Flexbox | Grid |
|---|---|---|
| 维度 | 一维(行或列) | 二维(行和列) |
| 适用场景 | 组件内部布局 | 页面整体布局 |
| 对齐控制 | 主轴和交叉轴 | 行和列独立控制 |
| 项目大小 | 内容驱动 | 容器驱动 |
| 间距 | gap | gap |
| 浏览器支持 | 更好 | 现代浏览器 |
多列布局
CSS 多列布局用于将内容分成多列显示,类似报纸排版。
多列属性:
| 属性 | 说明 | 示例 |
|---|---|---|
column-count | 列数 | 3 |
column-width | 列宽 | 200px |
columns | 简写 | 3 200px |
column-gap | 列间距 | 20px |
column-rule | 列分隔线 | 1px solid #ccc |
column-span | 跨列 | all |
.multi-column {
/* 固定列数 */
column-count: 3;
/* 或固定列宽,自动计算列数 */
column-width: 200px;
/* 列间距 */
column-gap: 30px;
/* 列分隔线 */
column-rule: 1px solid #ddd;
}
/* 标题跨所有列 */
.multi-column h2 {
column-span: all;
}
/* 防止内容断开 */
.multi-column p {
break-inside: avoid;
}
响应式布局
响应式设计使网页能够适应不同设备和屏幕尺寸。
媒体查询(Media Queries):
/* 基本语法 */
@media (条件) {
/* 样式规则 */
}
/* 最大宽度 */
@media (max-width: 768px) {
.sidebar { display: none; }
}
/* 最小宽度 */
@media (min-width: 1024px) {
.container { max-width: 1200px; }
}
/* 范围 */
@media (min-width: 768px) and (max-width: 1024px) {
.nav { flex-direction: column; }
}
/* 设备方向 */
@media (orientation: landscape) {
.gallery { grid-template-columns: repeat(4, 1fr); }
}
/* 高分辨率屏幕 */
@media (-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
.logo { background-image: url('[email protected]'); }
}
常用断点:
| 断点 | 设备 | 建议 |
|---|---|---|
< 576px | 手机竖屏 | xs |
576px - 768px | 手机横屏/小平板 | sm |
768px - 992px | 平板 | md |
992px - 1200px | 小桌面 | lg |
> 1200px | 大桌面 | xl |
移动优先策略:
/* 基础样式(移动端) */
.container {
padding: 15px;
}
.nav {
flex-direction: column;
}
/* 平板及以上 */
@media (min-width: 768px) {
.container {
padding: 30px;
}
.nav {
flex-direction: row;
}
}
/* 桌面 */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
}
响应式单位:
| 单位 | 说明 | 用途 |
|---|---|---|
% | 相对父元素 | 宽度、定位 |
vw | 视口宽度的 1% | 全屏元素 |
vh | 视口高度的 1% | 全屏高度 |
vmin | vw 和 vh 中较小值 | 响应式字体 |
vmax | vw 和 vh 中较大值 | 响应式字体 |
rem | 相对根元素字体大小 | 整体缩放 |
em | 相对父元素字体大小 | 组件内缩放 |
响应式图片:
/* 基础响应式图片 */
img {
max-width: 100%;
height: auto;
}
/* 使用 object-fit */
.cover-image {
width: 100%;
height: 300px;
object-fit: cover;
object-position: center;
}
/* 使用 picture 元素 */
/* HTML:
<picture>
<source media="(min-width: 1024px)" srcset="large.jpg">
<source media="(min-width: 768px)" srcset="medium.jpg">
<img src="small.jpg" alt="响应式图片">
</picture>
*/
容器查询(Container Queries):
/* 定义容器 */
.card-container {
container-type: inline-size;
container-name: card;
}
/* 基于容器宽度的样式 */
@container card (min-width: 400px) {
.card {
display: flex;
flex-direction: row;
}
}
@container card (max-width: 399px) {
.card {
display: block;
}
}
文本与字体
字体属性
font-family 字体族:
/* 字体栈 - 从左到右依次尝试 */
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, sans-serif;
}
/* 中文字体 */
body {
font-family: "PingFang SC", "Microsoft YaHei", "Hiragino Sans GB",
"WenQuanYi Micro Hei", sans-serif;
}
/* 代码字体 */
code {
font-family: "SF Mono", "Fira Code", Consolas, "Courier New", monospace;
}
字体族类型:
| 类型 | 说明 | 示例 |
|---|---|---|
serif | 衬线字体 | Times New Roman, Georgia |
sans-serif | 无衬线字体 | Arial, Helvetica |
monospace | 等宽字体 | Courier, Consolas |
cursive | 手写体 | Comic Sans |
fantasy | 装饰字体 | Impact |
font-size 字体大小:
/* 绝对单位 */
font-size: 16px;
font-size: 12pt;
/* 相对单位 */
font-size: 1rem; /* 相对根元素 */
font-size: 1.2em; /* 相对父元素 */
font-size: 100%; /* 相对父元素 */
/* 视口单位 */
font-size: 4vw; /* 视口宽度的 4% */
/* 关键字 */
font-size: small;
font-size: medium;
font-size: large;
font-size: larger;
font-size: smaller;
/* clamp() 响应式字体 */
font-size: clamp(1rem, 2.5vw, 2rem);
font-weight 字体粗细:
| 值 | 说明 |
|---|---|
100 - 900 | 数值(100的倍数) |
normal | 等同于 400 |
bold | 等同于 700 |
lighter | 比父元素细 |
bolder | 比父元素粗 |
font-style 字体样式:
| 值 | 说明 |
|---|---|
normal | 正常 |
italic | 斜体(使用字体的斜体版本) |
oblique | 倾斜(强制倾斜) |
font 简写属性:
/* font: style weight size/line-height family */
font: italic bold 16px/1.5 Arial, sans-serif;
/* 最少需要 size 和 family */
font: 16px Arial;
/* 常用写法 */
font: normal 400 16px/1.6 "Helvetica Neue", sans-serif;
文本属性
文本对齐:
| 属性 | 说明 | 值 |
|---|---|---|
text-align | 水平对齐 | left, right, center, justify |
vertical-align | 垂直对齐(行内元素) | baseline, top, middle, bottom |
/* 水平对齐 */
.center { text-align: center; }
.justify { text-align: justify; }
/* 垂直对齐 - 用于行内元素 */
img { vertical-align: middle; }
行高与间距:
/* 行高 */
line-height: 1.5; /* 无单位,推荐 */
line-height: 24px; /* 固定值 */
line-height: 150%; /* 百分比 */
/* 字间距 */
letter-spacing: 2px;
letter-spacing: 0.1em;
/* 词间距 */
word-spacing: 5px;
/* 首行缩进 */
text-indent: 2em;
文本装饰:
/* text-decoration 简写 */
text-decoration: underline;
text-decoration: line-through;
text-decoration: overline;
text-decoration: none;
/* 详细设置 */
text-decoration-line: underline;
text-decoration-color: red;
text-decoration-style: wavy; /* solid, double, dotted, dashed, wavy */
text-decoration-thickness: 2px;
/* 下划线偏移 */
text-underline-offset: 3px;
文本转换:
text-transform: uppercase; /* 全大写 */
text-transform: lowercase; /* 全小写 */
text-transform: capitalize; /* 首字母大写 */
text-transform: none; /* 默认 */
文本溢出处理:
/* 单行文本溢出省略 */
.ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 多行文本溢出省略 */
.multi-ellipsis {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* 文本换行 */
word-wrap: break-word; /* 长单词换行 */
word-break: break-all; /* 任意位置换行 */
white-space: pre-wrap; /* 保留空白,自动换行 */
white-space 属性:
| 值 | 空格 | 换行符 | 自动换行 |
|---|---|---|---|
normal | 合并 | 忽略 | 是 |
nowrap | 合并 | 忽略 | 否 |
pre | 保留 | 保留 | 否 |
pre-wrap | 保留 | 保留 | 是 |
pre-line | 合并 | 保留 | 是 |
Web字体
@font-face 自定义字体:
@font-face {
font-family: 'MyFont';
src: url('myfont.woff2') format('woff2'),
url('myfont.woff') format('woff'),
url('myfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
/* 使用自定义字体 */
body {
font-family: 'MyFont', sans-serif;
}
字体格式:
| 格式 | 扩展名 | 说明 |
|---|---|---|
| WOFF2 | .woff2 | 推荐,压缩率最高 |
| WOFF | .woff | 广泛支持 |
| TTF/OTF | .ttf/.otf | 传统格式 |
| EOT | .eot | IE 专用 |
| SVG | .svg | 已废弃 |
font-display 属性:
| 值 | 说明 |
|---|---|
auto | 浏览器默认行为 |
block | 短暂隐藏文本,等待字体加载 |
swap | 立即显示后备字体,加载后替换 |
fallback | 短暂隐藏,超时使用后备字体 |
optional | 短暂隐藏,可能不使用自定义字体 |
Google Fonts 使用:
<!-- HTML 引入 -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
/* CSS 引入 */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
body {
font-family: 'Roboto', sans-serif;
}
可变字体(Variable Fonts):
@font-face {
font-family: 'Inter';
src: url('Inter-VariableFont.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: normal;
}
/* 使用可变字体 */
.light { font-weight: 300; }
.regular { font-weight: 400; }
.bold { font-weight: 700; }
/* 使用 font-variation-settings */
.custom {
font-variation-settings: 'wght' 550, 'wdth' 75;
}
颜色与背景
颜色表示方法
颜色值类型:
| 类型 | 语法 | 示例 |
|---|---|---|
| 关键字 | 颜色名称 | red, blue, transparent |
| 十六进制 | #RRGGBB | #ff0000, #f00 |
| RGB | rgb(r, g, b) | rgb(255, 0, 0) |
| RGBA | rgba(r, g, b, a) | rgba(255, 0, 0, 0.5) |
| HSL | hsl(h, s%, l%) | hsl(0, 100%, 50%) |
| HSLA | hsla(h, s%, l%, a) | hsla(0, 100%, 50%, 0.5) |
| HWB | hwb(h w% b%) | hwb(0 0% 0%) |
| LAB | lab(l a b) | lab(50% 50 -50) |
| LCH | lch(l c h) | lch(50% 100 50) |
十六进制颜色:
/* 6位十六进制 */
color: #ff5500;
/* 3位简写(每位重复) */
color: #f50; /* 等同于 #ff5500 */
/* 8位(带透明度) */
color: #ff550080; /* 50% 透明度 */
/* 4位简写 */
color: #f508; /* 等同于 #ff550088 */
RGB/RGBA:
/* RGB - 0-255 */
color: rgb(255, 85, 0);
/* 百分比 */
color: rgb(100%, 33%, 0%);
/* RGBA - 带透明度 */
color: rgba(255, 85, 0, 0.5);
/* 现代语法(空格分隔) */
color: rgb(255 85 0);
color: rgb(255 85 0 / 50%);
HSL/HSLA:
HSL 更直观:Hue(色相)、Saturation(饱和度)、Lightness(亮度)
/* HSL */
color: hsl(20, 100%, 50%); /* 橙色 */
/* HSLA */
color: hsla(20, 100%, 50%, 0.5);
/* 现代语法 */
color: hsl(20 100% 50%);
color: hsl(20 100% 50% / 50%);
色相值参考:
| 色相 | 角度 |
|---|---|
| 红色 | 0° / 360° |
| 橙色 | 30° |
| 黄色 | 60° |
| 绿色 | 120° |
| 青色 | 180° |
| 蓝色 | 240° |
| 紫色 | 300° |
currentColor 关键字:
/* 继承当前 color 值 */
.icon {
color: #007bff;
border: 1px solid currentColor;
fill: currentColor; /* SVG */
}
背景属性
background 相关属性:
| 属性 | 说明 | 示例 |
|---|---|---|
background-color | 背景颜色 | #fff |
background-image | 背景图片 | url('bg.jpg') |
background-repeat | 重复方式 | no-repeat, repeat-x |
background-position | 位置 | center, top right |
background-size | 大小 | cover, contain, 100px |
background-attachment | 固定方式 | scroll, fixed, local |
background-origin | 定位区域 | padding-box, border-box, content-box |
background-clip | 裁剪区域 | 同上 |
background-size:
/* 关键字 */
background-size: cover; /* 覆盖整个容器,可能裁剪 */
background-size: contain; /* 完整显示,可能留白 */
/* 具体尺寸 */
background-size: 100px 200px;
background-size: 100% auto;
background-size: 50%;
background-position:
/* 关键字 */
background-position: center;
background-position: top right;
background-position: bottom left;
/* 具体值 */
background-position: 50% 50%;
background-position: 10px 20px;
/* 四值语法 */
background-position: right 10px bottom 20px;
多重背景:
.multi-bg {
background:
url('top.png') no-repeat top center,
url('bottom.png') no-repeat bottom center,
linear-gradient(to bottom, #fff, #f5f5f5);
}
background 简写:
/* background: color image repeat position/size attachment */
background: #f5f5f5 url('bg.jpg') no-repeat center/cover fixed;
/* 常用写法 */
background: url('hero.jpg') no-repeat center center;
background-size: cover;
渐变效果
线性渐变(linear-gradient):
/* 基本语法 */
background: linear-gradient(direction, color1, color2, ...);
/* 方向 */
background: linear-gradient(to right, red, blue);
background: linear-gradient(to bottom right, red, blue);
background: linear-gradient(45deg, red, blue);
/* 多色渐变 */
background: linear-gradient(to right, red, orange, yellow, green, blue);
/* 指定位置 */
background: linear-gradient(to right, red 0%, blue 50%, green 100%);
/* 硬边渐变 */
background: linear-gradient(to right, red 50%, blue 50%);
径向渐变(radial-gradient):
/* 基本语法 */
background: radial-gradient(shape size at position, color1, color2, ...);
/* 形状 */
background: radial-gradient(circle, red, blue);
background: radial-gradient(ellipse, red, blue);
/* 大小 */
background: radial-gradient(circle closest-side, red, blue);
background: radial-gradient(circle farthest-corner, red, blue);
/* 位置 */
background: radial-gradient(circle at top left, red, blue);
background: radial-gradient(circle at 25% 25%, red, blue);
圆锥渐变(conic-gradient):
/* 基本语法 */
background: conic-gradient(from angle at position, color1, color2, ...);
/* 饼图效果 */
background: conic-gradient(red 0deg 90deg, blue 90deg 180deg,
green 180deg 270deg, yellow 270deg 360deg);
/* 棋盘格 */
background: conic-gradient(#fff 90deg, #000 90deg 180deg,
#fff 180deg 270deg, #000 270deg);
background-size: 20px 20px;
重复渐变:
/* 重复线性渐变 */
background: repeating-linear-gradient(
45deg,
#606dbc,
#606dbc 10px,
#465298 10px,
#465298 20px
);
/* 重复径向渐变 */
background: repeating-radial-gradient(
circle,
red,
red 10px,
blue 10px,
blue 20px
);
渐变应用示例:
/* 渐变按钮 */
.btn-gradient {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
color: white;
}
/* 渐变边框 */
.gradient-border {
border: 3px solid transparent;
background:
linear-gradient(white, white) padding-box,
linear-gradient(135deg, #667eea, #764ba2) border-box;
}
/* 渐变文字 */
.gradient-text {
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* 遮罩渐变 */
.overlay {
background: linear-gradient(
to bottom,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 0.7) 100%
);
}
过渡与动画
CSS过渡
过渡(Transition)用于在属性值变化时添加平滑的动画效果。
transition 属性:
| 属性 | 说明 | 示例 |
|---|---|---|
transition-property | 过渡属性 | all, opacity, transform |
transition-duration | 持续时间 | 0.3s, 300ms |
transition-timing-function | 时间函数 | ease, linear, ease-in-out |
transition-delay | 延迟时间 | 0s, 0.1s |
基本用法:
/* 简写 */
transition: property duration timing-function delay;
/* 单个属性 */
.btn {
transition: background-color 0.3s ease;
}
/* 多个属性 */
.card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
/* 所有属性 */
.element {
transition: all 0.3s ease;
}
时间函数(timing-function):
| 值 | 说明 |
|---|---|
linear | 匀速 |
ease | 默认,慢-快-慢 |
ease-in | 慢速开始 |
ease-out | 慢速结束 |
ease-in-out | 慢速开始和结束 |
cubic-bezier(n,n,n,n) | 自定义贝塞尔曲线 |
steps(n, start/end) | 步进动画 |
/* 贝塞尔曲线 */
transition: transform 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
/* 步进动画 */
transition: background-position 0.5s steps(5);
常见过渡效果:
/* 悬停放大 */
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: scale(1.05);
}
/* 淡入淡出 */
.fade {
opacity: 0;
transition: opacity 0.3s ease;
}
.fade.show {
opacity: 1;
}
/* 滑动展开 */
.dropdown {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.dropdown.open {
max-height: 500px;
}
/* 按钮悬停 */
.btn {
background: #007bff;
transition: background-color 0.2s, transform 0.2s;
}
.btn:hover {
background: #0056b3;
transform: translateY(-2px);
}
CSS动画
动画(Animation)可以创建更复杂的动画效果,支持多个关键帧。
@keyframes 定义动画:
/* 使用 from/to */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 使用百分比 */
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-20px);
}
}
/* 多个关键帧 */
@keyframes rainbow {
0% { background: red; }
17% { background: orange; }
33% { background: yellow; }
50% { background: green; }
67% { background: blue; }
83% { background: indigo; }
100% { background: violet; }
}
animation 属性:
| 属性 | 说明 | 示例 |
|---|---|---|
animation-name | 动画名称 | fadeIn |
animation-duration | 持续时间 | 1s |
animation-timing-function | 时间函数 | ease |
animation-delay | 延迟 | 0s |
animation-iteration-count | 播放次数 | 1, infinite |
animation-direction | 播放方向 | normal, reverse, alternate |
animation-fill-mode | 填充模式 | none, forwards, backwards, both |
animation-play-state | 播放状态 | running, paused |
animation 简写:
/* animation: name duration timing-function delay iteration-count direction fill-mode */
animation: fadeIn 1s ease 0s 1 normal forwards;
/* 常用写法 */
animation: fadeIn 0.5s ease forwards;
animation: spin 1s linear infinite;
animation-fill-mode:
| 值 | 说明 |
|---|---|
none | 默认,动画前后不应用样式 |
forwards | 保持最后一帧样式 |
backwards | 延迟期间应用第一帧样式 |
both | 同时应用 forwards 和 backwards |
常见动画效果:
/* 旋转加载 */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
animation: spin 1s linear infinite;
}
/* 脉冲效果 */
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.pulse {
animation: pulse 2s ease infinite;
}
/* 抖动效果 */
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-10px); }
75% { transform: translateX(10px); }
}
.shake {
animation: shake 0.5s ease;
}
/* 打字机效果 */
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
.typewriter {
overflow: hidden;
white-space: nowrap;
animation: typing 3s steps(30) forwards;
}
/* 渐入上移 */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-in-up {
animation: fadeInUp 0.5s ease forwards;
}
变换Transform
Transform 用于对元素进行2D 或 3D 变换,不影响文档流。
2D 变换函数:
| 函数 | 说明 | 示例 |
|---|---|---|
translate(x, y) | 平移 | translate(10px, 20px) |
translateX(x) | 水平平移 | translateX(50%) |
translateY(y) | 垂直平移 | translateY(-10px) |
scale(x, y) | 缩放 | scale(1.5), scale(2, 0.5) |
rotate(angle) | 旋转 | rotate(45deg) |
skew(x, y) | 倾斜 | skew(10deg, 5deg) |
matrix() | 矩阵变换 | 复杂变换 |
/* 平移 */
transform: translate(50px, 100px);
transform: translateX(-50%); /* 常用于居中 */
/* 缩放 */
transform: scale(1.5); /* 等比放大 1.5 倍 */
transform: scale(2, 0.5); /* 宽度 2 倍,高度 0.5 倍 */
transform: scaleX(0); /* 水平方向消失 */
/* 旋转 */
transform: rotate(45deg); /* 顺时针 45 度 */
transform: rotate(-90deg); /* 逆时针 90 度 */
/* 倾斜 */
transform: skew(10deg);
transform: skewX(10deg);
transform: skewY(5deg);
/* 组合变换(从右到左执行) */
transform: translate(50px, 50px) rotate(45deg) scale(1.5);
3D 变换函数:
| 函数 | 说明 |
|---|---|
translate3d(x, y, z) | 3D 平移 |
translateZ(z) | Z 轴平移 |
scale3d(x, y, z) | 3D 缩放 |
rotate3d(x, y, z, angle) | 3D 旋转 |
rotateX(angle) | X 轴旋转 |
rotateY(angle) | Y 轴旋转 |
rotateZ(angle) | Z 轴旋转 |
perspective(n) | 透视距离 |
/* 3D 变换需要设置透视 */
.container {
perspective: 1000px;
}
.card {
transform-style: preserve-3d;
transition: transform 0.6s;
}
.card:hover {
transform: rotateY(180deg);
}
/* 翻转卡片 */
.card-front, .card-back {
backface-visibility: hidden;
}
.card-back {
transform: rotateY(180deg);
}
transform-origin 变换原点:
/* 默认中心点 */
transform-origin: center;
transform-origin: 50% 50%;
/* 左上角 */
transform-origin: top left;
transform-origin: 0 0;
/* 具体位置 */
transform-origin: 100px 50px;
/* 3D 原点 */
transform-origin: center center 50px;
常见变换应用:
/* 水平垂直居中 */
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 悬停效果 */
.card {
transition: transform 0.3s;
}
.card:hover {
transform: translateY(-5px) scale(1.02);
}
/* 图片悬停放大 */
.img-container {
overflow: hidden;
}
.img-container img {
transition: transform 0.3s;
}
.img-container:hover img {
transform: scale(1.1);
}
/* 加载动画 */
@keyframes spin3d {
from { transform: rotateY(0deg); }
to { transform: rotateY(360deg); }
}
.loader-3d {
animation: spin3d 1s linear infinite;
}
CSS预处理器
CSS 预处理器扩展了 CSS 的功能,提供变量、嵌套、混合、函数等特性,最终编译为标准 CSS。
Sass/SCSS
Sass 是最流行的 CSS 预处理器,有两种语法:Sass(缩进语法)和 SCSS(CSS 超集)。
变量:
// 定义变量
$primary-color: #007bff;
$font-size-base: 16px;
$spacing: 8px;
// 使用变量
.btn {
background: $primary-color;
font-size: $font-size-base;
padding: $spacing * 2;
}
// 变量默认值
$theme-color: blue !default;
嵌套:
// 选择器嵌套
.nav {
background: #333;
ul {
list-style: none;
margin: 0;
}
li {
display: inline-block;
}
a {
color: white;
&:hover { // & 代表父选择器
color: #007bff;
}
}
}
// 属性嵌套
.box {
border: {
width: 1px;
style: solid;
color: #ccc;
}
font: {
family: Arial;
size: 14px;
weight: bold;
}
}
混合(Mixin):
// 定义混合
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
// 带参数的混合
@mixin button($bg-color, $text-color: white) {
background: $bg-color;
color: $text-color;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background: darken($bg-color, 10%);
}
}
// 使用混合
.container {
@include flex-center;
}
.btn-primary {
@include button(#007bff);
}
.btn-danger {
@include button(#dc3545, #fff);
}
继承(Extend):
// 基础样式
%button-base {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
// 继承
.btn-primary {
@extend %button-base;
background: #007bff;
color: white;
}
.btn-secondary {
@extend %button-base;
background: #6c757d;
color: white;
}
函数:
// 内置函数
$color: #007bff;
.element {
background: lighten($color, 20%); // 变亮
border-color: darken($color, 10%); // 变暗
color: complement($color); // 补色
opacity: rgba($color, 0.5); // 透明度
}
// 自定义函数
@function rem($px) {
@return $px / 16px * 1rem;
}
.text {
font-size: rem(18px); // 1.125rem
}
条件与循环:
// 条件语句
@mixin theme($dark: false) {
@if $dark {
background: #333;
color: white;
} @else {
background: white;
color: #333;
}
}
// for 循环
@for $i from 1 through 5 {
.col-#{$i} {
width: 20% * $i;
}
}
// each 循环
$colors: (primary: #007bff, success: #28a745, danger: #dc3545);
@each $name, $color in $colors {
.btn-#{$name} {
background: $color;
}
}
// while 循环
$i: 1;
@while $i <= 3 {
.item-#{$i} {
width: 100px * $i;
}
$i: $i + 1;
}
模块化(@use 和 @forward):
// _variables.scss
$primary: #007bff;
$secondary: #6c757d;
// _mixins.scss
@use 'variables' as vars;
@mixin button {
background: vars.$primary;
}
// main.scss
@use 'variables' as *;
@use 'mixins';
.btn {
@include mixins.button;
color: $primary;
}
Less
Less 是另一个流行的 CSS 预处理器,语法更接近 CSS。
变量:
// 定义变量(使用 @)
@primary-color: #007bff;
@font-size: 16px;
// 使用变量
.btn {
background: @primary-color;
font-size: @font-size;
}
// 变量插值
@property: color;
.element {
@{property}: red;
}
嵌套:
.nav {
background: #333;
ul {
list-style: none;
}
a {
color: white;
&:hover {
color: @primary-color;
}
}
}
混合:
// 定义混合
.flex-center() {
display: flex;
justify-content: center;
align-items: center;
}
// 带参数
.button(@bg: #007bff, @color: white) {
background: @bg;
color: @color;
padding: 10px 20px;
}
// 使用
.container {
.flex-center();
}
.btn {
.button(#28a745);
}
函数:
@color: #007bff;
.element {
background: lighten(@color, 20%);
border: 1px solid darken(@color, 10%);
color: contrast(@color);
}
// 数学运算
@base: 16px;
.text {
font-size: @base * 1.5;
margin: @base / 2;
}
导入:
// 导入其他 Less 文件
@import "variables";
@import "mixins";
@import (reference) "bootstrap"; // 只引用,不输出
预处理器对比
| 特性 | Sass/SCSS | Less |
|---|---|---|
| 变量符号 | $ | @ |
| 语法 | SCSS 类似 CSS | 类似 CSS |
| 编译 | Ruby/Dart/Node | JavaScript |
| 混合 | @mixin / @include | .mixin() |
| 继承 | @extend | :extend() |
| 条件 | @if / @else | when |
| 循环 | @for / @each / @while | 递归混合 |
| 模块化 | @use / @forward | @import |
| 生态 | 更丰富 | Bootstrap 默认 |
选择建议:
- Sass/SCSS:功能更强大,社区更活跃,推荐新项目使用
- Less:学习曲线平缓,与 Bootstrap 3 集成好
PostCSS 简介:
PostCSS 不是预处理器,而是 CSS 转换工具,通过插件实现各种功能:
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer'), // 自动添加前缀
require('postcss-preset-env'), // 使用未来 CSS 特性
require('cssnano'), // 压缩 CSS
require('postcss-nested'), // 嵌套语法
]
}
CSS架构与规范
BEM命名规范
BEM(Block Element Modifier)是一种 CSS 命名方法论,提高代码可维护性。
BEM 结构:
.block {}
.block__element {}
.block--modifier {}
| 部分 | 说明 | 示例 |
|---|---|---|
| Block | 独立组件 | .card, .menu, .form |
| Element | 组件的组成部分 | .card__title, .menu__item |
| Modifier | 状态或变体 | .card--featured, .btn--large |
BEM 示例:
<!-- 卡片组件 -->
<div class="card card--featured">
<img class="card__image" src="..." alt="">
<div class="card__content">
<h3 class="card__title">标题</h3>
<p class="card__text">内容</p>
<button class="card__button card__button--primary">按钮</button>
</div>
</div>
/* Block */
.card {
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
/* Element */
.card__image {
width: 100%;
height: auto;
}
.card__content {
padding: 16px;
}
.card__title {
font-size: 18px;
margin-bottom: 8px;
}
.card__text {
color: #666;
}
.card__button {
padding: 8px 16px;
}
/* Modifier */
.card--featured {
border-color: #007bff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.card__button--primary {
background: #007bff;
color: white;
}
BEM 优点:
- 命名清晰,一目了然
- 避免选择器嵌套过深
- 组件独立,易于复用
- 减少样式冲突
BEM 与 Sass 结合:
.card {
border: 1px solid #ddd;
&__image {
width: 100%;
}
&__title {
font-size: 18px;
}
&--featured {
border-color: #007bff;
}
}
CSS模块化
CSS Modules:
CSS Modules 通过构建工具实现样式的局部作用域。
/* Button.module.css */
.button {
padding: 10px 20px;
background: #007bff;
}
.primary {
background: #007bff;
}
.secondary {
background: #6c757d;
}
// React 中使用
import styles from './Button.module.css';
function Button({ variant = 'primary', children }) {
return (
<button className={`${styles.button} ${styles[variant]}`}>
{children}
</button>
);
}
编译后的类名:
/* 自动生成唯一类名 */
.Button_button__3xk2d {
padding: 10px 20px;
}
.Button_primary__1a2b3 {
background: #007bff;
}
CSS Modules 特性:
| 特性 | 说明 |
|---|---|
| 局部作用域 | 类名自动哈希,避免冲突 |
| 组合 | composes 复用样式 |
| 全局样式 | :global(.class) 定义全局 |
| 变量 | 可导出变量给 JS 使用 |
/* 组合样式 */
.base {
padding: 10px;
}
.button {
composes: base;
background: #007bff;
}
/* 全局样式 */
:global(.container) {
max-width: 1200px;
}
/* 导出变量 */
:export {
primaryColor: #007bff;
}
CSS-in-JS
CSS-in-JS 是在 JavaScript 中编写 CSS 的方案,常用于 React 项目。
Styled Components:
import styled from 'styled-components';
// 创建样式组件
const Button = styled.button`
padding: 10px 20px;
background: ${props => props.primary ? '#007bff' : '#6c757d'};
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
`;
// 使用
function App() {
return (
<>
<Button>默认按钮</Button>
<Button primary>主要按钮</Button>
</>
);
}
// 继承样式
const PrimaryButton = styled(Button)`
background: #007bff;
`;
// 主题
const theme = {
colors: {
primary: '#007bff',
secondary: '#6c757d'
}
};
const ThemedButton = styled.button`
background: ${props => props.theme.colors.primary};
`;
Emotion:
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
import styled from '@emotion/styled';
// css prop
const buttonStyle = css`
padding: 10px 20px;
background: #007bff;
color: white;
`;
function Button() {
return <button css={buttonStyle}>按钮</button>;
}
// styled API
const StyledButton = styled.button`
padding: 10px 20px;
background: ${props => props.primary ? '#007bff' : '#6c757d'};
`;
CSS-in-JS 对比:
| 方案 | 特点 | 适用场景 |
|---|---|---|
| Styled Components | 组件化、主题支持 | React 项目 |
| Emotion | 性能好、灵活 | React 项目 |
| CSS Modules | 零运行时、简单 | 各种项目 |
| Tailwind CSS | 原子化、快速开发 | 各种项目 |
Tailwind CSS 简介:
Tailwind 是原子化 CSS 框架,通过组合工具类构建界面。
<!-- 传统 CSS -->
<button class="btn btn-primary">按钮</button>
<!-- Tailwind CSS -->
<button class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
按钮
</button>
/* Tailwind 配置 */
/* tailwind.config.js */
module.exports = {
theme: {
extend: {
colors: {
primary: '#007bff',
}
}
}
}
实战技巧
常见布局实现
水平垂直居中:
/* Flexbox 方式(推荐) */
.center-flex {
display: flex;
justify-content: center;
align-items: center;
}
/* Grid 方式 */
.center-grid {
display: grid;
place-items: center;
}
/* 定位 + Transform */
.center-position {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 定位 + margin auto */
.center-margin {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 200px;
height: 200px;
}
两栏布局(固定 + 自适应):
/* Flexbox */
.layout-flex {
display: flex;
}
.sidebar {
flex: 0 0 250px;
}
.content {
flex: 1;
}
/* Grid */
.layout-grid {
display: grid;
grid-template-columns: 250px 1fr;
}
/* Float(传统) */
.sidebar-float {
float: left;
width: 250px;
}
.content-float {
margin-left: 260px;
}
三栏布局(圣杯/双飞翼):
/* Flexbox 实现 */
.holy-grail {
display: flex;
}
.left, .right {
flex: 0 0 200px;
}
.center {
flex: 1;
}
/* Grid 实现 */
.holy-grail-grid {
display: grid;
grid-template-columns: 200px 1fr 200px;
}
等高列:
/* Flexbox(默认等高) */
.equal-height {
display: flex;
}
.equal-height > * {
flex: 1;
}
/* Grid */
.equal-height-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
粘性底部(Sticky Footer):
/* Flexbox */
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.main {
flex: 1;
}
.footer {
flex-shrink: 0;
}
/* Grid */
.page-grid {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
瀑布流布局:
/* CSS Columns */
.masonry {
column-count: 3;
column-gap: 20px;
}
.masonry-item {
break-inside: avoid;
margin-bottom: 20px;
}
/* Grid(需要 JS 配合) */
.masonry-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 10px;
gap: 20px;
}
CSS性能优化
选择器优化:
/* 避免 */
div.container ul li a { } /* 层级过深 */
*[type="text"] { } /* 通配符 + 属性 */
.nav > ul > li > a > span { } /* 过度限定 */
/* 推荐 */
.nav-link { } /* 直接类名 */
.nav-link-text { } /* BEM 命名 */
减少重绘重排:
/* 使用 transform 代替位置属性 */
/* 避免 */
.animate {
left: 100px;
top: 100px;
}
/* 推荐 */
.animate {
transform: translate(100px, 100px);
}
/* 使用 opacity 代替 visibility */
/* 避免 */
.hide { visibility: hidden; }
/* 推荐 */
.hide { opacity: 0; }
/* 批量修改样式 */
/* 避免 */
element.style.width = '100px';
element.style.height = '100px';
element.style.background = 'red';
/* 推荐 */
element.classList.add('new-style');
will-change 提示:
/* 告诉浏览器即将变化的属性 */
.animate {
will-change: transform, opacity;
}
/* 动画结束后移除 */
.animate.done {
will-change: auto;
}
CSS 加载优化:
<!-- 关键 CSS 内联 -->
<style>
/* 首屏关键样式 */
</style>
<!-- 非关键 CSS 异步加载 -->
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
<!-- 媒体查询拆分 -->
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="mobile.css" media="(max-width: 768px)">
<link rel="stylesheet" href="print.css" media="print">
减少 CSS 体积:
- 移除未使用的 CSS(PurgeCSS)
- 压缩 CSS(cssnano)
- 使用 CSS 变量减少重复
- 合理使用简写属性
浏览器兼容性
浏览器前缀:
/* 手动添加 */
.element {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
/* 使用 Autoprefixer 自动添加 */
/* 只需写标准属性 */
.element {
transform: rotate(45deg);
}
特性检测:
/* @supports 规则 */
@supports (display: grid) {
.container {
display: grid;
}
}
@supports not (display: grid) {
.container {
display: flex;
}
}
/* 组合条件 */
@supports (display: grid) and (gap: 20px) {
.grid {
display: grid;
gap: 20px;
}
}
渐进增强:
/* 基础样式(所有浏览器) */
.layout {
display: block;
}
/* 增强样式(支持 Flexbox) */
@supports (display: flex) {
.layout {
display: flex;
}
}
/* 最佳体验(支持 Grid) */
@supports (display: grid) {
.layout {
display: grid;
}
}
常见兼容问题:
| 问题 | 解决方案 |
|---|---|
| Flex 兼容 | 添加 -webkit- 前缀 |
| Grid 兼容 | 提供 Flexbox 降级方案 |
| CSS 变量 | 提供固定值降级 |
| position: sticky | 使用 JS polyfill |
| gap 属性 | 使用 margin 替代 |
/* CSS 变量降级 */
.element {
color: #007bff; /* 降级值 */
color: var(--primary-color); /* CSS 变量 */
}
/* Gap 降级 */
.flex-container {
display: flex;
margin: -10px;
}
.flex-container > * {
margin: 10px;
}
/* 支持 gap 时 */
@supports (gap: 20px) {
.flex-container {
gap: 20px;
margin: 0;
}
.flex-container > * {
margin: 0;
}
}
调试工具:
- Chrome DevTools:Elements 面板查看样式
- Firefox DevTools:Grid/Flexbox 可视化
- Can I Use:查询浏览器支持情况
- Browserslist:配置目标浏览器
// package.json
{
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}