BFC

Formatting Context与BFC

Formatting Context

大家一直在聊IFC(line formatting context)、BFC(block formatting context),但对于formatting text提之甚少,到底什么是formatting text?

Formatting contexts are the areas in which content is layed out. Each context holds the elements within it, and defines the rules for how those tags lay out within that context.
The most visible formatting context is the entire page. An HTML page defines how block elements flow, one after the other. Each statically positioned block element on the page is above the next statically positioned block element on the page.

Formatting Context :页面由元素组成,元素的渲染都遵循一定的规则。一旦某元素应用了Formatting Context ,含有元素的区域就会抛弃原来的渲染规则,然后遵循它自己的新的渲染规则。这个渲染规则决定了子元素如何定位,及元素之间如何相互作用。可见的最大formatting context就是整个页面。

box(盒模型)  :在一个文档中,每个元素都被表示为一个矩形的盒子。确定尺寸, 属性 --- 像它的颜色,背景,边框方面 --- 和这些盒子的位置是渲染引擎的目标。在CSS中,使用标准盒模型描述这些矩形盒子中的每一个。这个模型描述了元素所占空间的内容。每个盒子有四个边:外边距边边框边内填充边 与 内容边。 

所以说,一个Box的渲染规则(在页面上的具体展示)包含两个方面:这个盒子所占空间的内容与盒子在整个document中如何定位、及盒子之间如何相互作用。(注意:CSS作用的是盒子(Box), 而不是元素(Element)

Formatting Context分类

不同的 Formatting Context 有不同的渲染规则,常见的有 BFC (Block Formatting Contextext)IFC (Inline Formatting Context),和 CSS 3 新增加的 GFC (Grid Formatting Context)FFC (Flex Formatting Context)

IFC

行内格式化上下文涉及到两种盒子(boxes):行框(line box)以及行内框(inline box)。每一个行内元素都会生成inline boxinline box水平排列,浏览器的一整行生成一个行框(line box),所以一个行框(line box)可能包含多个行内框(inline box)

 行内非替换元素的content box无法通过设置height与width来设置。content box的高度仅能通过属性font-size来设置;content box的宽度则自适应其内容而无法通过属性width设置,而是等于其子行级盒子的外宽度(margin+border+padding+content width)之和。

IFC渲染规则 

水平方向上:各inline-level box从包含块的顶部在自左到右水平排列,line box的左边缘挨着它的包含块的左边缘,右边缘挨着它的包含块的右边缘。然而,浮动盒子也许会在包含块边缘和line box边缘之间。因此,尽管line boxs在同样的行内格式上下文中通常都有相同的宽度(就是他的包含块的宽度),但是水平方向上的空间因为浮动被减少了,它的宽度也会变得复杂。

竖直方向上:各inline-level box根据vertical-align属性值相对各自的父容器作垂直方向对齐;

 BFC 

BFC渲染规则 

 BFC:Block formatting context,官网上的定义是这样的:

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).

在BFC中,在竖直方向上,子元素代表的盒子自包含块顶部依次排列。两个盒子之间的垂直的间隙是由他们的 margin 值所决定的,两个相邻的块级盒子的垂直外边距会发生融合(叠加);在水平方向上,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘),即使存在浮动也是如此,除非这个盒子创建一个新的块级格式化上下文。

应用了BFC的盒子就是一个独立的盒子,它规定了内部的 block-level box 如何布局,并且这个独立盒子里的布局不受外部影响,也不会影响到外面的元素。

如何触发BFC?

  1. 浮动元素,float 除 none 以外的值
  2. 绝对定位元素,position(absolute,fixed)
  3. 非块级盒子的块级容器,例如:inline-blocks, table-cells, and table-captions。
  4. overflow 值不为 visible 的块级盒子。

ps

块级盒子:每个块级元素(display属性值为block,table,list-item)生成一个主要的块级盒Principal Block-level Box 来包含其后代盒和生成的内容,同时参与定位体系 Positioning Scheme 。某些块级元素还会在主要盒之外产生额外的盒: list-item 元素。这些额外的盒会相对于主要盒来摆放。

具体参考链接:https://segmentfault.com/a/1190000003096320https://developer.mozilla.org/en-US/docs/Web/CSS/Visual_formatting_model包含块

BFC中特殊的表现

BFC 并不是元素,而是满足上述条件的元素触发的渲染机制,与position:absolute、position:relative元素在BFC中不占有位置不同,float元素在BFC中其实是实际占有空间的。

1、对于BFC中的块级元素(特指display: block)而言,即float元素会感知到其前面块级元素,但块级元素感知不到float元素的存在,即float元素不影响块级元素的布局。

2、对于BFC中的inline或者inline-block元素而言,float元素是感知不到到inline与inline-block元素存在的,但行内元素能感知到float元素的存在,即float元素会影响到后面行内元素的布局。

3、当float元素高度为0时,其水平方向上的margin,padding属性会失去作用。对于这点我是这样理解的:

       设置float浮动的元素自动获取display: block样式。对于display:block元素,当其高度为0时,其水平方向上的margin,padding属性也不会起作用。需要注意的是块级正常流元素的高度为auto,而且只有块级子元素,其默认高度为从最高块级子元素的外边框边界到最低块级子元素外边界之间的距离(参考《CSS权威指南》P180)。

 1、内联元素元素与float元素

    <div style=‘border: solid 1px black;height: 150px;’>
      <div style=‘display: inline-block;;border: solid 1px green; height: 20px;’>
        表示我在float的前面
      </div>
      <div style=‘float: left;border: solid 1px green; height: 20px;’>
        我是float元素
      </div>
      <div style=‘display: inline-block;: solid 1px green; height: 20px;’>
        表示我在float的后面
      </div>
    </div>

可以看到两个inline-block元素不会影响float元素,但float元素会影响inline-block元素。

 2、block元素与float元素

 

    <div style=‘border: solid 1px black;height: 150px;’>
      <div style=‘border: solid 1px green; height: 20px;’>
        表示我在float的前面
      </div>
      <div style=‘float: left;border: solid 1px green; height: 20px;’>
        我是float元素
      </div>
      <div style=‘border: solid 1px green; height: 20px;’>
        表示我在float的后面
      </div>
    </div>

可以看到两个block元素不会受float元素的影响,但是float元素会受block元素的影响。

3、float元素高度为0

    <div style=“border: solid 1px red”>
      <p style=“margin-right: 100px;padding-right: 100px;float:left”>I am P element</p>
      <span style="background: pink">I am span flowing the p element</span>
    </div>

虽然为float元素设置了margin-right: 100px;padding-right: 100px; 但是float元素还是被无情地忽略了,他在父元素中没有实际占有位置。

 BFC应用

解决margin重叠问题

例如,两个p 元素之间的 margin 为 50px,此时发生了外边距叠加。要解决这个叠加问题,即让每个 p 元素之间的 margin 是 100px,应该怎么办?我们可以给 每个p 元素添加一个父元素,让并它触发 BFC。

清除 float 浮动,解决高度坍塌

实现特殊布局,如两栏布局与三栏布局

参考文档:

https://www.w3.org/TR/CSS21/visuren.html#inline-formatting

https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model

http://www.cnblogs.com/winter-cn/archive/2013/05/11/3072929.html#3634307

https://blog.duan-ya.com/article/2017-01-22/132

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值