CSS 盒模型
经典图解

如上图所述,每个 HTML 元素,都像一个盒子,而这个盒子,有content(内容),padding(填充缝隙),border(边界/外壳),margin(边缘空白)。
content:可以理解为盒子里装的内容物padding:可以理解为盒子的外壳和内容之间的缝隙(或者是填充物),就像快递盒子里面可能会填上那种充气的保护垫border:可以理解为盒子的外壳margin:可以理解为盒子与盒子间的空隙
相关属性
width 元素宽度
width:<length>|<percentage>|auto|inherit</span>
解释:
- 该属性,很明显,是用来设置元素宽度的,但是具体设置的是
content部分的宽度,还是border包含的部分的宽度,要视情况而定,本篇后面会讲 - 一般对于
inline(行级)元素设置宽度是没有意义的,只给inline-block,block或者其他某些类型的元素设置宽度 - 默认值是
auto,没有继承性,除非设置了inherit - 引申出
min-width,max-width属性,是给元素设置最小宽度和最大宽度的
height 元素高度
height:<length>|<percentage>|auto|inherit</span>
解释:
- 和
width一致
padding 填充宽度
padding:[<length>|<percentage>]{1, 4}|inherit</span>
解释:
padding是设置填充宽度的一个属性。可以设置 1 到 4 个值,分别设置上、右、下、左(顺时针)四个填充宽度,如上图。- 设置为
<percentage>时,百分比数值是相对父元素 - 也可以分开设置
padding:padding-top,padding-right,padding-bottom,padding-left。 - 举例说明:
- 写一个值的情况:
padding:20px;,说明四个方向的padding都是同一个值,也就是 20px - 写两个值的情况:
padding:20px 10px;,其实等于padding:20px 10px 20px 10px;,也就是说,如果上和下的padding相等,那么只要设置一个就够了,左右也是一样。 - 写三个值的情况:
padding:20px 10px 5px;,其实等于padding:20px 10px 5px 10px,事实上写三个就只指定了上,右和下的宽度,剩余的左宽度应该等于右边的宽度。
- 写一个值的情况:
- 总结一下规则:
- 对面相等,后者省略
- 四面相等,只写一个
- 其实类似
padding这样,要对四个方向设值的属性,一般都可以像padding的规则进行设置。 padding的颜色和content的颜色一致,都是background-color
margin 外边距宽度
margin:[<length>|<percentage>|auto]{1, 4}|inherit</span>
解释:
margin的书写方式基本上和padding是一样的,但是还是有一些区别的。margin默认为 0,但是可能浏览器的默认样式表会给某些标签设置初始margin值,比如 IE6、IE7 的 body 标签,默认的样式应该是:display:block;margin:15px 10px;zoom:1;(不是很确定),而没有预设 padding 值,chrome/firefox 也只是设置了margin:8px;没有预设 padding- 上下毗邻的两个元素的
margin-top和margin-bottom会合并,取两者之间的较大值,看下面这个例子,两个元素间距仅为 30px,而不是 30px+10px:1
2<div style="height:30px;width:100px;margin:30px 10px;background-color:lightseagreen;"></div>
<div style="height:30px;width:100px;margin:10px 10px;background-color:lightseagreen;"></div>
- 父元素的上下
margin分别会和第一个子元素的margin-top以及最后一个子元素的margin-bottom进行合并。1
2
3
4<div style="width: 100px; margin: 40px auto; background-color: lightblue;">
<div style="height:30px;width:100px;margin:30px 0;background-color:lightseagreen;"></div>
<div style="height:30px;width:100px;margin:10px 0;background-color:lightseagreen;"></div>
</div>
但值得注意的是,上面这种情况的触发条件是比较苛刻的。只有在父元素没有设置border的时候才会合并。因为子元素的所有内容(包括margin)是要完全包含在父元素的border里面的。假设,我在上面这种情况中,给父元素添加border,就会变成下面这种情况:
border 边框
border:[<border-width>||<border-style>||<border-color>]|inherit</span> > border-width:[<length>|thin|medium|thick]{1,4}|inherit</span> > border-style:[solid|dashed|dotted|…]{1,4}|inherit</span> > border-color:[<color>|transparent]{1,4}|inherit</span> > border-radius:[<length>|<percentage>]{1,4} [/[<length>|<percentage>]{1,4}]
解释:
- 上面的属性,都可以写成
border-direction-xxx的形式,如border-bottom-color。 border-style最常用的三种就是:solid(实线),dashed(虚线),dotted(点线)- 重点讲一下
border-radius:
- 事实上,每个角都是一个椭圆,而椭圆都会有两个属性,就是 x 轴长度和 y 轴长度,如图所示。 - 所以设置全部四个角,需要 8 个值来表示,前四个,分别表示 1,2,3,4 个角的 X 轴方向半径,而后四个,则需要在前面加上/以示区别。比如上图中的圆角矩形,可以写成border-radius: 10px 15px 5px 5px /10px 5px 5px 15px。 -border-radius也满足对面相同,后者省略;四面相等,只写一个的规则,也就是,如果 1 号角和 3 号角如果一样,则只要写 1 号角的就行了。 -border-radius还满足x,y 一致,后者省略的规则,也就是说如果 x 方向半径和 y 方向半径一致的话,y 方向就可以不写 - 对border-radius设置百分比的值时,是相对本元素的width和height而言的。也就是说,如果对一个正方形元素,设置border-radius:50%就可以变成圆形,如下:
outline 轮廓
outline:[<outline-width>||<outline-style>||<outline-color>]|inherit</span>
outline-width:[<length>|thin|medium|thick]|inherit</span> > outline-style:[solid|dashed|dotted|…]|inherit</span> > outline-color:<color>|inherit</span>
解释:
outline是在border外面的一圈,不占据空间的轮廓。基本上和border的属性一致。- 下面这个例子,你会发现两个
div块之间,outline会互相覆盖,这说明outline并不占据空间。
1 | div { |
overflow 溢出
overflow:visible|hidden|scroll|auto
解释:
overflow是用来设置如果子元素超过父元素的溢出规则。visible表示可见;hidden表示隐藏;scroll表示固定显示滚动条;auto表示根据内容多少来选择显示或不显示滚动条;- 效果对比:
overflow: visible; overflow: visible; overflow: visible; overflow: visible; overflow: visible; Jackie Anxis
overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; Jackie Anxis
overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; Jackie Anxis
- 也可以利用
overflow-x,overflow-y分别设置 X 和 Y 方向的溢出处理
box-sizing 选择宽度设置
box-sizing:content-box|border-box|inherit</span>
解释:
box-sizing是用来指定,width和height指定的究竟是content内容的宽度还是border包含的宽度。- 默认是
content-box,表示 CSS 样式中,width和height指定的是content内容的宽度,也就是说,width: 100px;padding:10px;这段代码,实际上border(不包含border)里面的内容应该宽为 120px - 设置为
border-box,表示 CSS 样式中,width和height指定的是border(包括border在内)包含内容的宽度。
-
1 | width: 100px; |
这段代码,实际上,content部分的宽度只有 60px,而要加上padding和border的宽度才达到 100px。
box-shadow 设置阴影
box-shadow:none|<shadow>[,<shadow>]* > <shadow>:inset?&&<length>{2,4}&&<color>
解释:
box-shadow用来设置一个元素的阴影,默认是none,可以是多个值,中间用,隔开,表示多层阴影。inset表示内阴影- 对于每一层阴影,
length可以有 2-4 个,分别表示水平偏移(正值表示向右)、垂直偏移(正值表示向下),模糊半径,阴影大小;如下图所示的一段 CSS:
1 | box-shadow: 10px 10px 5px 20px lightblue; |

黑色边框部分,是向下偏移 10px,向右偏移 10px 应该产生的阴影(也就是box-shadow: 10px 10px lightblue;的情况下应该有的大小),而红色边框比黑色边框总共宽 40px(2 个阴影大小的宽度),而 5px 的模糊半径,是包含在 20px 的阴影大小里面的。
关于盒模型中百分比的问题做一个统一说明
width&height
对子元素的
width和height设置百分比值,无论父元素的box-sizing如何,都是相对父元素content部分进行计算的。
1 | /*left div content-box*/ |
- 第一个父元素的
content-box的宽为200px;所以子元素的width/height应该是基于200px进行计算的。 - 第二个父元素的
content-box的宽为200px-10px*2=180px;所以子元素的width/height应该是基于180px进行计算的。
padding&margin&border
对子元素的
padding和margin设置百分比值,无论父元素的box-sizing如何,都是相对父元素content部分的width进行计算的。
哦,忘了说了。border是不允许设置百分比值的。可怜的border。
1 | /*padding-test*/ |

- 父元素的
content-box的宽为400px-50px*2=300px;所以子元素的padding/margin应该是基于300px进行计算的。 - 注意:无论上下还是左右的
padding或者margin,都是相对父元素的width而言的,和height无关。
border-radius
对元素的
border-radius设置百分比值,x 轴方向的值是相对于元素border-box的width计算的,y 轴方向的值是相对于元素border-box的height计算的
1 | div { |
以下是左上角部分截图: