扒一下W3C规范里的BFC和IFC

一、盒子模型

页面任何一个元素都可以看成是box,box分block-level,inline-level和匿名的。

匿名box:
    <div>
        Some text
        <p>More text</p>
    </div>
其中"Some text",浏览器会为其生成一个匿名box

二、BFC

什么是BFC?

BFC的全称是Block Formatting Context,直译过来是:块级格式化上下文。

在理解BFC时先理解三个概念:

1、Block-level elements
属于diplay: block;的元素,都是Block-level elements(块级元素);有可能会触发BFC。

2、block boxes
W3C规范原文的定义:"Block-level boxes that are also block containers are called block boxes."可以作为block containers的块级元素,称为block boxes

3、block container box
原文:"a block-level box is also a block container box"。

最后还有一句:"The three terms "block-level box," "block container box," and "block box" are sometimes abbreviated as "block" where unambiguous."

都简称为块级元素好了orz...为什么要纠结这个?主要是被规范的用词搞晕了,花了点时间才搞明白这三个词的意思。

BFC的布局规矩:


1、内部box在垂直方向,一个接一个的放置;
2、box的垂直方向由margin决定,属于同一个BFC的两个box间的margin会重叠
3、BFC区域不会与float box重叠(可用于排版);
4、BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
5、计算BFC的高度时,浮动元素也参与计算

哪些元素或属性会触发BFC?

1、根元素;
2、float属性不为none;
3、position为absolute或fixed;
4、display为inline-block, flex, 或者inline-flex;
5、overflow不为visible;

扒了下 W3C的文档,里面对BFC的解释是酱紫的:

"9.4.1 Block formatting contexts

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.

In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box's line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).

For information about page breaks in paged media, please consult the section on allowed page breaks."

三、IFC

同理,IFC是Inline formatting context。

规范 里,IFC的描述比BFC的描述多很多,原文比较长,一点点扒吧:

an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.

在一个IFC中,从父级元素的顶部开始,盒子一个接一个横向排列。此时,横向的margin、borders、padding在这些盒子中都是有效的。这些盒子有可能通过不同的方式垂直对齐:1、他们底部或者顶部可以对齐,2、或者可以他们内部的文字基线可以对齐。如果一个矩形区域,包含着一些排成一条线的盒子,称为line box。

The width of a line box is determined by a containing block and the presence of floats. The height of a line box is determined by the rules given in the section on line height calculations.

一个line box的宽度,由他的包含块(containg block)和floats的存在情况决定。linebox的高度,由你给出的代码决定。

A line box is always tall enough for all of the boxes it contains. However, it may be taller than the tallest box it contains (if, for example, boxes are aligned so that baselines line up). When the height of a box B is less than the height of the line box containing it, the vertical alignment of B within the line box is determined by the 'vertical-align' property. When several inline-level boxes cannot fit horizontally within a single line box, they are distributed among two or more vertically-stacked line boxes. Thus, a paragraph is a vertical stack of line boxes. Line boxes are stacked with no vertical separation (except as specified elsewhere) and they never overlap.

一般line box的高度对于子元素而言总是够用的,不过有可能比他包含的最高的元素还高(如果这样,内部包含的盒子会对齐,基线排成一排)。当盒子的高度小于父级盒子高度时,垂直方向的对齐由‘vertical-align’属性决定(疑问:原文的box B是啥??)。
当几个内联盒子在line box一行内放不下时,它们会分布在两个以上的垂直并列(vertically-stacked)的line box上。因此,一个段落都是一堆line box堆叠在一起。line box在垂直堆叠的时候,不会有分离(no vertical separation)而且绝不会重叠(其他特殊情况除外【啥特殊情况??】)

In general, the left edge of a line box touches the left edge of its containing block and the right edge touches the right edge of its containing block. However, floating boxes may come between the containing block edge and the line box edge. Thus, although line boxes in the same inline formatting context generally have the same width (that of the containing block), they may vary in width if available horizontal space is reduced due to floats. Line boxes in the same inline formatting context generally vary in height (e.g., one line might contain a tall image while the others contain only text).

一般来说,line box和内部元素,都是左挨左,右挨右。不过浮动盒子可能会在包含块和line box的边缘之间。因此,即使line box在同一个IFC里通常有相同的宽度。如果他们横向间距会因float减少,它们宽度可能会不一样。line box在同一个IFC高度可能不一样(e.x.:含有不同高度的image)

When the total width of the inline-level boxes on a line is less than the width of the line box containing them, their horizontal distribution within the line box is determined by the 'text-align' property. If that property has the value 'justify', the user agent may stretch spaces and words in inline boxes (but not inline-table and inline-block boxes) as well.

当内联盒子的总宽度比line box小的时候,它们的水平分布由'text-align'属性决定。如果该属性值为'justify',用户可以拓宽在inline box的空间和文字。

When an inline box exceeds the width of a line box, it is split into several boxes and these boxes are distributed across several line boxes. If an inline box cannot be split (e.g., if the inline box contains a single character, or language specific word breaking rules disallow a break within the inline box, or if the inline box is affected by a white-space value of nowrap or pre), then the inline box overflows the line box.

如果内联盒子的宽度超过了line box,内联盒子会被分解成几个盒子,然后分布在几个line box里面。如果内联盒子不能被分解(e.g.,如果内联盒子有单个单词、或者有特殊的换行规则,或者被'white-space'的'nowrap'、'pre'影响),它会超过line box。

When an inline box is split, margins, borders, and padding have no visual effect where the split occurs (or at any split, when there are several).

如果一个内联盒子被分解了,margins、borders、和padding在他们被分解的位置没有视觉效果。

Inline boxes may also be split into several boxes within the same line box due to bidirectional text processing.

由于双向文本处理(bidirectional text processing)内联盒子有可能在同一个line box里被分解成不同的盒子。

Line boxes are created as needed to hold inline-level content within an inline formatting context. Line boxes that contain no text, no preserved white space, no inline elements with non-zero margins, padding, or borders, and no other in-flow content (such as images, inline blocks or inline tables), and do not end with a preserved newline must be treated as zero-height line boxes for the purposes of determining the positions of any elements inside of them, and must be treated as not existing for any other purpose.

line box主要被用来在IFC内装载内联级内容。不包含文本、不预留空白、没有非零margins,padding,border 或者其他flow内容(images、 inline block 或者 inline tables)的内联元素的line box必须被当成零高度的line box,主要为了定位其他在其里面的元素,还有必须被当成不存在的或者其他目的(这是什么鬼???看不懂)。

参考资料:

W3C规范:http://www.w3.org/TR/CSS2/visuren.html
MDN的介绍:https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Visual_formatting_model
知乎一个很棒的答案:https://www.zhihu.com/question/20086234

Lapsec
hi~~我叫陈旭元
756 声望
25 粉丝
0 条评论
推荐阅读
通过时间扭曲实现缓动动画
经常会见到各类缓动函数,在CSS里面有现成的bounce、elastic等缓动效果直接用。如果在canvas动画中,我们要实现这些缓动函数。直接去思考怎么处理挺头疼的,介绍一种不错的实现方式,源自《HTML5 Canvas核心技术》。

lapsec1阅读 3.1k

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy45阅读 5.8k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木63阅读 6k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs39阅读 6.2k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木41阅读 7.2k评论 6

CSS 绘制一只思否猫
欢迎关注我的公众号:前端侦探练习 CSS 有一个比较有趣的方式,就是发挥想象,绘制各式各样的图案,比如来绘制一只思否猫?思否猫,SegmentFault 思否的吉祥物,是一只独一无二、特立独行、热爱自由的(&gt;^ω^&lt...

XboxYan42阅读 2.8k评论 14

封面图
还在用 JS 做节流吗?CSS 也可以防止按钮重复点击
举个例子:一个保存按钮,为了避免重复提交或者服务器考虑,往往需要对点击行为做一定的限制,比如只允许每300ms提交一次,这时候我想大部分同学都会到网上直接拷贝一段throttle函数,或者直接引用lodash工具库

XboxYan34阅读 2.3k评论 2

封面图
756 声望
25 粉丝
宣传栏