摘要:本文系统讲解 CSS 盒子模型的核心知识,从块级盒子与行内盒子的区别、盒子模型的四大组成部分,到边框、圆角、内边距、外边距的用法,再到外边距折叠与塌陷、盒子的尺寸计算(box-sizing)、背景、阴影、过渡以及文字溢出省略号等实战技巧,最后介绍 CSS 样式初始化(Reset / Normalize)的两种方案与真实开发流程,帮助读者建立完整的布局基础。
所有的 HTML 元素都被一个个无形的“盒子”包围着。学会盒子模型,就掌握了 CSS 精准布局、处理元素排列与间距的关键。
目录
一、盒子类型:块级盒子 vs 行内盒子
二、盒子模型的四大组成部分
三、边框(Border)
1. 基本语法
2. 四个方向单独设置
四、圆角边框(Border-radius)
1. 基础用法
2. 特殊形状
3. 四个角分别设置(顺时针记忆)
五、内边距(Padding)
1. 简写规则(顺时针记忆)
2. 单边设置
六、外边距(Margin)
1. 简写规则(与 Padding 完全一致,顺时针)
2. 单边设置
3. 块级盒子水平居中(经典技巧)
七、外边距的折叠与塌陷(高频易错点)
1. 兄弟关系 —— 外边距折叠(合并)
2. 父子关系 —— 外边距塌陷(严重问题)
八、盒子的尺寸计算(Box-sizing) —— 核心难点
1. 默认模式:content-box(标准盒模型)
2. 推荐模式:border-box(怪异盒模型 / IE盒模型)
九、盒子背景(Background)
十、盒子阴影(Box-shadow)
十一、过渡(Transition)
十二、文字溢出显示省略号(实战必备)
1. 单行文字溢出
2. 多行文字溢出(WebKit 内核)
CSS 样式初始化(CSS Reset / Normalize)
一、为什么要进行样式初始化?
1. 常见的默认样式差异示例
2. 初始化的核心目的
二、两种初始化方案
方案一:简单重置(简单粗暴型)
方案二:Normalize.css(推荐,生产环境标准)
工作流程总结(真实开发习惯)
一、盒子类型:块级盒子 vs 行内盒子
在 CSS 中,盒子分为两种主要类型,它们在页面中的表现截然不同。
| 特性 | 区块盒子(Block Box) | 行内盒子(Inline Box) |
|---|---|---|
| 换行 | 会产生换行(独占一行) | 不会产生换行(在一行内并列) |
| 宽高 | width/height生效 | width/height不起作用 |
| 默认宽度 | 不设宽度时,默认填满父元素 100% 空间 | 由内容撑开 |
| 内边距/外边距 | 上下左右内外边距都生效 | 垂直方向(上下)的内外边距不起效果; 水平方向(左右)的内外边距有效 |
| 常见标签 | <div>、<p>、<h>、<ul>、<table> | <span>、<em>、<a>、<strong> |
小总结:块级独占一行,宽高有效;行内并排显示,宽高无效,垂直内外边距无效。
二、盒子模型的四大组成部分
一个完整的盒子由内到外包含四部分:内容(Content)→内边距(Padding)→边框(Border)→外边距(Margin)。
- 内容(Content):显示文字、图片的区域。大小由
width/height或内容本身撑开。 - 内边距(Padding):内容区域到边框之间的内部间距。
- 边框(Border):包裹内容和内边距的边界线。
- 外边距(Margin):盒子外部与其他元素之间的间距(不可见)。
三、边框(Border)
1. 基本语法
边框由三个属性值组成:border: 粗细 样式 颜色;(三者顺序无要求,中间用空格隔开)。
div { border: 2px solid red; /* 实线 */ border: 1px dashed blue; /* 虚线 */ border: 1px dotted pink; /* 点状虚线 */ }常用边框样式:
| 样式值 | 描述 | 视觉效果 |
|---|---|---|
solid | 实线边框 | 单一条直线 |
dashed | 虚线边框 | 短横线组成 |
dotted | 点状边框 | 圆点组成 |
2. 四个方向单独设置
根据方位名词top(上)、bottom(下)、left(左)、right(右)分别控制。
div { border-top: 1px solid pink; /* 只设上边框 */ border-bottom: 2px solid #000; /* 只设下边框(常用作分割线) */ border-left: none; /* 取消左边框 */ border-right: 1px dashed #ccc; }四、圆角边框(Border-radius)
border-radius允许设置元素的外边框圆角,让盒子更精致。
1. 基础用法
button { border-radius: 10px; /* 四个角都是 10px 圆角 */ }2. 特殊形状
| 目标形状 | 实现技巧 |
|---|---|
| 胶囊按钮 | 长方形设置border-radius为高度的一半 |
| 正圆形 | 正方形(确保原图或原本边框为正方形)设置border-radius为高度的一半或50% |
/* 胶囊按钮 */ .radius3 { width: 200px; height: 40px; margin: 20px; background-color: skyblue; /* 圆角边框 */ border-radius: 40px; /* 胶囊按钮设置圆角宽度或者高度的一半较小值就可以实现 */ /* 文字居中 */ text-align: center; line-height: 40px; } /* 圆形头像 */ .avatar { width: 100px; height: 100px; /*如果图片非正圆进行压缩 */ border-radius: 50%; /* 或者 50px */ }3. 四个角分别设置(顺时针记忆)
语法:border-radius: 左上 右上 右下 左下;(顺时针,中间空格隔开)
| 写法 | 作用 |
|---|---|
border-radius: 10px 20px 30px 40px; | 左上10,右上20,右下30,左下40 |
border-radius: 10px 20px 30px; | 左上10,右上/左下20,右下30 |
border-radius: 10px 20px; | 左上/右下10,右上/左下20 |
border-radius: 10px; | 四角都是10 |
.radius1 { width: 200px; height: 200px; margin: 20px; background-color: pink; /* 圆角边框 */ border-radius: 20px; /* 圆角边框2 左上和右下圆角20px 右上和左下圆角40px */ border-radius: 20px 40px; /* 圆角边框3 顺时针记忆,中间空格隔开 左上圆角20px 右上圆角40px 右下圆角60px 左下圆角80px */ border-radius: 20px 40px 60px 80px; }不需要圆角的角设置为
0即可。
五、内边距(Padding)
内边距位于边框和内容区域之间,用于让内容不要紧贴边框,更美观。
1. 简写规则(顺时针记忆,与边框圆角都类似语法)
语法:padding: 上 右 下 左;(顺时针)
| 写法 | 作用 |
|---|---|
padding: 10px; | 上下左右四个内边距都是 10px |
padding: 10px 20px; | 上下 10px,左右 20px |
padding: 10px 20px 30px; | 上 10px,左右 20px,下 30px |
padding: 10px 20px 30px 40px; | 上10,右20,下30,左40(顺时针) |
2. 单边设置
div { padding-top: 10px; padding-bottom: 10px; padding-left: 20px; padding-right: 20px; }六、外边距(Margin)
外边距是盒子外部不可见的空间,用于推开其他元素,拉开距离。
1. 简写规则(与 Padding 完全一致,顺时针)
语法:margin: 上 右 下 左;
| 写法 | 作用 |
|---|---|
margin: 10px; | 四边都是 10px |
margin: 10px 20px; | 上下10,左右20 |
margin: 10px 20px 30px; | 上 10px,左右 20px,下 30px |
margin: 10px 20px 30px 40px; | 上10,右20,下30,左40 |
2. 单边设置
div { margin-top: 10px; margin-right: 10px; margin-bottom: 10px; margin-left: 10px; }3. 块级盒子水平居中(经典面试问题技巧)
条件:块级盒子必须有宽度,且左右外边距设为auto。
.box { width: 200px; height: 200px; margin: 0 auto; /* 上下为0,左右自动均分,实现水平居中 */ }常见其他大厂写法:
margin-left: auto; margin-right: auto;
margin:auto;(jd写法,示例为b站写法)
七、外边距的折叠与塌陷
1. 兄弟关系 —— 外边距折叠(合并)
现象:两个并列的块级元素,上下外边距会合并为一个,大小取较大的那个。
.box1 { margin-bottom: 30px; } .box2 { margin-top: 20px; } /* 实际两个盒子之间的距离是 30px,而不是 50px */解决方案:这是浏览器特性,无需解决。我们只需给其中一个盒子设置单边外边距即可,比如只设置margin-bottom。
2. 父子关系 —— 外边距塌陷(严重问题)
现象:给子盒子设置上外边距(margin-top),父盒子会跟着一起往下掉(塌陷)。
/* 父盒子没有边框 */ .father { width: 300px; background: pink; } .son { width: 100px; height: 100px; margin-top: 50px; } /* 结果:父盒子带着子盒子一起往下掉了50px */注意:塌陷只发生在块级元素之间。外边距塌陷是块级盒子特有的行为,因为只有块级元素才会参与垂直方向的外边距合并。其他元素,比如图片(<img>)、行内元素(<span>、<a>)等,不会发生塌陷。原因在于:
- 图片是行内替换元素:它不参与块级格式化上下文中的外边距合并规则,给图片设置
margin-top会直接生效,不会把父盒子带下去。 - 行内元素垂直外边距无效:行内盒子的上下外边距本身就不起作用(前面盒子类型一节讲过),自然谈不上塌陷。
- 浮动、绝对定位的元素:它们脱离了普通文档流,也不会触发外边距塌陷。
所以,外边距塌陷的触发前提是:父子双方都是普通文档流中的块级盒子。如果你发现某个元素设置了margin-top却没有塌陷,先检查它是不是块级元素。
3 种解决方案:
- 给父盒子添加上边框(
border-top: 1px solid transparent;)。 - 给父盒子添加上内边距(
padding-top: 1px;)。 - 给父盒子添加
overflow: hidden;(触发 BFC,最推荐)。
.father { overflow: hidden; /* 完美解决,无副作用 */ }八、盒子的尺寸计算(Box-sizing) —— 核心难点
默认情况下(content-box),width和height只代表内容区域的大小。一旦添加了padding和border,整个盒子的可见宽度会被撑大,这给布局计算带来很大困扰。
1. 默认模式:content-box(标准盒模型)
/* 默认值,可以不写 */ box-sizing: content-box;公式:盒子实际宽度 =width+padding+border
如果你设置
width: 200px; padding: 10px; border: 5px;,最终盒子占据宽度为230px(因为上下左右都要加上)。
2. 推荐模式:border-box(怪异盒模型 / IE盒模型)
box-sizing: border-box;公式:盒子实际宽度 =width(已包含padding和border)
如果你设置
width: 200px; padding: 10px; border: 5px;,最终盒子宽度就是200px。浏览器会自动压缩内容区域来容纳内边距和边框。
实际开发中,几乎都会统一重置为border-box,这样宽度即所见即所得:
/* 通配符重置,包含伪元素 */ *, *::before, *::after { box-sizing: border-box; }九、盒子背景(Background)
背景用于装饰盒子,包括颜色、图片、位置等。
| 属性 | 作用 | 常用值 | 示例 |
|---|---|---|---|
background-color | 背景颜色 | 颜色值(十六进制、rgb) | background-color: #f0f0f0; |
background-image | 背景图片 | url(图片路径) | background-image: url(bg.png); |
background-repeat | 是否重复 | repeat(默认)、no-repeat、repeat-x、repeat-y | background-repeat: no-repeat; |
background-position | 背景定位 | x y(方位词、px、%) | background-position: center top; |
background-size | 背景尺寸 | cover(覆盖)、contain(包含)、像素/百分比 | background-size: cover; |
background-attachment | 背景固定 | scroll(滚动)、fixed(固定) | background-attachment: fixed; |
<style> .box { width: 400px; height: 400px; background-color: pink; /* 1.背景图片 */ background-image: url(./img/ldh.png); /* 2.背景平铺 / background-repeat: no-repeat; / 按照左上角水平方向平铺 */ background-repeat: repeat-x; background-repeat: repeat-y; /* 3.背景位置 / / 背景位置center center 表示背景图片居中显示,写一个也可以 / background-position: center center; / 背景位置可以是像素值 / background-position: 100px 100px; / 背景位置可以是百分比 / background-position: 50% 50%; / 背景位置可以是关键字 top left bottom right,如果只写一个,默认是另一方向是center */ background-position: top left; /* 4.背景缩放 / background-size: cover; background-size: contain; / 背景缩放可以是像素值,写一个默认自适应 / background-size: 200px 200px; / 背景缩放可以是百分比 */ background-size: 50% 50%; /* 5.背景固定 fixed 固定的,相对于当前视口 / background-attachment: fixed; / background-attachment: scroll; */ /* 复合写法 */ background: pink url(./img/ldh.png) no-repeat center center / cover fixed; } </style>背景复合写法(顺序无强制要求,空格隔开):
/* 推荐顺序:颜色 图片 重复 固定 位置/尺寸 */ background: #fff url(bg.jpg) no-repeat fixed center/cover;背景渐变:
- 线性渐变:
background: linear-gradient(to right, #ff6b6b, #4ecdc4); - 径向渐变:
background: radial-gradient(circle, #ff9a9e, #fad0c4);
文字背景渐变(高级技巧):
h1 { background: linear-gradient(to right, pink, red); -webkit-background-clip: text; /* 背景裁剪到文字 */ -webkit-text-fill-color: transparent; /* 文字填充变透明 */ }十、盒子阴影(Box-shadow)
为盒子添加阴影,增加立体感和交互反馈。
语法:box-shadow: X轴偏移 Y轴偏移 模糊半径 扩散半径 颜色;
X轴偏移和Y轴偏移:必须写。- 默认是外阴影,若改为内阴影加
inset。
.card { box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); } /* 鼠标经过阴影加深(结合过渡) */ .card:hover { box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2); }十一、过渡(Transition)
过渡用于在属性值变化时平滑切换,而不是瞬间突变。常与:hover配合使用。
过渡写在盒子身上:transition 要写在本身(
.box)而不是:hover上,这样鼠标移入、移出两个方向都有动画;写在:hover上的话,移开时阴影会瞬间消失。
语法:transition: 过渡的属性 过渡时间 运动曲线 延迟时间(可选);
- 过渡时间单位是秒(
s),如0.3s。 - 如果所有属性都要过渡,属性写
all。
| 值 | 含义 | 效果 |
|---|---|---|
| all | 过渡的属性:哪些属性变化时要产生动画。all 表示所有属性;也可以只写某一个,如transition: box-shadow 0.5s | 鼠标悬停时 box-shadow 出现、移开时消失,都会有动画 |
| 0.5s | 过渡时间:动画持续多久 | 阴影淡入淡出共 0.5 秒 |
| ease-in-out | 运动曲线:速度变化的节奏 | 先慢 → 中间快 → 结束又慢 |
| (没写) | 延迟时间:等多久才开始动画 | 可选,不写就是 0,立即开始 |
常见运动曲线对比:
- ease — 默认,快进慢出
- linear — 匀速
- ease-in — 慢进快出
- ease-out — 快进慢出
- ease-in-out — 两头慢中间快
- steps(n) — 分步跳变,可以做走马灯或逐帧动画
.box { width: 100px; transition: all 0.5s; /* 所有变化都在0.5秒内完成 */ } .box:hover { width: 200px; /* 宽度会平滑放大 */ }十二、CSS 样式初始化(CSS Reset / Normalize)
一、为什么要进行样式初始化?
浏览器(Chrome、Firefox、Safari、Edge 等)为了能让 HTML 在没有 CSS 的情况下也能“勉强可读”,会给元素附加一套默认样式(User Agent Stylesheet)。
不同浏览器的默认样式并不一致,这会导致同一个网页在不同浏览器中呈现出细微但令人头疼的差异。
1. 常见的默认样式差异示例
| 元素 | 各浏览器默认表现差异 |
|---|---|
<body> | 内外边距(margin/padding)大小不一致,有的 8px,有的 10px。 |
<h1>~<h6> | 默认font-weight粗细程度不同,font-size大小不同。 |
<ul>/<ol> | 默认padding-left缩进值不同(有的 40px,有的 20px),list-style-type(项目符号样式)也有细微区别。 |
<a> | 链接默认颜色、下划线样式在各浏览器中一致(通常蓝色+下划线),但激活态(:active)表现不同。 |
<button>/<input> | 边框(border)、背景(background)、内边距(padding)在各浏览器中差异极大。 |
2. 初始化的核心目的
- 统一浏览器默认样式:确保页面在所有浏览器中以相同的外观起步,消除环境差异。
- 减少冗余代码:不需要在每个组件中重复写
margin: 0;来覆盖默认值。 - 提高代码可维护性:基于一个干净、一致的基准样式进行开发,避免诡异的“浏览器玄学”Bug。
二、两种初始化方案
根据项目规模和需求,我们有两种主流方案:简单重置(适合小白练手/小型项目)和引入 Normalize.css(适合中大型/生产项目)。
方案一:简单重置(简单粗暴型)
- 核心思想:使用通配符选择器
*,强制抹平所有元素的内外边距,并手动将常用的块级标签重置为视觉统一的样式。 - 适用场景:个人练习、后台管理界面、对设计还原度要求不高的小型项目。
/* 1. 去除所有元素默认的内外边距(最核心) */ * { margin: 0; padding: 0; } /* 2. 取消列表(ul/ol)默认的项目符号和序号 */ ul, ol { list-style: none; } /* 3. 取消链接默认的下划线 */ a { text-decoration: none; } /* 4. 取消标题默认的加粗(让标题回归普通文本粗细,方便统一控制) */ h1, h2, h3, h4, h5, h6 { font-weight: 400; } /* 5. 取消 em / i 默认的斜体(如果需要斜体则用 font-style: italic 单独声明) */ em, i { font-style: normal; } /* 6. 给 body 一个基础字体和颜色,统一全站文字基调 */ body { font-size: 16px; font-family: "Microsoft YaHei", Arial, sans-serif; color: #333; }⚠️ 注意:虽然通配符
*方便,但性能较差(它会遍历匹配所有元素)。在大型项目中,我们极少这样写,而是使用更优的方案二。
方案二:Normalize.css(推荐,生产环境标准)
- 核心思想:保留有用的默认样式,而不是彻底抹平。
<ul> - 例如:
<h1>默认就是大标题,<b>默认就是加粗。Normalize.css 并不会把它们强制改成普通文本,而是修复各浏览器中这些默认样式的具体数值偏差。 - 这意味着你不需要完全重写所有标签,页面在未加载 CSS 时依然拥有良好的语义化可读性。
- 使用方式:直接从官网下载,或通过 CDN 引入,像外部样式表一样在 HTML 中作为第一个样式文件引入。
在<head>中的引入顺序:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 1. 最先引入 Normalize.css(修复浏览器差异) --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css"> <!-- 2. 再引入你自己的项目公共样式(覆盖/追加你的业务逻辑) --> <link rel="stylesheet" href="./css/style.css"> <title>我的项目</title> </head>- 官网下载:Normalize.css: Make browsers render all elements more consistently.
- Vue.js 官方文档、GitHub、Twitter 等大量顶级网站都在使用 Normalize.css 作为初始化基底。
工作流程总结(真实开发习惯)
- 新建项目→ 第一时间去找 Normalize.css(复制其核心代码或 CDN 引入)。
- 作为全局基底→ 把它放在所有自定义 CSS 的最前面。
- 再写公共样式→ 在
style.css中再去设置body的基础字体、背景色、通用工具类等。
这样一来,你的页面就不会被不同浏览器的“出厂设置”干扰,所有样式运行都在你自己的控制之下。