css的尺寸盒子及相关属性

前言

尺寸盒子(呃,我也不知道准确定义是什么),顾名思义就是尺寸属性作用的对象。

mark

从上图可以看出,尺寸盒子从内到外依次可以划分为content-boxpadding-boxborder-boxmargin-box;其中margin-box在实际中没有啥用途。

尺寸属性就是诸如widthheight直接规定元素尺寸的属性,以及定义widthheight作用区域box-sizing属性,除此之外还有像background-originbackground-clip影响元素背景填充区域和显示区域的属性。

box-sizing

box-sizing实际上决定了widthheight作用的尺寸盒子,而其属性值有:

  • content-box(默认值):没错,指的就是widthheight设置的值是针对于content-box这个盒子,即content区域;

  • border-box:同理,此时widthheight设置的值是针对于border-box这个盒子,即border区域(=content + padding + border);

  • inherit:继承父级属性值;

css说的盒模型实际上就是指的box-sizing的属性值,而一般都说不同的盒模型的元素实际宽高有不同的计算方式,不过明白box-sizing本质之后,就能理解元素的实际宽高只有一种计算方式content + padding + border

举个栗子:

1
2
<div id="box1"></div>
<div id="box2"></div>
1
2
3
4
5
6
7
8
9
10
11
div{
width: 100px;
height: 100px;
padding: 20px;
border: 10px solid darkorchid;
background-color: lightcoral;
margin-bottom: 50px;
}
#box2{
box-sizing: border-box;
}

mark

尽管两个div尺寸样式设置完全一样,但是可以看出不同的box-sizing确实得到的实际尺寸完全不一样:

mark

mark

mark

mark

根本原因就是不同的box-sizing使得widthheight属性作用的尺寸盒子不同,然而元素的实际尺寸计算方式是完全没有变滴……

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-colorbackground-image)的实际显示区域;相当于通过background-originbackground-positionbackground-repeat等属性绘制出背景或背景图,然后通过background-clip选取一个区域作为最终显示的区域

background-clip的属性值有:

  • content-box
  • padding-box
  • border-box(默认值)
  • text(兼容性不好)

栗子

1
2
3
<div id="b1"></div>
<div id="b2"></div>
<div id="b3"></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
div{
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;
}

mark

mark

mark

background-image的绘制区域是从background-positionborder-box的右下角?而非background-origin指定的区域的右下角?比如:当background-origincontent-box,而background-clipborder-box时:

mark

可以很明显看出,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这几个属性(当然前提是absolutefixed布局)配合margin:auto;进行使用时,top, bottom, left, right的属性值相当于设定了该元素的margin-box的边界。此时,若widthheightauto时,就会自动填充整个margin-box;如果widthheight设定了固定值,且固定值小于margin-box,那么『剩余可分配空间』就会被margin自动计算分配(上下左右四个边界)。

最常用的就是利用margin:autotop, 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
<section id="test">
<div id="box"></div>
</section>

mark

可以看出当top, bottom, left, right的值全为0时,相当于margin-box就是父级容器的大小,因此设置margin:auto时会自动计算剩余可分配空间(上下左右四个方向),由于四个方向都是auto,因此上下和左右各自平分竖直和水平方向的剩余可分配空间作为margin,因此也就形成了水平垂直居中。

不过在查看firefoxchrome也一样)的计算后规则时,貌似四个方向的margin值都为0,而left等值反而进行了计算:

mark

参考文档

  1. 《css世界》—— 3.2 width/height作用的具体细节
  2. background-clip - CSS:层叠样式表 | MDN
  3. background-origin - CSS:层叠样式表 | MDN
  4. 《css世界》—— 4.3.4 深入理解 CSS 中的margin:auto