容易忽略的CSS盒子模型细节

今天在网上逛的时候发现了一篇介绍大多数人容易忽略的CSS盒子模型细节,整理了一下它的内容并验证了。CSS是前端必须掌握的技能之一。其中的box盒模型,大体就是bordermarginpaddingcontent,概念挺好理解,但当盒子模型与其他属性一起使用时的具体细节我们可能有点模糊。

因为涉及到bordermarginpadding,那我们就简单粗暴的方式KO掉讨厌的默认样式,像下面这样:

1
2
3
4
5
*{
margin: 0;
padding: 0;
border: none;
}

下面问题来了(不是挖掘机的问题)

问题一:嵌套块级元素时,子元素margin的参考标准是?具体来说就是父元素的content-boxpadding-boxborder-box还是margin-box

1
2
3
<div id="parent">
<div id="son"></div>
</div>

对应的样式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#parent{
width: 200px;
height: 200px;
background-color: pink;
margin: 50px;
padding: 50px;
border: 50px solid skyblue;
}

#son{
width: 100px;
height: 100px;
background-color: red;
margin: 50px;
}

效果如下:
子元素的margin效果图
显而易见,子元素的margin是参考父元素的content-box。父元素的粉红色部分包括了padding,这也说明了背景颜色会覆盖到padding,在IE6、7下因为其独特的渲染模式会出现问题,用hack写法纠正后结果仍然是一样的。

问题二:overflow:hidden隐藏的是超出哪里的部分呢?具体来说就是超出content-boxpadding-box还是margin-box会被隐藏?

HTML不变,对应的样式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#parent{
width: 100px;
height: 100px;
background-color: pink;
margin: 50px;
padding: 50px;
border: 50px solid skyblue;
overflow: hidden;
}

#son{
width: 300px;
height: 300px;
background-color: red;
}

效果如下:
父元素的overflow:hidden效果图
显而易见,overflow:hidden是隐藏超出其padding-box的部分(图中粉色的部分表示padding-box)

问题三:position:absolute定位参考点是什么?

绝对定位的情况要复杂一些,首先position:absolute定位的元素是参考有定位的最近的父元素来的,首先定位元素自身的参考是最外层的盒子模型,也就是说从margin-boxborder-boxpadding-box再到content-box,依照这个顺序(从外到内)查找,一旦找到就依该盒子模型定位。这个自己可以写个Demo玩耍去。

HTML不变,CSS如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#parent{
width: 200px;
height: 200px;
background-color: pink;
margin: 50px;
padding: 50px;
border: 50px solid skyblue;
position: relative;
}

#son{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}

效果如下:
`position:absolute`定位元素效果图
当定位元素的lefttopbottomright值都为默认值时,定位元素的左上角与父级元素(已有定位)的content-box盒子模型左上角重合。

再看另一种情况,当给定位元素的lefttopbottomright设定值的时候,看看下面的样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#parent{
width: 200px;
height: 200px;
background-color: pink;
margin: 50px;
padding: 50px;
border: 50px solid skyblue;
position: relative;
}

#son{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top: 0;
left: 0;
}

效果如下:
`position:absolute`定位元素效果图
由图可知,一旦给定位元素的lefttopbottomright设定了值,则其在那个方向的位置参考的是父级元素(已有定位)的padding-box盒子模型对应的边,剩余默认值的方向参考父级元素(已有定位)的content-box盒子模型对应的边,比如说定位元素只设置left: 50px;,则它左边距离父级元素(已有定位)的padding-box盒子模型的左边为50px,因为它的top值没有设置,所以在竖直方向上距离父级元素(已有定位)的content-box盒子模型的距离为0,注意是content-box

简单总结一下问题三:position:absolute定位参考点是什么?的重点

  1. 绝对定位的元素是参考有定位的最近的父元素来的
  2. 绝对定位的元素自身的参考点是最外围的盒子
  3. lefttopbottomright设置值后,则在设置值的方向依照父元素的padding-box的对应方向定位
  4. lefttopbottomright为默认值时,则元素在默认值方向上依照父元素的content-box的对应方向定位

问题四:元素的背景覆盖到哪个区域,border-boxpadding-box?还是margin-box

首先可以肯定的是,content-box区域是肯定会覆盖到的。呵呵

在第一个问题中我们可以知道,背景颜色至少会覆盖到padding-box区域,margin-box区域是肯定不会覆盖到的,介于中间的border-box区域会吗?看下面的CSS:

1
2
3
4
5
6
7
8
#parent{
width: 200px;
height: 200px;
background-color: pink;
margin: 50px;
padding: 50px;
border: 50px dotted skyblue;
}

效果如下:
背景颜色覆盖区域效果图
背景颜色会覆盖到border-box区域

背景还有另一种情况,当背景为图片的时候又是哪一种情况呢?CSS如下:

1
2
3
4
5
6
7
8
#parent{
width: 200px;
height: 200px;
background-image: url(demo.jpg);
margin: 50px;
padding: 50px;
border: 50px dotted skyblue;
}

效果如下:
背景图片覆盖区域效果图
可以看到默认情况下,图片从padding-box区域的左上角开始覆盖,右侧和下侧会覆盖到border-box区域!但不会覆盖到margin-box区域,但是图片多余的部分会重复,比如右边多的会在左边重复,下边多的会在上边重复,如果设置了

1
background-repeat: no-repeat;

就可以看到图片的确从padding-box区域的左上角开始覆盖,右侧和下侧会覆盖到border-box区域为止!见下图
背景图片覆盖区域效果图

所以背景颜色和图片都会覆盖到border-box区域,但不会覆盖到margin-box区域。

OK,是不是感觉自己更了解CSS盒子模型了呢?

Fork me on GitHub