什么是盒子模型
当你对一个文档进行布局 (laying out) 时候, 浏览器引擎会根据 CSS-Box 模型将所有元素描述为一个盒子, CSS 会决定这些盒子的大小, 位置, 属性(颜色, 边框...).
盒模型分类
盒模型分为两类: IE 盒模型和标准盒模型. 两者的区别在于:
IE 盒模型的 width/height = content + border + padding
标准盒模型的 width/height = content
IE 盒模型
标准盒模型
普通文档流块元素的 CSS 外边距合并问题
- <style>
- * {
- margin: 0;
- padding: 0;
- }
- .demo1 {
- width: 40px;
- height: 40px;
- background: pink;
- padding: 10px;
- margin: 10px 0;
- border: 2px solid pink;
- }
- .demo2 {
- width: 40px;
- height: 40px;
- padding: 10px;
- background: blue;
- margin: 20px 0;
- border: 2px solid blue;
- }
- </style>
- <div class="demo1"></div>
- <div class="demo2"></div>
可见 demo1 与 demo2 的外边距为 20px. 而不是 30px.
需要注意的是: 只有普通文档流中块框的垂直外边距才会发生外边距合并. 行内框, 浮动框或绝对定位之间的外边距不会合并.
改变盒子模型
CSS3 支持改变盒子模型.
box-sizing
box-sizing 用来改变计算盒子高度 / 宽度的默认盒子模型. 可以使用此属性来模拟不正确支持 CSS 盒子模型规范的浏览器的行为.
- /* 关键字 值 */
- box-sizing: content-box;
- box-sizing: border-box;
- /* 全局 值 */
- box-sizing: inherit;
- box-sizing: initial;
- box-sizing: unset;
content-box(默认值): 标准盒模型
宽度 = 内容的宽度
高度 = 内容的高度
不会包含 border, padding.
demo 演示:
- .demo1 {
- box-sizing: content-box;
- width: 40px;
- height: 40px;
- background: pink;
- padding: 10px;
- margin: 10px 0;
- border: 2px solid pink;
- }
- <div class="demo1"></div>
盒子内容宽度就是 40px;
border-box: 怪异模式
width = border + padding + 内容的 width,
height = border + padding + 内容的 height.
demo 演示:
- .demo {
- box-sizing: border-box;
- width: 40px;
- height: 40px;
- background: pink;
- padding: 10px;
- margin: 10px 0;
- border: 2px solid pink;
- }
- <div class="demo"></div>
盒子的内容宽度为 16px;
padding-box: 已经弃用
inherit: 规定应从父元素继承 box-sizing 属性的值
为什么要使用 border-box
content-box 缺点
当你想让两个子容器 float:left, 宽度各 50%, 然后给一点 padding, 最后让子容器并排充满父容器, 一切想的挺美好, 然而你发现结果并不是这么美好, 因为子容器的盒子宽度已经超出了父容器的一半, 导致了折行, 于是, width 就不能 50% 了, 只能是 50% 再减去 padding 的像素值
- <style>
- * {
- margin: 0;
- padding: 0;
- }
- .demo div {
- float: left;
- width: 50%;
- height: 100px;
- padding: 0 10px;
- }
- .demo1 {
- background: pink;
- }
- .demo2 {
- background: blue;
- }
- </style>
- <div class="demo">
- <div class="demo1"></div>
- <div class="demo2"></div>
- </div>
border-box 的优势:
border-box 的诞生, 主要就是解决 content-box 的最大缺点. border-box 意味着子容器的 padding 和 border 的厚度都算在 50% 之内, 这样, 你可以随意的修改 padding 和 border 的厚度值, 根本不用担心父容器被撑爆.
简单修改下上述代码.
- .demo div {
- box-sizing: border-box;
- float: left;
- width: 50%;
- height: 100px;
- padding: 0 10px;
- }
因此 border-box 使用场景如下:
子元素有 padding 和 border, 或者至少有其一, 并且需要给子元素设定 100% 宽度(或者 50% 宽度等等), 这时候显然需要 border-box. 设为 border-box 之后, padding 和 border 的厚度可以随意调, 并不会溢出父元素. 如果是 content-box, 那么, 宽度必然会溢出, 而且, 为了不溢出, 你设定子元素的宽度就只能是一个定值, 或者是一个计算值(比如 calc(100% - 20px).
来源: https://juejin.im/post/5c6d6c566fb9a049aa6faba7