【CSS】Formatting Context——BFC&IFC


概念

Formatting Context

Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,有一套渲染规则决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

Formatting context的种类
  • Block fomatting context (BFC):块级格式化上下文
  • Inline formatting context (IFC):行内格式化上下文
  • Flex formatting context(FFC):CSS3中的flex布局
  • Grid formatting context(GFC):CSS3中的Grid布局

一、BFC: Block Formatting Context

BFC的概念

BFC(块级格式化上下文),是一个独立的渲染区域,让处于 BFC 内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。

BFC触发条件

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.

  • html根节点就是一个BFC
  • float属性不为none
  • positionabsolutefixed
  • 非块级元素具有 display: inline-block, table-cell, table-caption
  • 块级元素具有overflow且不为visible
BFC布局规则

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

一、内部的Box会在垂直方向,一个接一个地放置。
二、Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠(按照最大margin值设置)
三、BFC的区域不会与float box重叠。
四、每个盒子的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此,除非这个元素自己形成了一个新的BFC。
五、BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
六、计算BFC的高度时,浮动元素也参与计算

规则实现(个人理解):

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <p>一、内部的Box会在垂直方向,一个接一个地放置</p>
    <div style="overflow: hidden;">
        <div style="width: 80px; height: 80px; background: lightgreen;">div1</div>
        <div style="width: 160px; height: 160px; background: pink;">div2</div>
        <div style="width: 80px; height: 80px; background: lightgreen;">div3</div>
    </div>
    <hr>
    
    <p>二、Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠(按照最大margin值设置)</p>
    <div style="overflow: hidden;">
        <p>不触发BFC,margin重叠</p>
        <div style="overflow: hidden;">
            <div style="margin: 20px; width: 100px; height: 100px; background: lightgreen;">div1</div>
            <div style="margin: 20px; width: 100px; height: 100px; background: pink;">div2</div>
        </div>
        
        <p>触发BFC,margin不重叠</p>
        <div style="overflow: hidden;">
            <div style="margin: 20px; width: 100px; height: 100px; background: lightgreen;">div1</div>
            <div style="overflow: hidden;">
                <div style="margin: 20px; width: 100px; height: 100px; background: pink;">div2-BFC</div>
            </div>
        </div>
    </div>
    <hr>
    
    <p>三、BFC的区域不会与float box重叠</p>
    <div style="overflow: hidden;"></div>
    <div style="float: left; width: 80px; height: 80px; background: lightgreen;">div1-float-BFC</div>
    <div style="overflow: hidden; width: 160px; height: 160px; background: pink;">div2-BFC</div>
    </div>
    <hr>
    
    <p>四、每个盒子的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此</p>
    <div style="overflow: hidden;">
        <div style="float: left; width: 80px; height: 80px; background: lightgreen;">div1-float-BFC</div>
        <div style="width: 160px; height: 160px; background: pink;">div2</div>
    </div>
    <hr>

    <p>五、BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素</p>
    <div style="overflow: hidden;">
        <div>
            <p>不触发BFC,float元素影响外部</p>
            <div style="width:600px; background: yellow; border:5px solid red">
                <div style="float: left; width: 100px; height: 100px; background: lightgreen;">div1</div>
                <div style="float: left; width: 100px; height: 100px; background: pink;">div2</div>
            </div>
            <div style="width: 300px; height: 120px; background: lightblue;border:5px solid black">被影响的元素</div>
        </div>
        <hr>

        <div>
            <p>触发BFC,float元素不影响外部</p>
            <div style="width:600px; overflow: hidden; background: yellow; border:5px solid red">
                <div style="float: left; width: 100px; height: 100px; background: lightgreen;">div1</div>
                <div style="float: left; width: 100px; height: 100px; background: pink;">div2</div>
            </div>
            <div style="width: 300px; height: 120px; background: lightblue;border:5px solid black">不被影响的元素</div>
        </div>
    </div>
    <hr>

    <p>六、计算BFC的高度时,浮动元素也参与计算</p>
    <div style="overflow: hidden;">
        <div style="width: 160px; height: 160px; background: pink;">div2</div>
        <div style="float: left; width: 80px; height: 80px; background: lightgreen;">div1-float-BFC</div>
    </div>
    <hr>
</body>
</html>


在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

BFC应用
  1. 清除浮动
  2. 布局:自适应两栏布局
  3. 防止垂直margin合并

二、IFC: Inline Formatting Context

IFC的概念

内联格式设置上下文是网页视觉呈现的一部分。内联框在句子以使用的书写模式运行的方向上一个接一个地布置:

  • 在水平书写模式下,框从左侧开始水平放置。
  • 在垂直书写模式下,它们将从顶部开始垂直布置。
IFC布局规则

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

在行内格式化上下文中,boxes一个接一个地水平排列,起点是包含块的顶部。水平方向上的 marginborderpadding在框之间得到保留。boxes以不同的方式在垂直方向对齐:顶部或底部对齐,或根据text自身的baselines对齐。排成一行的boxes行承的长方形区域,叫做行盒。

行盒(line box)
  1. line box的宽度由包含块和float情况决定:
  • 一般来说,line box的宽度等于包含块两边之间的宽度,然而float可以插入到包含块和行盒边之间,如果有float,那么line box的宽度会比没有float时小;
    • 当一行的行内级盒的总宽度小于它们所在的line box的宽度时,它们在行盒里的水平分布由text-align属性决定。如果该属性值为justify,用户代理可能会拉伸行内盒(不包括inline-table和inline-block盒)里的空白和字(间距)。
  1. line box的高度由line-height决定, line box的高度能够容纳它包含的所有盒,当盒的高度小于行盒的高度(例如,如果盒是baseline对齐)时,盒的竖直对齐方式由vertical-align属性决定。
    <div style="width: 1000px; overflow: hidden; background:lightgoldenrodyellow;">
        <span style="float:left; font-size: 30px;border: 2px solid red;">
            Float占据包含块与行盒之间的空间
        </span>
        <em style="font-size: 20px; border: 2px solid violet;">
            great1
        </em>
        <span style="border: 2px solid lightgreen;">good</span>
    </div>
    <br>
    <div style="width: 1000px; background: lightgoldenrodyellow;">
        <em style="font-size: 5px; vertical-align: text-top; border: 2px solid green;">
            小于行盒的高度的字体,垂直对齐由vertical-align:text-top决定
        </em>
        <span style="font-size: 30px; border: 2px solid red;">
            font-size:30的字体 
        </span>
        <em style="font-size: 10px; vertical-align: middle; border: 2px solid green;">
            小于行盒的高度的字体,垂直对齐由vertical-align:middle决定
        </em>
    </div>
    <br>
    <div style=" width: 1000px; overflow: hidden; text-align: center; background: lightgoldenrodyellow;">
        <span style="float: left; font-size: 30px; border: 2px solid red">
            Float占据包含块与行盒之间的空间
        </span>
        <em style="font-size: 15px; border: 2px solid blue; vertical-align: bottom;">
            行内盒的宽度小于行盒宽度时,text-align决定行内盒的水平位置
        </em>
    </div>

在这里插入图片描述

行内盒(inline box)
  1. 当一个inline box超出一个line box的宽度时,它会被分成几个盒,并且这些盒会跨多line box分布;当一个inline box被分割后,margin,borderpadding在发生分割的地方(或者在任何分割处,如果有多处的话)不会有可视化效果。
  2. 如果一个inline-block无法分割(例如,如果该inline box含有一个单个字符,或者特定语言的单词分隔规则不允许在该inline box里分隔,或如果该inline box受到了一个值为nowrap或者pre的white-space的影响),那么该inline box会从line box溢出。
  3. 同一个line box里的inline box也可能因为双向(bidirectional)文本处理而被分割成几个盒
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <p>行内可分割</p>
    <div style="width: 600px; overflow: hidden; background:lightgoldenrodyellow;border: 1px solid black"">
        <span style="font-size: 20px;border: 2px solid red;">
            当一个inline box超出一个line box的宽度时,它会被分成几个盒,并且这些盒会跨多line box分布
        </span>  
        <br><br><hr><br>
        <span style="margin:20px;padding: 10px; font-size: 20px;border: 2px solid lightgreen;">
            当一个inline box被分割后,margin,border和padding在发生分割的地方(或者在任何分割处,如果有多处的话)不会有可视化效果
        </span>  
    </div>
    <br>
    <p>行内不可分割——溢出</p>
    <div style="width: 400px; overflow: hidden; background:lightgoldenrodyellow;">
                <span style="font-size: 15px; border: 2px solid lightgreen;">
            goodgoodgoodgoodgoodgoodgoodgoodBADBADBADBADBADBADBAgoodgoodgoodgoodgoodgoodgood
        </span>       
    </div>
</body>
</html>

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值