CSS —— 让网页从"能看"变成"好看"的那层皮
一、先说两句
HTML 是房子的结构——墙、地板、屋顶、门窗的位置。CSS 是什么?
**CSS 是装修——墙刷什么颜色、地板铺木纹还是瓷砖、窗帘选什么材质、灯光怎么打。**
没有 CSS 的网页长这样:
```
我的网站
======
欢迎来到我的网站
---------------
这是一段文字
* 项目一
* 项目二
* 项目三
© 2025 我的网站
```
而且这是字体最大号、纯黑色、白底、所有元素从上到下排列的样子——**跟 1991 年 Tim Berners-Lee 看到的网页一模一样。**
加上 CSS 之后:
```
┌─────────────────────────────────────┐
│ �� 我的网站 [首页] [关于] [联系] │
│─────────────────────────────────────│
│ ✨ 欢迎来到我的网站 │
│ 这是一段精心排版的文字, │
│ 字体舒适、间距合理、配色和谐。 │
│ │
│ �� 项目一 �� 项目二 �� 项目三 │
│─────────────────────────────────────│
│ © 2025 我的网站 │
└─────────────────────────────────────┘
```
**同样的 HTML,加了 CSS 之后,体验天差地别。**
CSS 的全称是 **Cascading Style Sheets(层叠样式表)**。三个关键词:
- **Cascading(层叠)** ——多个样式规则可以叠加,优先级高的覆盖优先级低的
- **Style(样式)** ——控制外观
- **Sheets(表)** ——可以写在一个单独的文件里
1996 年 CSS 1 发布,只有几十个属性。现在(2025 年)CSS 已经有 **500+ 属性**,从简单的颜色字体到复杂的 3D 变换、动画、网格布局,甚至能做完整的响应式设计。
但核心思想三十年没变:**CSS 只做一件事——选择元素,改变它的外观。**
二、CSS 的核心机制
**1. 选择器 —— 选中谁?**
CSS 的第一步是选中你要修改的元素:
```css
/* 标签选择器:选中所有 <p> */
p {
color: red;
}
/* 类选择器:选中所有 class="highlight" 的元素 */
.highlight {
background: yellow;
}
/* ID 选择器:选中 id="logo" 的那个元素(一个页面只有一个) */
#logo {
width: 200px;
}
/* 属性选择器:选中所有 target="_blank" 的链接 */
a[target="_blank"] {
color: orange;
}
/* 后代选择器:选中 article 里的所有 p */
article p {
line-height: 1.8;
}
/* 子选择器:只选 article 的直接子元素 p */
article > p {
text-indent: 2em;
}
/* 伪类:选中鼠标悬停时的链接 */
a:hover {
text-decoration: underline;
}
/* 伪元素:选中第一行 */
p::first-line {
font-weight: bold;
}
```
**选择器的优先级(权重)—— CSS 里最著名的计算题:**
```bash
!important → 权重:∞(最高,但滥用会导致维护灾难)
内联样式 style="" → 权重:1,0,0,0
ID 选择器 #id → 权重:0,1,0,0
类/属性/伪类 .class → 权重:0,0,1,0
标签/伪元素 p → 权重:0,0,0,1
通配符 * → 权重:0,0,0,0
继承的样式 → 没有权重
当两条规则冲突时:
比较四位数,从左到右,哪个大用哪个
如果全部相等,后面写的覆盖前面写的
```
例子:
```css
/* 权重 = 0,0,1,1 */
div .highlight { color: red; }
/* 权重 = 0,1,0,0 */
#main { color: blue; }
/* 蓝色胜出(ID 选择器 > 类选择器)*/
/* 无论顺序如何,ID 选择器的权重永远大于类选择器 */
```
这是 CSS 新手最头疼的地方——"我明明写了颜色为什么不生效?"——90% 是因为选择器优先级不够。
**2. 盒模型 —— 每个元素都是一个盒子**
理解盒模型是理解 CSS 布局的前提:
```css
/* 每个元素本质上由四层组成: */
div {
width: 200px; /* 内容区(Content)—— 真正放内容的区域 */
padding: 20px; /* 内边距(Padding)—— 内容到边框的间距 */
border: 2px solid black; /* 边框(Border)—— 元素的边界线 */
margin: 30px; /* 外边距(Margin)—— 元素到其他元素的间距 */
}
/* 标准盒模型下,这个 div 的实际宽度:
200 + 20*2 + 2*2 + 30*2 = 304px
这很不直观——你设了 width: 200,但实际占了 304px */
/* 推荐:改成 border-box,更符合直觉 */
* {
box-sizing: border-box;
}
/* 此时 width: 200 包含了 padding 和 border
实际宽度就是 200px + 30*2 margin = 260px
margin 不计入盒子尺寸,只决定间距 */
```
**`box-sizing: border-box` 是每个 CSS 新手第一个要学的技巧**——没有它,写布局的时候宽高总是算不准。
**3. 布局方式 —— 从 table 到 flexbox 到 grid**
CSS 的布局能力经历了三个阶段:
```bash
第一阶段:表格布局(1990s-2000s)
<table> 套 <table> 套 <table>
优点:什么浏览器都能显示
缺点:HTML 巨大、难以维护、不语义
第二阶段:Float 布局(2000s-2010s)
float: left / right + clearfix
优点:脱离表格,更语义化
缺点:天生不是为布局设计的,各种 hack
第三阶段:Flexbox(2012+)—— 一维布局
display: flex
优点:水平居中、垂直居中、等分布局一行搞定
缺点:只能处理一行或一列
第四阶段:Grid(2017+)—— 二维布局
display: grid
优点:行和列同时控制,真正为布局而生
缺点:老浏览器不支持(但 IE 已经死了,问题不大)
```
**Flexbox —— 最常用的现代布局方式:**
```css
/* 垂直居中 —— 曾经让无数前端崩溃的问题,现在一行解决 */
.container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
/* 等分布局 */
.container {
display: flex;
}
.item {
flex: 1; /* 每个子元素平均分配剩余空间 */
}
```
**Grid —— 真正的网格系统:**
```css
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 三列:中间是两倍宽 */
grid-template-rows: auto auto auto;
gap: 20px; /* 行列间距 */
}
/* 常见的"三明治"布局 */
.container {
display: grid;
grid-template-rows: auto 1fr auto; /* header(自适应) + main(撑满) + footer(自适应) */
min-height: 100vh;
}
```
三、CSS3 —— 让 Web 设计翻开了新的一页
CSS3 不是单个版本,而是一系列模块的统称(2005-2015 年间陆续推出)。
**1. 圆角、阴影、渐变 —— 告别图片**
```css
/* 以前:图片切四个圆角 → 现在:一行 CSS */
.box {
border-radius: 8px; /* 圆角,现在连截图的圆角都用这个 */
box-shadow: 0 2px 8px rgba(0,0,0,0.1); /* 阴影,Material Design 的影子就是这个 */
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
/* 渐变背景 */
}
```
**2. 动画和过渡 —— 让页面活起来**
```css
/* 过渡:属性变化时平滑过渡 */
.button {
background: blue;
transition: background 0.3s ease; /* 0.3 秒平滑变化 */
}
.button:hover {
background: red; /* 鼠标移上来,背景从蓝色慢慢变成红色 */
}
/* 动画:更复杂的运动 */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.box {
animation: fadeIn 0.5s ease-out;
}
```
**3. 媒体查询 —— 响应式设计的基石**
```css
/* 当屏幕宽度小于 768px(平板/手机)时,应用这些样式 */
@media (max-width: 768px) {
.container {
flex-direction: column; /* 改成竖排 */
}
.sidebar {
display: none; /* 隐藏侧栏 */
}
.menu {
font-size: 16px; /* 增大字号方便手指点击 */
}
}
```
四、CSS 的命名管理——项目大了就知道重要
CSS 本身没有"变量"和"作用域"的概念,写多了很容易冲突。所以出现了各种命名方法论:
```bash
# BEM(Block Element Modifier)—— 最流行的命名规范
.block {} # 独立的组件
.block__element {} # 组件内部的子元素
.block--modifier {} # 组件的某种状态
# 示例
.card {} # 卡片组件
.card__title {} # 卡片标题
.card__content {} # 卡片内容
.card--featured {} # 被标记为"精选"的卡片
# 不使用 BEM 的话,项目大了之后:
/* 你永远不知道 .title 是哪个组件的标题 */
.title { font-size: 20px; }
/* 三个组件各自有一个 .title,冲突了 */
/* 最后所有人都在选择器前面加 !important 解决——灾难 */
```
**现代 CSS 有了更好的方案——CSS Modules 或 Tailwind CSS:**
```bash
# CSS Modules —— 自动生成唯一类名,不会冲突
.Button_title_3x4d { /* 编译后自动加哈希 */
font-size: 20px;
}
# Tailwind CSS —— 直接用实用类名,不写自定义 CSS
<div class="text-xl font-bold bg-blue-500 rounded-lg p-4">
不需要写 CSS 文件,全在 HTML 里用现成的类名组合
</div>
```
**Tailwind 现在非常流行**——它让你不怎么写 CSS 文件,直接在 HTML 里用预定义的类名组合出任何样式。争议很大(有人觉得"这是把 CSS 混到 HTML 里,开历史倒车"),但用的人确实越来越多。
五、CSS 性能
CSS 的性能优化不太被人关注,但影响确实存在:
**选择器的效率(从快到慢):**
```bash
最快: #id → 直接通过 ID 索引
很快: .class → 通过类名索引
中等: tag → 通过标签名索引
慢: .class .class → 后代选择器(要遍历 DOM)
更慢: .class > .class → 子选择器
最慢: .class .class .class .class → 多级嵌套
```
但现实中——**除非你的页面有几万个元素,否则选择器性能差距可以忽略不计。**
真正影响性能的是:
```bash
1. 强制重排(Reflow)
→ 修改布局属性(width/height/margin/padding/position)
→ 浏览器要重新计算所有元素的位置和大小
2. 重绘(Repaint)
→ 修改外观属性(color/background/box-shadow)
→ 不影响布局,但浏览器要重新绘制
3. 合成(Composite)
→ 用 transform 和 opacity 做的动画
→ 在单独的层上处理,不影响主线程
→ 最流畅!
4. JavaScript 修改样式
→ 批量修改用 class,不要一行行改 style
```
```javascript
// ❌ 不推荐:多次重排
el.style.width = '100px';
el.style.height = '100px';
el.style.margin = '10px';
// ✅ 推荐:一次 class 切换,一次重排
el.className = 'box-active';
```
六、CSS vs —— 其实没有真正的竞品
CSS 是浏览器渲染的唯一标准。没有其他选择。
但有一些工具和概念可以"减少写 CSS":
| 方案 | 核心思想 | 适合谁 |
|------|---------|-------|
| 原生 CSS | 直接写 .css 文件 | 所有人(必学) |
| SCSS / Sass | CSS 的增强版(变量/嵌套/混合) | 项目较大的团队 |
| Tailwind CSS | 不写 CSS,用原子类名组合 | 快速开发、现代项目 |
| CSS Modules | 每个组件自动隔离样式 | React/Vue 项目 |
| Styled Components | 把 CSS 写在 JS 里 | React 项目 |
| Bootstrap | 现成的 UI 组件库 | 不想从头写 CSS |
**但不管用哪个——你都得先懂 CSS。** 就像不管开手动挡还是自动挡,都得先懂交规。
七、⚠️ 常见坑
**!important 依赖症**
```css
/* 新手经常做的事:CSS 不生效 → 加 !important → 好了 */
.text-color { color: red !important; }
/* 但之后每个人都要用 !important 来覆盖你 */
.other-text { color: blue !important; } /* 只能继续加 */
/* 最后全文件充满 !important,谁都不敢删 */
/* 正确做法:提高选择器优先级,不要用 !important */
.container .text-color { color: red; } /* 权重更高 */
```
**Flex 和 Grid 分不清**
```bash
# 什么时候用 Flex?
单行或单列排列 → 导航栏、按钮组、标签页
需要居中 → 什么居中都行
内容大小不确定 → 分配剩余空间
# 什么时候用 Grid?
行和列同时控制 → 网格式的页面布局
两栏/三栏经典布局 → header/main/footer
元素要跨行跨列 → Grid 天生支持
```
**简单规则:一维用 Flex,二维用 Grid。**
**百分比和内边距的冲突**
```css
/* ❌ 设了宽度 50%,再加 padding,实际超过 50% */
.column {
width: 50%;
padding: 20px; /* 实际变成 50% + 40px */
}
/* ✅ 用 border-box 解决 */
*, *::before, *::after {
box-sizing: border-box;
}
```
**reset.css / normalize.css 没加**
不同浏览器的默认样式不同。不加重置样式表:
```bash
Chrome 的 <h1> 是 32px
Firefox 的 <h1> 是 28px
Safari 的 <body> 有 8px margin,别的浏览器可能没有
```
解决方案——在所有 CSS 文件之前引入:
```css
/* normalize.css:保留有用的默认样式,统一不一致的地方 */
@import "normalize.css";
/* 或者更激进的 reset:去掉所有默认样式,从零开始 */
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
```
**垂直居中**
这是 CSS 圈著名的"段子"——每个新手都会问"怎么垂直居中":
```css
/* 2025 年的答案——一行搞定 */
.parent {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中(可选) */
}
```
写在最后
CSS 是所有 Web 技术里最"分裂"的一门——喜欢它的人觉得它让设计变得无比自由,讨厌它的人觉得它是最不讲逻辑的语言(为什么我改了颜色没生效?为什么这个元素不在我期望的位置上?)。
这两种感受都是真实的。CSS 不是传统意义上的"编程语言",它没有变量、没有函数、没有逻辑控制。但它有自己的逻辑——**选择器优先级、层叠规则、盒模型、布局上下文**——理解这些之后,CSS 的行为其实是可预测的。
CSS 最让人爱恨交织的地方在于:**用起来门槛极低(几行代码就能改颜色和字号),但精通极难(要懂渲染原理、性能优化、各种奇技淫巧)。**
但有一点是确定的——**没有 CSS 的 Web 是一个文字堆砌的黑白世界。** CSS 把互联网从文档变成了设计,从"能看"变成了"好看"。
就冲这一点,值得你花时间好好学它。
本文由 AI 生成,内容仅供参考。CSS 属性和规范更新较快,具体用法请以 MDN 文档(developer.mozilla.org/zh-CN/docs/Web/CSS)为准。
—— 全文完 ——
�� CSS —— 让网页从"能看"变成"好看"的那层皮
一、先说两句
HTML 是房子的结构——墙、地板、屋顶、门窗的位置。CSS 是什么?
**CSS 是装修——墙刷什么颜色、地板铺木纹还是瓷砖、窗帘选什么材质、灯光怎么打。**
没有 CSS 的网页长这样:
```
我的网站
======
欢迎来到我的网站
---------------
这是一段文字
* 项目一
* 项目二
* 项目三
© 2025 我的网站
```
而且这是字体最大号、纯黑色、白底、所有元素从上到下排列的样子——**跟 1991 年 Tim Berners-Lee 看到的网页一模一样。**
加上 CSS 之后:
```
┌─────────────────────────────────────┐
│ �� 我的网站 [首页] [关于] [联系] │
│─────────────────────────────────────│
│ ✨ 欢迎来到我的网站 │
│ 这是一段精心排版的文字, │
│ 字体舒适、间距合理、配色和谐。 │
│ │
│ �� 项目一 �� 项目二 �� 项目三 │
│─────────────────────────────────────│
│ © 2025 我的网站 │
└─────────────────────────────────────┘
```
**同样的 HTML,加了 CSS 之后,体验天差地别。**
CSS 的全称是 **Cascading Style Sheets(层叠样式表)**。三个关键词:
- **Cascading(层叠)** ——多个样式规则可以叠加,优先级高的覆盖优先级低的
- **Style(样式)** ——控制外观
- **Sheets(表)** ——可以写在一个单独的文件里
1996 年 CSS 1 发布,只有几十个属性。现在(2025 年)CSS 已经有 **500+ 属性**,从简单的颜色字体到复杂的 3D 变换、动画、网格布局,甚至能做完整的响应式设计。
但核心思想三十年没变:**CSS 只做一件事——选择元素,改变它的外观。**
二、CSS 的核心机制
**1. 选择器 —— 选中谁?**
CSS 的第一步是选中你要修改的元素:
```css
/* 标签选择器:选中所有 <p> */
p {
color: red;
}
/* 类选择器:选中所有 class="highlight" 的元素 */
.highlight {
background: yellow;
}
/* ID 选择器:选中 id="logo" 的那个元素(一个页面只有一个) */
#logo {
width: 200px;
}
/* 属性选择器:选中所有 target="_blank" 的链接 */
a[target="_blank"] {
color: orange;
}
/* 后代选择器:选中 article 里的所有 p */
article p {
line-height: 1.8;
}
/* 子选择器:只选 article 的直接子元素 p */
article > p {
text-indent: 2em;
}
/* 伪类:选中鼠标悬停时的链接 */
a:hover {
text-decoration: underline;
}
/* 伪元素:选中第一行 */
p::first-line {
font-weight: bold;
}
```
**选择器的优先级(权重)—— CSS 里最著名的计算题:**
```bash
!important → 权重:∞(最高,但滥用会导致维护灾难)
内联样式 style="" → 权重:1,0,0,0
ID 选择器 #id → 权重:0,1,0,0
类/属性/伪类 .class → 权重:0,0,1,0
标签/伪元素 p → 权重:0,0,0,1
通配符 * → 权重:0,0,0,0
继承的样式 → 没有权重
当两条规则冲突时:
比较四位数,从左到右,哪个大用哪个
如果全部相等,后面写的覆盖前面写的
```
例子:
```css
/* 权重 = 0,0,1,1 */
div .highlight { color: red; }
/* 权重 = 0,1,0,0 */
#main { color: blue; }
/* 蓝色胜出(ID 选择器 > 类选择器)*/
/* 无论顺序如何,ID 选择器的权重永远大于类选择器 */
```
这是 CSS 新手最头疼的地方——"我明明写了颜色为什么不生效?"——90% 是因为选择器优先级不够。
**2. 盒模型 —— 每个元素都是一个盒子**
理解盒模型是理解 CSS 布局的前提:
```css
/* 每个元素本质上由四层组成: */
div {
width: 200px; /* 内容区(Content)—— 真正放内容的区域 */
padding: 20px; /* 内边距(Padding)—— 内容到边框的间距 */
border: 2px solid black; /* 边框(Border)—— 元素的边界线 */
margin: 30px; /* 外边距(Margin)—— 元素到其他元素的间距 */
}
/* 标准盒模型下,这个 div 的实际宽度:
200 + 20*2 + 2*2 + 30*2 = 304px
这很不直观——你设了 width: 200,但实际占了 304px */
/* 推荐:改成 border-box,更符合直觉 */
* {
box-sizing: border-box;
}
/* 此时 width: 200 包含了 padding 和 border
实际宽度就是 200px + 30*2 margin = 260px
margin 不计入盒子尺寸,只决定间距 */
```
**`box-sizing: border-box` 是每个 CSS 新手第一个要学的技巧**——没有它,写布局的时候宽高总是算不准。
**3. 布局方式 —— 从 table 到 flexbox 到 grid**
CSS 的布局能力经历了三个阶段:
```bash
第一阶段:表格布局(1990s-2000s)
<table> 套 <table> 套 <table>
优点:什么浏览器都能显示
缺点:HTML 巨大、难以维护、不语义
第二阶段:Float 布局(2000s-2010s)
float: left / right + clearfix
优点:脱离表格,更语义化
缺点:天生不是为布局设计的,各种 hack
第三阶段:Flexbox(2012+)—— 一维布局
display: flex
优点:水平居中、垂直居中、等分布局一行搞定
缺点:只能处理一行或一列
第四阶段:Grid(2017+)—— 二维布局
display: grid
优点:行和列同时控制,真正为布局而生
缺点:老浏览器不支持(但 IE 已经死了,问题不大)
```
**Flexbox —— 最常用的现代布局方式:**
```css
/* 垂直居中 —— 曾经让无数前端崩溃的问题,现在一行解决 */
.container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
/* 等分布局 */
.container {
display: flex;
}
.item {
flex: 1; /* 每个子元素平均分配剩余空间 */
}
```
**Grid —— 真正的网格系统:**
```css
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 三列:中间是两倍宽 */
grid-template-rows: auto auto auto;
gap: 20px; /* 行列间距 */
}
/* 常见的"三明治"布局 */
.container {
display: grid;
grid-template-rows: auto 1fr auto; /* header(自适应) + main(撑满) + footer(自适应) */
min-height: 100vh;
}
```
三、CSS3 —— 让 Web 设计翻开了新的一页
CSS3 不是单个版本,而是一系列模块的统称(2005-2015 年间陆续推出)。
**1. 圆角、阴影、渐变 —— 告别图片**
```css
/* 以前:图片切四个圆角 → 现在:一行 CSS */
.box {
border-radius: 8px; /* 圆角,现在连截图的圆角都用这个 */
box-shadow: 0 2px 8px rgba(0,0,0,0.1); /* 阴影,Material Design 的影子就是这个 */
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
/* 渐变背景 */
}
```
**2. 动画和过渡 —— 让页面活起来**
```css
/* 过渡:属性变化时平滑过渡 */
.button {
background: blue;
transition: background 0.3s ease; /* 0.3 秒平滑变化 */
}
.button:hover {
background: red; /* 鼠标移上来,背景从蓝色慢慢变成红色 */
}
/* 动画:更复杂的运动 */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.box {
animation: fadeIn 0.5s ease-out;
}
```
**3. 媒体查询 —— 响应式设计的基石**
```css
/* 当屏幕宽度小于 768px(平板/手机)时,应用这些样式 */
@media (max-width: 768px) {
.container {
flex-direction: column; /* 改成竖排 */
}
.sidebar {
display: none; /* 隐藏侧栏 */
}
.menu {
font-size: 16px; /* 增大字号方便手指点击 */
}
}
```
四、CSS 的命名管理——项目大了就知道重要
CSS 本身没有"变量"和"作用域"的概念,写多了很容易冲突。所以出现了各种命名方法论:
```bash
# BEM(Block Element Modifier)—— 最流行的命名规范
.block {} # 独立的组件
.block__element {} # 组件内部的子元素
.block--modifier {} # 组件的某种状态
# 示例
.card {} # 卡片组件
.card__title {} # 卡片标题
.card__content {} # 卡片内容
.card--featured {} # 被标记为"精选"的卡片
# 不使用 BEM 的话,项目大了之后:
/* 你永远不知道 .title 是哪个组件的标题 */
.title { font-size: 20px; }
/* 三个组件各自有一个 .title,冲突了 */
/* 最后所有人都在选择器前面加 !important 解决——灾难 */
```
**现代 CSS 有了更好的方案——CSS Modules 或 Tailwind CSS:**
```bash
# CSS Modules —— 自动生成唯一类名,不会冲突
.Button_title_3x4d { /* 编译后自动加哈希 */
font-size: 20px;
}
# Tailwind CSS —— 直接用实用类名,不写自定义 CSS
<div class="text-xl font-bold bg-blue-500 rounded-lg p-4">
不需要写 CSS 文件,全在 HTML 里用现成的类名组合
</div>
```
**Tailwind 现在非常流行**——它让你不怎么写 CSS 文件,直接在 HTML 里用预定义的类名组合出任何样式。争议很大(有人觉得"这是把 CSS 混到 HTML 里,开历史倒车"),但用的人确实越来越多。
五、CSS 性能
CSS 的性能优化不太被人关注,但影响确实存在:
**选择器的效率(从快到慢):**
```bash
最快: #id → 直接通过 ID 索引
很快: .class → 通过类名索引
中等: tag → 通过标签名索引
慢: .class .class → 后代选择器(要遍历 DOM)
更慢: .class > .class → 子选择器
最慢: .class .class .class .class → 多级嵌套
```
但现实中——**除非你的页面有几万个元素,否则选择器性能差距可以忽略不计。**
真正影响性能的是:
```bash
1. 强制重排(Reflow)
→ 修改布局属性(width/height/margin/padding/position)
→ 浏览器要重新计算所有元素的位置和大小
2. 重绘(Repaint)
→ 修改外观属性(color/background/box-shadow)
→ 不影响布局,但浏览器要重新绘制
3. 合成(Composite)
→ 用 transform 和 opacity 做的动画
→ 在单独的层上处理,不影响主线程
→ 最流畅!
4. JavaScript 修改样式
→ 批量修改用 class,不要一行行改 style
```
```javascript
// ❌ 不推荐:多次重排
el.style.width = '100px';
el.style.height = '100px';
el.style.margin = '10px';
// ✅ 推荐:一次 class 切换,一次重排
el.className = 'box-active';
```
六、CSS vs —— 其实没有真正的竞品
CSS 是浏览器渲染的唯一标准。没有其他选择。
但有一些工具和概念可以"减少写 CSS":
| 方案 | 核心思想 | 适合谁 |
|------|---------|-------|
| 原生 CSS | 直接写 .css 文件 | 所有人(必学) |
| SCSS / Sass | CSS 的增强版(变量/嵌套/混合) | 项目较大的团队 |
| Tailwind CSS | 不写 CSS,用原子类名组合 | 快速开发、现代项目 |
| CSS Modules | 每个组件自动隔离样式 | React/Vue 项目 |
| Styled Components | 把 CSS 写在 JS 里 | React 项目 |
| Bootstrap | 现成的 UI 组件库 | 不想从头写 CSS |
**但不管用哪个——你都得先懂 CSS。** 就像不管开手动挡还是自动挡,都得先懂交规。
七、⚠️ 常见坑
**!important 依赖症**
```css
/* 新手经常做的事:CSS 不生效 → 加 !important → 好了 */
.text-color { color: red !important; }
/* 但之后每个人都要用 !important 来覆盖你 */
.other-text { color: blue !important; } /* 只能继续加 */
/* 最后全文件充满 !important,谁都不敢删 */
/* 正确做法:提高选择器优先级,不要用 !important */
.container .text-color { color: red; } /* 权重更高 */
```
**Flex 和 Grid 分不清**
```bash
# 什么时候用 Flex?
单行或单列排列 → 导航栏、按钮组、标签页
需要居中 → 什么居中都行
内容大小不确定 → 分配剩余空间
# 什么时候用 Grid?
行和列同时控制 → 网格式的页面布局
两栏/三栏经典布局 → header/main/footer
元素要跨行跨列 → Grid 天生支持
```
**简单规则:一维用 Flex,二维用 Grid。**
**百分比和内边距的冲突**
```css
/* ❌ 设了宽度 50%,再加 padding,实际超过 50% */
.column {
width: 50%;
padding: 20px; /* 实际变成 50% + 40px */
}
/* ✅ 用 border-box 解决 */
*, *::before, *::after {
box-sizing: border-box;
}
```
**reset.css / normalize.css 没加**
不同浏览器的默认样式不同。不加重置样式表:
```bash
Chrome 的 <h1> 是 32px
Firefox 的 <h1> 是 28px
Safari 的 <body> 有 8px margin,别的浏览器可能没有
```
解决方案——在所有 CSS 文件之前引入:
```css
/* normalize.css:保留有用的默认样式,统一不一致的地方 */
@import "normalize.css";
/* 或者更激进的 reset:去掉所有默认样式,从零开始 */
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
```
**垂直居中**
这是 CSS 圈著名的"段子"——每个新手都会问"怎么垂直居中":
```css
/* 2025 年的答案——一行搞定 */
.parent {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中(可选) */
}
```
写在最后
CSS 是所有 Web 技术里最"分裂"的一门——喜欢它的人觉得它让设计变得无比自由,讨厌它的人觉得它是最不讲逻辑的语言(为什么我改了颜色没生效?为什么这个元素不在我期望的位置上?)。
这两种感受都是真实的。CSS 不是传统意义上的"编程语言",它没有变量、没有函数、没有逻辑控制。但它有自己的逻辑——**选择器优先级、层叠规则、盒模型、布局上下文**——理解这些之后,CSS 的行为其实是可预测的。
CSS 最让人爱恨交织的地方在于:**用起来门槛极低(几行代码就能改颜色和字号),但精通极难(要懂渲染原理、性能优化、各种奇技淫巧)。**
但有一点是确定的——**没有 CSS 的 Web 是一个文字堆砌的黑白世界。** CSS 把互联网从文档变成了设计,从"能看"变成了"好看"。
就冲这一点,值得你花时间好好学它。
本文由 AI 生成,内容仅供参考。CSS 属性和规范更新较快,具体用法请以 MDN 文档(developer.mozilla.org/zh-CN/docs/Web/CSS)为准。
—— 全文完 ——
CSS —— 让网页从"能看"变成"好看"的那层皮
文章评论 0 条
U
👍
👎
@
K
Kevin
2 小时前
Rust 的 async 生态终于要完善了!Async Iterator 和 async closure 这两块一直是我觉得最欠缺的。期待今年的进展!
👀 12
💬 回复
S
Sarah
5 小时前
编译速度优化这块太重要了,我们项目从 5 分钟降到 2 分钟就是巨大的效率提升。期待并行前端解析的上线。
👀 8
💬 回复
查看更多评论 →