前言
尺寸盒子(呃,我也不知道准确定义是什么),顾名思义就是尺寸属性作用的对象。
从上图可以看出,尺寸盒子从内到外依次可以划分为content-box,padding-box,border-box,margin-box;其中margin-box在实际中没有啥用途。
而尺寸属性就是诸如width,height等直接规定元素尺寸的属性,以及定义width,height作用区域的box-sizing属性,除此之外还有像background-origin和background-clip影响元素背景填充区域和显示区域的属性。
box-sizing
box-sizing实际上决定了width和height作用的尺寸盒子,而其属性值有:
content-box(默认值):没错,指的就是width和height设置的值是针对于content-box这个盒子,即content区域;
border-box:同理,此时width和height设置的值是针对于border-box这个盒子,即border区域(=content + padding + border);
inherit:继承父级属性值;
css说的盒模型实际上就是指的box-sizing的属性值,而一般都说不同的盒模型的元素实际宽高有不同的计算方式,不过明白box-sizing的本质之后,就能理解元素的实际宽高只有一种计算方式:content + padding + border;
举个栗子:
1
2
1
2
3
4
5
6
7
8
9
10
11div{
width: 100px;
height: 100px;
padding: 20px;
border: 10px solid darkorchid;
background-color: lightcoral;
margin-bottom: 50px;
}
#box2{
box-sizing: border-box;
}
尽管两个div的尺寸样式设置完全一样,但是可以看出不同的box-sizing确实得到的实际尺寸完全不一样:
根本原因就是不同的box-sizing使得width和height属性作用的尺寸盒子不同,然而元素的实际尺寸计算方式是完全没有变滴……
background-origin
background-origin规定了指定背景图片(background-image属性,对普通的背景颜色区域不起作用,背景颜色区域一直是border-box) 的原点位置(background-position属性)相对区域。
注意:当使用 background-attachment 为fixed时,该属性将被忽略不起作用。——MDN
background-origin的属性值有:
content-box
padding-box(默认值)
border-box
inherit(继承父级元素属性值)
没错,这几个属性值分别对应上述的几个尺寸盒子所在区域;
background-clip
background-clip属性规定了背景(包括background-color和background-image)的实际显示区域;相当于通过background-origin、background-position和background-repeat等属性绘制出背景或背景图,然后通过background-clip来选取一个区域作为最终显示的区域。
background-clip的属性值有:
content-box
padding-box
border-box(默认值)
text(兼容性不好)
栗子
1
2
3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18div{
width: 452px;
height: 452px;
padding: 20px;
border: 10px solid rgba(70, 152, 199, 0.6);
background-image: url('lena.png');
margin-bottom: 20px;
background-repeat: no-repeat;
background-clip: padding-box;
}
#b2{
background-origin: content-box;
background-clip: content-box;
}
#b3{
background-origin: border-box;
background-clip: border-box;
}
注:background-image的绘制区域是从background-position到border-box的右下角?而非background-origin指定的区域的右下角?比如:当background-origin为content-box,而background-clip为border-box时:
可以很明显看出,background-image的绘制区域的右下角并非content-box;
关于margin-box
注:这部分仅是自己的理解,还需要进一步验证。
margin:auto 的作用机制
margin:auto是用来给元素自动计算分配『剩余可分配空间』的margin的,但是触发这个功能有一个前提条件:
触发 margin:auto 计算有一个前提条件,就是 width 或 height 为 auto 时,
元素是具有对应方向的自动填充特性的。——《css世界》
除了块级元素的流动性能够使元素在文档流的方向(文字排列方向)进行自动填充外,还有一种方法就是利用top等属性设置margin-box的边界,元素就会自动填充margin-box。
margin:auto 的填充规则如下。
(1)如果一侧定值,一侧 auto,则 auto 为剩余空间大小。
(2)如果两侧均是 auto,则平分剩余空间。
——《css世界》
top, bottom, left, right
当利用top, bottom, left, right这几个属性(当然前提是absolute或fixed布局)配合margin:auto;进行使用时,top, bottom, left, right的属性值相当于设定了该元素的margin-box的边界。此时,若width和height为auto时,就会自动填充整个margin-box;如果width和height设定了固定值,且固定值小于margin-box,那么『剩余可分配空间』就会被margin自动计算分配(上下左右四个边界)。
最常用的就是利用margin:auto和top, bottom, left, right来使元素水平垂直居中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#test{
position: relative;
height: 300px;
border: 1px dashed darkblue;
}
#box{
position: absolute;
top: 0;
bottom:0;
left: 0;
right: 0;
width: 300px;
height: 150px;
background-color: #39f;
margin: auto;
}
1
2
3
可以看出当top, bottom, left, right的值全为0时,相当于margin-box就是父级容器的大小,因此设置margin:auto时会自动计算剩余可分配空间(上下左右四个方向),由于四个方向都是auto,因此上下和左右各自平分竖直和水平方向的剩余可分配空间作为margin,因此也就形成了水平垂直居中。
不过在查看firefox(chrome也一样)的计算后规则时,貌似四个方向的margin值都为0,而left等值反而进行了计算:
参考文档
《css世界》—— 3.2 width/height作用的具体细节
《css世界》—— 4.3.4 深入理解 CSS 中的margin:auto