大家好,我叫【小奇腾】,你们有没有遇到过这种情况?明明设置了两个
width: 50%的盒子想让它们并排,结果右边那个死活都要掉到下一行去?难道是
50% + 50% > 100%?数学老师骗了我们? 不,是 CSS 盒模型 在“欺骗”你的眼睛。今天这节课,我们不背枯燥的概念
本期详细的视频教程bilibili:CSS 盒子又“炸”了?一文看懂标准盒模型 vs 怪异盒模型
一、盒子的“解剖学”:洋葱是怎么剥开的?
在开始区分”标准盒模型 vs 怪异盒模型“之前,我们先了解什么是盒子模型的基本组成,想象你现在手里拿着一个橘子🍊,准备送给朋友。CSS 的盒子模型(Box Model)和这个橘子🍊一模一样,由从内到外的四层组成:
-
Content(果肉) :最核心好吃的那个部分
-
Padding(果皮) :保护果肉的缓冲层。注意:果皮和果肉是一体的,果肉烂了(背景色),果皮通常也是那个颜色。
-
Border(包装盒) :最外层的硬壳。它是橘子和外界的分界线。
-
Margin(社交距离) :这一箱橘子和那一箱苹果之间,必须留出的空气缝隙。
划重点:Margin 是用来推开别人的,不属于盒子本身的大小;而 Content + Padding + Border 才是盒子自己的“肉身”。
盒子模型的示意图
在浏览器,自己写一个盒子,然后通过检查工具,就可以看到盒子模型的样子。
.box {
width: 200px;
height: 200px;
border: 10px solid #ccc;
padding: 30px;
margin: 20px;
}
<div class="box"></div>
- 盒子模型图
- 盒子模型的每个部分(当我的鼠标放在盒子模型上)
- content(内容区)
宽度200 x 高度200 - padding(内边距)
4个内边距都是 30 - border(边框)
4条边框都是 10 - margin(外边距)
4个外边距都是 20
- content(内容区)
二、 直觉的陷阱:你要买多大的橘子?
在我们的直觉里,如果我们买一个宽 100px 的盒子,那这个盒子占的地方应该就是 100px,对吧?
但在 CSS 的标准盒模型(Standard Box Model) 里,逻辑是反直觉的。
🍊 橘子比喻
想象你去买橘子。
- Content(内容区) :是橘子果肉。
- Padding(内边距) :是橘子皮。
- Border(边框) :是包装盒。
当你写下 width: 100px 时,你以为你控制了整个橘子的大小。 实际上,你只控制了“橘子果肉”的大小。
如果你给这个橘子穿上 20px 厚的皮(padding),再套上 5px 厚的壳(border)。 浏览器是这样算账的(做加法):
实际占地宽度 = 果肉(100) + 左皮(20) + 右皮(20) + 左壳(5) + 右壳(5) 结果 = 150px!
💥 案发现场
你有一个盒子里面装了两个子盒子,里面两个子盒子你设置了 width: 50%,但只要你加了一丁点 padding 或 border,这个盒子的实际宽度就变成了 50% + 皮。 两个胖子挤在一起,总宽度超过了 100%,父容器装不下,右边的胖子就被挤下去了。这就是标准盒模型给新手挖的最大的坑。
代码示例
从代码中,可以看到给两个子元素都给的50%的宽度,按道理是应该平并排在.box这个父盒子里的,但是却掉下来了一个.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 1000px;
display: flex;
flex-wrap: wrap;
border: 4px solid purple;
}
.left {
width: 50%;
padding: 20px;
border: 5px solid #ccc;
background-color: red;
}
.right {
width: 50%;
padding: 20px;
border: 5px solid blue;
background-color: green;
}
</style>
</head>
<body>
<div class="box">
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
效果图:
二、 救星登场:怪异盒模型(Border-box)
为了解决这个问题,CSS 提供了一个属性,虽然它以前被称为“怪异盒模型”(Quirks Mode),但我觉得它应该叫**“省心盒模型”**。
即:box-sizing: border-box;
📦 快递箱比喻
在这个模式下,盒子就像一个快递箱。 当你写下 width: 100px 时,这个箱子死锁就是 100px 宽,雷打不动。
如果你非要往里面塞 20px 的泡沫(padding):
- 泡沫可以被压缩,箱子外壳不会变大(不会撑破布局)。
- 只能委屈里面的空间(Content)变小。
计算这里发生了什么
还是刚才的数据,但这次我们加上了 box-sizing: border-box 给到两个子盒子;
-
CSS 设置:
width: 100px,padding: 20px,border: 5px -
浏览器实际渲染宽度:100px(不用算了,就是它!)
-
里面的内容还能剩多少空间?
100px (总宽) - 40px (左右皮) - 10px (左右壳) = 50px
虽然内容区被挤小了,但你的页面布局稳如泰山,绝对不会乱跑!
三、 终极一招:一行代码走天下
在实际开发中,我们不想每次写个 div 都要掏出计算器算宽度。怪异盒模型”好用也更符合直觉, 比如淘宝、京东页面,前端工程师们都会在CSS的第一行加上box-sizing: border-box。
这句话翻译过来就是:
“浏览器你给我听好了!从现在开始,我说这个盒子宽 100px,它就是 100px。不管我加多少内边距和边框,你都得自己在内部消化,绝对不准把盒子撑大!”
四、总结一下
- 盒子四要素:Content(橘子果肉)、Padding(橘子果皮)、Border(包装壳)、Margin(橘子和其他物品距离)。
- 标准盒模型:
width只管肉,加皮会变胖(容易炸布局)。 - 怪异盒模型:
width管整体,加皮肉变少(布局超稳定)。 - 建议:开局一条
box-sizing: border-box,写代码少掉很多头发。