视觉格式化模型
CSS的核心可以说有三个:层叠、盒模型、视觉格式化模型。
盒模型规定了单个盒子的规则,而视觉格式化模型规定了页面中多个盒子的排列规则,它大体上将页面中盒子的排列分为三种方式:
- 常规流
- 浮动
- 绝对定位
常规流布局
常规流有时也被称为文档流、普通文档流、常规文档流等,所有元素默认情况下都属于常规流布局。
总体规则:块盒独占一行,行盒水平依次排列。
包含块(containing block):每个盒子都有它的包含块,它决定了盒子的活动区域。
绝大部分情况下,盒子的包含块,为其父元素的内容盒。
如:
<div class="parent">
<div class="child">
child
</div>
</div>
.parent{
background: lightblue;
width: 300px;
height: 200px;
border: 2px solid;
padding: 30px;
}
.child{
border: 2px solid;
height: 100px;
background: blueviolet;
}
得到:
可以看到子<div>
元素的宽度是有限的,是它父元素的内容盒的宽度大小300px
。
如果这时修改父<div>
的margin使其移动,子<div>
也会跟着移动。
块盒的常规流
总宽度
每个块盒的总宽度(content + padding + border + margin),必须刚好等于包含块的宽度。
宽度width
的默认值是auto,表示将剩余空间吸收掉。margin
的取值也可以是auto,默认值是0。width
吸收能力强于margin
,所以当它们同时是auto时由width
吸收。
若content、padding、border、margin计算后,仍然有剩余空间,该剩余空间默认被margin-right
全部吸收,因为文字默认都是从左向右排列的,这就是我们常遇到的情况。
如果设置为margin-right: auto
和margin-left: auto
,则得到:
这是常规流中常见的一种居中方式:欲使块盒在其包含块中居中,可以定宽、然后左右margin取值auto。
开发中常用margin: 0 auto
,简写属性,也就是上下为0(也可以为其他大小),左右auto。
基于这个特性,我们可以做出一些有意思的效果,如设置margin
为负数:
每个块盒垂直方向上默认值
height: auto
,表示高度适应内容多少来调整margin: 0
,0就是0,没什么好说的
百分比取值
这块不仅是常规流的知识,之后的浮动、绝对定位都要用到。
pading
、width
、margin
可以取值为百分比。这个百分比是相对于包含块的宽度,比如就算你设置margin-top: 50%
,这个百分比也是父元素宽度的50%。高度
height
取值百分比,这个百分比是相对于包含块的高度包含块的高度。
但如果父元素并没有设置高度,这时即取默认值auto,表示父元素高度取决于子元素。但子元素又设置了height
取值为百分比,这时出现了“死锁”(借用一下操作系统的概念),百分比取值无效。
上下外边距的合并
两个常规流块盒,上下外边距相邻则会合并。
div{
width: 100px;
padding: 10px;
border: 3px solid;
margin: 50px;
}
如果上下两个外边距不相等,则取最大值。
两个上边距相邻也会合并,如:
<div class="parent">
<div class="child">
</div>
</div>
.parent{
background: blueviolet;
height: 300px;
width: 300px;
margin-top: 50px;
}
.child{
background: red;
width: 100px;
height: 100px;
margin-top: 50px;
}
本来我们预期child div元素应该距parent div元素上面50px,但由于这两个外边距相邻了,就合并了。
这时如果想实现我们预期的效果,不让它们合并,只要打破合并的条件就可以了,也就是不让它们相邻,比如可以给parent div元素加上border: 5px solid
,就得到:
也可以转换思维,把child div元素的margin-top
转换为parent div元素的padding-top
:
这个上下外边距合并规则和印刷学里面的排版有关系。