在 CSS:关于元素高度与宽度的讨论 系列文章(一) 中讨论了display为display:block的非置换元素的宽度与高度在不同情况下的表现,但是有些地方并不严谨,因此在这里做一个补充,在补充前先简单介绍一下css盒模型以及其在可视化格式模型布局中盒子被管理的几个要点。在 CSS:关于元素高度与宽度的讨论 系列文章(二) 中介绍了块级元素、块元素、行内级元素、行内元素、置换元素、非置换元素,同样的在这篇文章中将介绍两种盒概念, containing box (包含块)以及 block container box (块容器盒)
The CSS box model describes the rectangular boxes that are generated for elements in the document tree and laid out according to the visual formatting model.
css盒模型描述了在文档树里生成并且根据可视化格式模型进行渲染布局的矩形框们。
In the visual formatting model, each element in the document tree generates zero or moreboxes according to the box model. The layout of these boxes is governed by:
box dimensions and type.
positioning scheme (normal flow, float, and absolute positioning).
relationships between elements in the document tree.
external information (e.g., viewport size, intrinsic dimensions of images, etc.).
在可视化格式模型中,每个元素在文档树里根据盒模型生成0或多个盒子。这些盒的 布局
被以下要素所管理
盒子的尺寸和类型
定位方案(普通流,浮动,绝对定位)
文档树中元素之间的关系
外部信息(例如,视口大小,图像的内在尺寸等)
因此下面我们要谈的便是关于盒子的尺寸问题。
In CSS 2.1, many box positions and sizes are calculated with respect to the edges of >a rectangular box called a containing block.In general, generated boxes act as >containing blocks for descendant boxes; we say that a box "establishes" the >containing block for its descendants. The phrase "a box's containing block" means >"the containing >block in which the box lives," not the one it generates.
Each box is given a position with respect to its containing block, but it is not >confined by this containing block; it may overflow.
在CSS2.1中,一个包含块的位置和尺寸相对于矩形框的边缘记进行计算。通常,生成的框为它的后代盒子充当包含块;我们认为,一个盒子(框)为他的后代建立了包含块。当我们在说“一个框(盒)的包含块”的意思是“该框所处的包含块”,而不是说它自身产生的包含块。
每个盒子相对于它的包含块进行定位,但并不限于它的包含块内;它有可能会溢出。
元素的包含块定义如下
The containing block in which the root element lives is a rectangle called the initial containing block. For continuous media, it has the dimensions of the viewport and is anchored at the canvas origin; it is the page area for paged media. The 'direction' property of the initial containing block is the same as for the root element.
根
元素所在的包含块为一个称为初始包含块的矩形框(根元素存在于initial containing block内),在我们常用的浏览器环境下,指的是原点与 canvas 重合,大小和 viewport 相同的矩形。
For other elements, if the element's position is 'relative' or 'static', the containing block is formed by the content edge of the nearest block container ancestor box.
对于其他元素,如果元素的 position
属性值为 relative
或者 static
(元素在文档流中),其包含块为祖先元素中最近的 block container box(块容器盒) 的 content box (除 margin, border, padding 外的区域);
If the element has 'position: fixed', the containing block is established by the viewport in the case of continuous media or the page area in the case of paged media.
如果元素的 position
值为 fixed
,包含块由视口 viewport 建立
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
1.In the case that the ancestor is an inline element, the containing block is the bounding box around the padding boxes of the first and the last inline boxes generated for that element. In CSS 2.1, if the inline element is split across multiple lines, the containing block is undefined.
2.Otherwise, the containing block is formed by the padding edge of the ancestor
If there is no such ancestor, the containing block is the initial containing block.
如果元素的 position
值为 absolute
,则它的包含块由最近的 position
的值为
absolute
, relative
, fixed
的祖先元素(offset parent)所建立,如下列方式
1.如果祖先是行内元素,则containing block为能够包含祖先元素生成的第一个和最后一个 inline boxs 的 padding boxs (除 margin, border 外的区域) 的最小矩形;
2.否则,则由这个祖先元素的 padding boxs 形成
如果没有这样的祖先元素,则包含块为初始包含块
Except for table boxes, which are described in a later chapter, and replaced elements, a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes.
除了table boxs以及置换元素,一个块级盒子也是一个块容器盒(block container box)。一个块容器盒要么只包含块级盒子,要么在盒内建立IFC只包含行内级盒子。也并不是所有的块容器盒都是块级盒子:非置换行内块(span)和非置换单元格(th,td)同样也是块容器,但它们并不是块级盒子。块级盒子是被叫做块盒的块容器
根据上面对containing box的介绍,我们可以把包含块当成一个大箱子,箱子里要摆很多小盒子,小盒子怎么摆取决于大箱子。不同的小盒子在它的大箱子里的初始位置是不一样的,下面举个简单的栗子来说明一下
<div id="wrap"> <div id="inner"></div> </div>
CSS
#wrap { width: 100px; height: 100px; padding: 10px; border: 2px dashed #333; background: orange; } #inner { width: 30px; height: 30px; background: #ccc;
原图
理解一 :通过此图可以知道inner盒子在position为默认的是static时,它的 包含块 为最近的祖先元素的 content-box ,所以他的起始位置位于从wrap的 content-box 的左上角
理解二 :当把inner的position值设为absolute,并设top:0,left:0时,同时把wrap的值设为relative时,inner的包含块为他的off-set parent的 padding-box ,因此inner定位的原点为wrap的 padding-box 的左上角。
思考:通过上述例子我们可以更直观的感受到,对于不同的元素它的 containing-box 是不一样的,同样的对于高度与宽度的继承时的计算,因为containing-box的不一样,计算时也会出现差异的,在我的上两篇文章中,都笼统的说成是xxx的宽或高度等于xxx的父或子的内容的宽度,因此这样的说法是不严谨的,有两点 1.
因为举得例子中的祖先元素只包含content-box,而不一样的元素的 containing-box 是不一样的,有的是其某祖先元素的padding-box有的是其祖先元素的content-box因此 2
.且我认为对于一个元素高度与宽度的继承应该是说继承这个元素所处的 containing-box 的值的一些计算,而不是单纯的认为是其父元素,因为它的父元素的有可能并不是它的包含块或者说它所处的包含块只是他父元素的一部分,所以下面将对于之前写的文章作出一些补充。
注:第一篇文章的内容大体来说是正确的,因此可以先理解完第一篇文章,再来看这篇文章会更好,这边文章的目的也算是对于前两章不足的内容的补充,如有错误,欢迎指正,( ^__^ ) 。
下面所举得例子,html的结构就如上例子,下面就不写出html结构了。元素在文档流中指的就是position的值为static或者relative
#wrap { width: 100px; height: 40px; padding: 10px; border: 2px dashed #333; margin: 10px; background: orange; } #inner { width: 100%; height: 100%; background: #ccc; }
加上float等于left或者right时,效果与上图相同
结论1:当元素在文档流中或者为浮动元素时,元素的宽高度为其 祖先元素中 最近的 block container box(块容器盒)的 content box ,也就是继承它的包含块的宽高度 。
在上述css中的inner上加上position:absolute,在wrap上加上position:relative,效果如下
因为inner并未设置它的定位值,故其位置显示如图,若设定位值也是相对于off-set parent的padding-box进行定位,可看上面的理解一二。
结论2:当元素的position的值为absolute时,元素的宽高度为其其 祖先元素中 最近的offset parent的 padding box ,也就是继承它的包含块的宽高度 。
在上述css中的inner上加上position:fixed;
因为inner并未设置它的定位值,故其位置显示如图。
结论3:当元素的position的值为fixed时,元素的宽高度为其包含块viewport的宽高度。
#wrap { width: 100px; height: 40px; padding: 10px; border: 2px dashed #333; margin: 10px; background: orange; } #inner { height: 10px; background: #ccc; }
结论1 :当元素在文档流时,元素的宽度为其祖先元素中最近的 block container box(块容器盒)的 content box ,也就是继承它的包含块的宽度 。
结论2:如文章一中的结论一样,元素宽度等于其内容所占空间,同样的在文章一中,也得出了元素不设高度,元素的高度为其内容所占据空间,若没有内容,则高度为0。
思考:那么由此我们可以引发我们的又一思考,在元素不设高度或者宽度的情况下,当元素的子代的position scheme不同的情况下,元素的宽度又是如何变化的?
接下来我就不举栗子了,直接给出结论
元素不设宽度且元素不在文档流中,元素宽度为 内容
宽度
元素不设高度,元素高度等于 内容
高度
当子元素都为普通流中元素时,元素宽度为子元素中宽度最大的元素,高度为子元素 高度之和
(子元素单个计算:子元素高度 + 子元素padding + 子元素border + 子元素margin)
当子元素都为浮动元素时,元素宽度为子元素宽度之和,高度为子元素中高度最大的元素
当子元素都为绝对定位或者固定定位元素时,元素宽度和高度都为 0
元素不设宽度且元素在文档流中,元素宽度为其祖先元素中最近的 block container box(块容器盒) 的 content box
元素不设高度,元素高度等于 内容
高度
当子元素都为普通流中元素,高度为子元素 高度之和
(子元素单个计算:子元素高度+子元素padding+子元素border)(边距折叠)
当子元素不在文档流中,元素高度为 0
1.当元素继承其祖先元素的宽高度时,元素的宽高度为其 containing-box 的高宽度
2.当元素的宽度或者高度等于其内容的宽度或者高度时,如上得出的结论