文档树中的一个元素在网页中是如何通过CSS来确定它自己的布局呢?
我们可以把页面中的元素都可以看成是一个矩形的框,那么之前的问题显然与两种因素有关,框的位置和框的大小。那么这两种因素又是如何计算的呢?

几个名词概念

  • containing block
  • block-level element,block-level box,block container,block box
  • inline-level element
  • 匿名块级(行内)元素
  • Block Formatting Context(BFC),Inline Formatting Context(IFC),都是指containing box中的一种布局的方式

VFM可以理解为是一种文字排版的方式,通常一种box对应的一种排版的上下文,但是在block box中可能存在两种,BFC和IFC。

几个block**名词之间的关系

(这里谈论的元素,默认是在普通文档流中)

(1) 首先是block-level element,表象是,这些元素会独占一行,即使是不能占满,也要霸道的不把那一行让给别的元素。

这样的一些元素有,(1)display:block的(2)display:list-item的(li)(3)display:table的

这些block-level element会创建一个叫block-level box的东西,可以给它设置宽和高,已经垂直方向上的margin。

但是不是每一个block-level box都是block-level element,比如table box和replaced element。

(2) 接着是block container,是指只包括block-level box,或者建立了inline formatting context的一种容器,而IFC只能包含inline-level element.

也就是说block container,要么只能全包含block-level box,要么只能全包含inline-level box(block container中的行内元素会被匿名块级盒子包裹,从整体上来看还是一个呈现出block的)。

它可以有以下几种,(1)block-level box(2)non-replaced inline-block(3)non-replaced table cells.

(3) 再有如果一个box既是block container又是block-level box,那么这个box被称之为block box。

这部分有点绕,可以看一下下面的示意图

BFC是什么

从表现来看,是处于BFC中的box,从container top开始,由上至下,垂直方向的一个个’落’下来;这些box上下之间的间隙由各box的margin决定,会有margin叠加;并且这些box的margin box的左边挨着container的content box的左边缘;

什么时候情况下能构建出BFC?

float,绝对定位的元素;inline-block,table-cell,table-caption的block container;overflow != visible的block box

containing box

通常我们说一个元素的containing box,是要在它的祖先元素上查找这个box。并且这个元素的大小与它的containing box的内容框的大小有关,这个元素的位置与containing box是谁有关。

如何确定元素的位置

首先,我们应当清楚的以下3种定位的方案:

(1) 正常文档流中包括的position为relative的块级和行内元素,还有block-level box的block formatting和inline-level box的inline formatting

(2) 绝对定位

(3) float

知乎上看到的这个解释的比较好:

如何确定元素的大小

先了解下一耳熟能详的盒模型:

关于width,height,margin,padding,再来看下面的这个图,然后再讨论有auto时是如何计算的?

(1) 对于块级元素(非替换的行内元素直接设置width,height,垂直方向上的margin是不会生效的),从水平方向来说,需要满足下面的公式:

margin-left+border-left+padding-left+width+padding-right+border-right+margin-right=CBWidth(包含块的content box的宽度)

(tips:下面讨论的场景都是没有为元素设置padding和border的情况下)

一个auto时:

设置auto的这个属性的宽度=CBWidth-另外两个不是auto的值

二个auto时:

  • margin-left(margin-right)和width是auto,那么margin-left(margin-right)会被置为0,而width会尽可能的宽,直到满足上述公式。比如CBWidth=400px,margin-right=100px,那么此时margin-left=0,width=300px.
  • margin-left,margin-right是auto,那么它们俩的宽度将均分CBWidth-width之后的值。也就是假设,CBWidth=400px,width=100px,那么此时margin-left=150px,margin-right=150px.这也就是为什么设置margin-left:auto,margin-right:auto之后,元素会水平居中对齐。

三个auto时:

margin-left和margin-right都会被置为0,然后width会尽可能的宽,直到等于CBWidth

(2) 对于inline box来说,只有line-height,font-size,vertical这3个属性能对其高度影响

vertical只应用于行内元素,替换元素。vertical设置为%时,是相对于这个元素自身的line-height的。

我所理解的VFM里的关系

参考文章