width/height,padding,border,margin,outline,box-shadow,box-sizing,盒子之间的合并和塌陷问题
1. 盒子模型介绍
生活中, 经常会看到各种各样的盒子:礼物盒,手机盒等
页面中的每一个标签,都可以看做是一个盒子,通过盒子的视角更方便的进行布局
浏览器在渲染网页时,会将网页中的元素看做是一个个的矩形区域,形象的称之为盒子
CSS中规定每个盒子分别由4个区域构成
内容(content)- 元素的内容width/height
内边距(padding)- 元素和内容之间的间距
边框(border)- 元素自己的边框
外边距(margin)- 元素和其他元素之间的间距
因为盒子有四边, 所以margin/padding/border都包括top/right/bottom/left四个边

2. 内容 – width和height
设置内容是通过宽度和高度设置的
- 宽度设置:width
- 高度设置:height
注意:
对于行内级非替换元素来说, 设置宽高是无效的!还可以设置如下属性
- min-width:最小宽度,无论内容多少,宽度都大于或等于min-width
- max-width:最大宽度,无论内容多少,宽度都小于或等于max-width
- 移动端适配时, 可以设置最大宽度和最小宽度
下面两个属性不常用
- min-height:最小高度,无论内容多少,高度都大于或等于min-height
- max-height:最大高度,无论内容多少,高度都小于或等于max-height
3. 内边距 - padding
padding属性用于设置盒子的内边距, 通常用于设置边框和内容之间的间距
padding包括四个方向, 所以有如下的取值
- padding-top:上内边距
- padding-right:右内边距
- padding-bottom:下内边距
- padding-left:左内边距
padding单独编写是一个缩写属性
- padding-top、padding-right、padding-bottom、padding-left的简写属性
- padding缩写属性是从零点钟方向开始, 沿着顺时针转动的, 也就是
上右下左
padding并非必须是四个值, 也可以有其他值
padding值个数 padding例子 代表的含义 4 padding: 10px 20px 30px 40px;top: 10px, right: 20px, bottom: 30px, left: 40px;3 padding: 10px 20px 30px;缺少left, left使用right的值 2 padding: 10px 20px;缺少left, 使用right的值; 缺少bottom, 使用top的值 1 padding: 10px;top/right/bottom/left都使用10px
4. 边框 - border
- border用于设置盒子的边框
- 边框相对于content/padding/margin来说特殊一些
- 边框具备宽度width
- 边框具备样式style
- 边框具备颜色color
4.1. 边框宽度
- border-top-width、border-right-width、border-bottom-width、border-left-width
- border-width是上面4个属性的简写属性
4.2. 边框颜色
- border-top-color、border-right-color、border-bottom-color、border-left-color
- border-color是上面4个属性的简写属性
4.3. 边框样式
border-top-style、border-right-style、border-bottom-style、border-left-style
border-style是上面4个属性的简写属性
边框的样式设置值
- solid:实线
- dash:虚线
- dotted:点线
- double:双实线
- inset:凹陷
- outset:突出
- groove:凹槽, 沟槽, 边框看上去好象是雕刻在画布之内
- ridge:山脊,和grove相反,边框看上去好象是从画布中凸出来
4.4. 同时设置的方式
相对某一边同时设置 宽度 样式 颜色, 可以进行如下设置
- border-top
- border-right
- border-bottom
- border-left
- border:统一设置4个方向的边框
边框颜色、宽度、样式的编写顺序任意
1 | border: 1px solid red; |
4.5. 圆角 – border-radius
border-radius用于设置盒子的圆角
border-radius常见的值
数值:通常用来设置小的圆角, 比如6px
百分比
通常用来设置一定的弧度或者圆形
会因为盒子宽高值不同而圆角不圆润
1
2
3
4
5
6
7div {
background-color: blue;
width: 200px;
height: 100px;
border: 10px solid red;
border-radius: 10%;
}

border-radius事实上是一个缩写属性
- 将这四个属性 border-top-left-radius、border-top-right-radius、border-bottom-right-radius,和 border-bottom- left-radius 简写为一个属性
如果一个元素是正方形, 设置border-radius大于或等于50%时,就会变成一个圆
4.6. 边框的形状
1 | <div class="box"></div> |
border主要是用来给盒子增加边框的, 但是在开发中也可以利用边框的特性来实现一些形状

1
2
3
4
5
6
7
8
9
10
11
12.box {
width: 100px;
height: 100px;
background-color: #f00;
box-sizing: border-box;
border: 30px solid orange;
border-top-color: blue;
border-right-color: green;
border-bottom-color: purple;
}将border宽度设置成50会是什么效果?

1
2
3
4
5
6
7
8
9
10
11
12.box {
width: 100px;
height: 100px;
background-color: #f00;
box-sizing: border-box;
border: 50px solid orange;
border-top-color: blue;
border-right-color: green;
border-bottom-color: purple;
}将border另外三边的颜色去除会是什么效果?

1
2
3
4
5
6
7
8
9
10
11
12.box {
width: 100px;
height: 100px;
/* background-color: #f00; */
box-sizing: border-box;
border: 50px solid orange;
border-top-color: transparent;
border-right-color: transparent;
border-bottom-color: transparent;
}如果将这个盒子旋转呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14.box {
width: 100px;
height: 100px;
/* background-color: #f00; */
box-sizing: border-box;
border: 50px solid orange;
border-top-color: transparent;
border-right-color: transparent;
border-bottom-color: transparent;
transform: rotate(90deg);
}所以利用border或者CSS的特性可以做出很多图形
5. 外边距 - margin
margin属性用于设置盒子的外边距, 通常用于元素和元素之间的间距
margin包括四个方向, 所以有如下的取值
- margin-top:上内边距
- margin-right:右内边距
- margin-bottom:下内边距
- margin-left:左内边距
margin单独编写是一个缩写属性
- margin-top、margin-right、margin-bottom、margin-left的简写属性
- margin缩写属性是从零点钟方向开始, 沿着顺时针转动的, 也就是
上右下左
margin也并非必须是四个值, 也可以有其他值
margin值的个数 margin例子 代表的含义 4 margin: 10px 20px 30px 40px;top: 10px, right: 20px, bottom: 30px, left: 40px;3 margin: 10px 20px 30px;缺少left, left使用right的值 2 margin: 10px 20px;缺少left, 使用right的值; 缺少bottom, 使用top的值 1 margin: 10px;top/right/bottom/left都使用10
5.1. 上下margin的传递
margin-top传递
- 如果块级元素的顶部线和父元素的顶部线重叠,那么这个块级元素的margin-top值会传递给父元素
margin-bottom传递
- 如果块级元素的底部线和父元素的底部线重写,并且父元素的高度是auto,那么这个块级元素的margin-bottom值会传递给父元素
如何防止出现传递问题?
- 给父元素设置padding-top/padding-bottom
- 给父元素设置border
- 触发BFC:父元素设置overflow为auto
- 转换成行内块元素
- 设置浮动
- 使用双伪元素清除浮动
建议
- margin一般是用来设置兄弟元素之间的间距
- padding一般是用来设置父子元素之间的间距
5.2. 上下margin的折叠
垂直方向上相邻的2个margin(margin-top、margin-bottom)有可能会合并为1个margin,这种现象叫做collapse(折叠)
水平方向上的margin(margin-left、margin-right)永远不会collapse
折叠后最终值的计算规则
- 两个值进行比较,取较大的值
如何防止margin collapse?
- 只设置其中一个元素的margin
上下margin折叠的情况
- 两个兄弟块级元素之间上下margin的折叠
- 父子块级元素之间margin的折叠
6. 元素默认内外边距
- 浏览器会默认给部分标签设置默认的margin和padding,但一般在项目开始前需要先清除这些标签默认的margin和padding,后续自己设置
- body标签默认有margin
- p标签默认有上下的margin
- ul标签默认有上下的margin和padding-left
解决方法
淘宝网代码
1
2
3
4blockquote,body,button,dd,dl,dt,filedset,form,h1,h2,h3,h4,h5,h6,hr,input,legend,li,ol,p,pre,td,textarea,ul{
margin: 0;
padding: 0;
}京东代码
1
2
3
4*{
margin: 0;
padding: 0;
}
7. 行内非替换元素注意事项
7.1. width/height
- 不生效
7.2. padding
- 水平方向的padding布局有效,占据空间
- 垂直方向的padding布局有效,但是不占据空间
7.3. border
- 水平方向的border布局有效,占据空间
- 垂直方向的border布局有效,但是不占据空间
7.4. margin
- 水平方向的margin布局有效
- 垂直方向的margin布局无效
8. 外轮廓 - outline
outline表示元素的外轮廓
- 不占用空间
- 默认显示在border的外面
outline相关属性有
- outline-width:外轮廓的宽度
- outline-style:取值跟border的样式一样,比如solid、dotted等
- outline-color:外轮廓的颜色
- outline:outline-width、outline-style、outline-color的简写属性,跟border用法类似
应用实例
去除a元素、input元素的focus轮廓效果
1
2
3a {
outline: none;
}等价于设置了 a:link,a:visited,a:focus,a:hover,a:active的outline
9. 盒子阴影 – box-shadow
box-shadow 属性可以设置一个或者多个阴影
- 每个阴影用
<shadow>表示 - 多个阴影之间用逗号,隔开,从前到后叠加
- 每个阴影用
shadow的常见格式如下
1
<shadow> = <color>? &&[ <length>{2} <length [0,∞]>?<length>?]&&inset?
- 当给出两个、三个或四个
<length>值时- 如果只给出两个值,那么这两个值将会被当作
<offset-x> <offset-y> - 如果给出了第三个值,那么第三个值将会被当作
<blur-radius> - 如果给出了第四个值,那么第四个值将会被当作
<spread-radius>
- 如果只给出两个值,那么这两个值将会被当作
- 可选,
inset关键字 - 可选,
<color>值
- 当给出两个、三个或四个
offset-x
- 设置水平偏移量,正值阴影则位于元素右边,负值阴影则位于元素左边
offset-y
- 设置垂直偏移量,正值阴影则位于元素下方,负值阴影则位于元素上方
blur-radius
- 模糊半径。值越大,模糊面积越大,阴影就越大越淡。不能为负值。默认为 0,此时阴影边缘锐利
spread-radius
- 延伸半径。取正值时,阴影扩大;取负值时,阴影收缩。默认为 0,此时阴影与元素同样大
color
- 阴影的颜色,如果没有设置,就跟随color属性的颜色
inset
- 外框阴影变成内框阴影,默认阴影在边框外
案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14/* x 偏移量 | y 偏移量 | 阴影颜色 */
box-shadow: 60px -16px teal;
/* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影颜色 */
box-shadow: 10px 5px 5px black;
/* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色 */
box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);
/* 插页 (阴影向内) | x 偏移量 | y 偏移量 | 阴影颜色 */
box-shadow: inset 5em 1em gold;
/* 任意数量的阴影,以逗号分隔 */
box-shadow: 3px 3px red, -1em 0 0.4em olive;拓展
- 当
offset-x、offset-y和blur-radius都是 0,盒阴影将是一个四边都是一样长度的带有颜色的outline - 当设置了多个阴影时,阴影绘制由最后一个开始,故第一个设置的阴影将覆盖在后设置的阴影之上
- 当
测试盒子的阴影
10. 盒子大小问题
10.1. 盒子实际大小计算公式
盒子尺寸400*400,背景绿色,边框10px 实线 黑色
1 | /* 这是错误的,这样设置的div的尺寸为460*460 */ |
设置width和height是内容的宽高!
设置border,padding会撑大盒子!
盒子实际大小计算公式
- 盒子宽度 = 左边框+左内边距+内容宽度+右内边距+右边框
- 盒子高度 = 上边框+上内边距+内容高度+下内边距+下边框
10.2. 不会撑大盒子的特殊情况
- 如果子盒子没有设置宽度,此时宽度默认是父盒子的宽度
- 此时子盒子设置左右的padding或者左右的border,此时不会撑大盒子
10.3. CSS属性 - box-sizing
- box-sizing用来设置盒子模型中宽高的行为
- content-box
- padding、border都布置在width、height外边
- 元素的实际占用宽度 = border + padding + width
- 元素的实际占用高度 = border + padding + height
- border-box
- padding、border都布置在width、height里边
- 元素的实际占用宽度 = width
- 元素的实际占用高度 = height
11. IE盒子模型
W3C标准盒子模型
box-sizing: content-box;

IE盒子模型(IE8以下浏览器)
box-sizing: border-box;
