CSS 盒子模型(Box Model)详解
- 0、序言(非必要)
- 1、盒子模型的组成
- 1.0 盒子模型的总览
- 1.1 第一层 内容(content)
- 1.2 第二层 内边距(padding)
- 1.3 第三层 边框(border)
- 1.4外边距(margin)
- 2、关于盒子模型的属性和值
- 2.1 边框线(border)
- 2.2 内边距(padding)
- 2.3外边距(margin)
- 3、外边距的合并和塌陷问题
- 3.1外边距的合并
- 3.2 父元素的坍陷
- 4、总结
0、序言(非必要)
刚学前端的时候,你是不是经常遇到这种情况:
“我明明设置了宽度,为什么看起来比想象中大?”
“这个 div 怎么和另一个 div 挤在一起?”
“margin 和 padding 到底有什么区别啊啊啊?”
别急别急~(。•̀ᴗ-)✧
这些问题,几乎都和 CSS 的「盒子模型」有关。
只要把盒子模型搞懂,CSS 至少能一下子明白一半!
1、盒子模型的组成
1.0 盒子模型的总览
在 CSS 里,每一个元素,本质上都是一个盒子(Box),
不管是 div标签、span标签、p标签、img标签,还是其他什么的标签,浏览器在渲染它们的时候,都会当成一个「盒子」来处理。
这个盒子从里到外,一共由 4 个部分 组成:
┌─────────────────────┐
│margin│ ← 外边距
│ ┌───────────────┐ │
│ │border│ │ ← 边框
│ │ ┌───────────┐ │ │
│ │ │padding│ │ │ ← 内边距
│ │ │ ┌───────┐ │ │ │
│ │ │ │content│ │ │ │ ← 内容
│ │ │ └───────┘ │ │ │
│ │ └───────────┘ │ │
│ └───────────────┘ │
└─────────────────────┘
(⊙﹏⊙),看上去好复杂难懂,第一眼看上去想放弃了。
但是你先别急,其实这个类比一下就容易懂的多了,我们可以把盒子模型类比成俄罗斯套娃,层层相叠。
1.1 第一层 内容(content)
里面第一层是:核心(你所写的html的内容呈现出来的效果)
这是盒子真正放内容的地方,比如文字、图片等。
│ │ │ ┌───────┐ │ │ │
│ │ │ │content│ │ │ │ ← 内容
│ │ │ └───────┘ │ │ │
1.2 第二层 内边距(padding)
然后再套上一层内边距。(内容和边框之间的距离,相当于“缓冲区”。)
│ │ ┌───────────┐ │ │
│ │ │ padding │ │ │ ← 内边距
│ │ │ ┌───────┐ │ │ │
│ │ │ │content│ │ │ │ ← 内容
│ │ │ └───────┘ │ │ │
│ │ └───────────┘ │ │
content + padding 共同构成元素的内容区域,
1.3 第三层 边框(border)
到了这里,如果不做任何修改的话,盒子的实际大小大于你所定义的盒子的大小,因为第一层第二层都是标签的主体,而边框是套在标签的外面是一个额外的附加值,所以盒子实际的大小还要再加上边框的大小。
│ ┌───────────────┐ │
│ │border│ │ ← 边框
│ │ ┌───────────┐ │ │
│ │ │padding│ │ │ ← 内边距
│ │ │ ┌───────┐ │ │ │
│ │ │ │content│ │ │ │ ← 内容
│ │ │ └───────┘ │ │ │
│ │ └───────────┘ │ │
│ └───────────────┘ │
我们有时会用边框框住标签使得更加美观好看,但边框大小有时会影响我们的整体布局,而手动根据边框大小去减去对应盒子的大小太过烦琐,工程量大起来找起来很麻烦。
到了这个时候前人的智慧开始发挥作用了,拯救万千苍生与苦楚当中。
box-sizing:border-box;这行css代码的作用是将边框线算在元素盒子整体大小中。
也就是说,让width / height包含padding和border。
举个例子:
div{width:200px;padding:20px;border:10px solid black;box-sizing:border-box;}在上述div盒子中,本来盒子的大小应该是200px+20px,为220px
但是因为box-sizing: border-box;这行代码设置div元素的盒子大小包含了边框线大小所以还是200px。
强烈建议( •̀∀•́ )✧在开头加上,省去了计算盒子大小还有一时忘记边框也有大小的烦琐。
1.4外边距(margin)
外边距就是每个盒子与其他盒子之间的边距
┌─────────────────────┐
│margin│ ← 外边距
│ ┌───────────────┐ │
│ │border│ │ ← 边框
│ │ ┌───────────┐ │ │
│ │ │padding│ │ │ ← 内边距
│ │ │ ┌───────┐ │ │ │
│ │ │ │content│ │ │ │ ← 内容
│ │ │ └───────┘ │ │ │
│ │ └───────────┘ │ │
│ └───────────────┘ │
└─────────────────────┘
如果设置了外边距的话,盒子相当于再套上一层拒绝的刺(外边距)。外边距的大小并不影响盒子的实际大小
所以,盒子的占用空间=边框+内边距+内容
而外边距和边框的大小可以用
*{padding:0; margin:0;}让其默认值为零
2、关于盒子模型的属性和值
在实际运用中我们应该理解原理而不用去死记硬背。
2.1 边框线(border)
| 属性值 | 样式 |
|---|---|
| solid | 实线 |
| dashed | 虚线 |
| dotted | 点线 |
可以设置单方向的边框线。
用法为 border-方位名词。
2.2 内边距(padding)
用法可以用padding-方位名词。
padding-top:10px padding-right:10px padding-bottom:10px padding-left:10px或者用多值写法
padding:10px;/* 上右下左 */padding:10px 10px;/* 上下 | 左右 */padding:10px 10px 10px;/* 上 | 左右 | 下 */padding:10px 10px 10px 10px;/* 上右下左 */说明:将元素的内边距的上、右、下、左大小分别设置为10px。
2.3外边距(margin)
同上,用法可以用margin-方位名词。
margin-top:10px margin-right:10px margin-bottom:10px margin-left:10px或者用多值写法
margin:10px 10px 10px 10px说明:将元素的外边距的上、右、下、左大小分别设置为10px。
3、外边距的合并和塌陷问题
3.1外边距的合并
在css当中,垂直配列的兄弟元素,margin会合并只取最大值而不是相加,
举个例子
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title><style>.a{margin-bottom:50px;}.b{margin-top:30px;}</style></head><body><divclass="a">1</div><divclass="b">2</div></body></html>这俩者的距离应该是50px而不是80px
3.2 父元素的坍陷
举个例子
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title><style>.a{margin-bottom:50px;}.b{margin-top:30px;}.parent{background:pink;}.child{margin-top:50px;}</style></head><body><divclass="a">1</div><divclass="b">2</div><divclass="parent">3<divclass="child">4</div></div></body></html>你会发现——
child 的 margin-top 顶到了 parent 外面!
这就叫:外边距塌陷
发生外边距塌陷的条件(同时满足)
父元素 没有 border
父元素 没有 padding
父元素 没有创建新的 BFC
子元素是第一个元素(margin-top)或最后一个(margin-bottom)
本质上原因是
浏览器觉得:
“你这个 margin 也算父的吧,合并一下省点事。(´◓Д◔`)”
方法一:给父元素加 border(最简单)
.parent { border-top: 1px solid transparent; }✅ 方法二:给父元素加 padding(常用)
.parent {
padding-top: 1px;
}
✔️ 实战很常见
✔️ 同时还能调内部布局
✅ 方法三:触发 BFC(强烈推荐)
.parent { overflow: hidden; }或:
.parent { display: flow-root; }🔥 这是现代前端最推荐的方式
✅ 方法四:给父元素设 display: inline-block
.parent { display: inline-block; }✔️ 能解决
❌ 会影响布局方式(不常用)
4、总结
什么时候该用 margin?什么时候用 padding?
给你一句“不会错”的口诀:
👉 拉开盒子之间的距离,用 margin
👉 给盒子内部留空间,用 padding
你写页面时:
❌ 布局混乱,多半是盒子模型没想清楚
❌ 上下间距怪怪的,80% 是 margin 合并 / 塌陷
✅ box-sizing: border-box 先加上
✅ 父元素想“包住”子元素,优先用 padding 或 BFC
作者碎碎念╮(╯_╰)╭ (非必要):
哎,一直在尝试和调整博客的内容和风格,前面写的博客太水了,不能这样下去了,有些简单内容就跳过不说了,接下来主要将重点内容和原理说明白,尽量做到精简
(╥﹏╥)