zoukankan      html  css  js  c++  java
  • 经常问到的 BFC 和 IFC 是什么?

    什么是BFC?什么作用?

    Block Formatting Context

    块盒子布局发生的区域,浮动元素和其他元素交互的区域

    浮动定位和清除浮动的时候只会应用于同一个BFC内的元素。浮动不会影响其他BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动

    外边距的折叠也只会发生在同一BFC中的块级元素之间。可以创建新的BFC来消除外边距的折叠问题。

    常见的定位布局方案有,普通流,浮动和绝对定位。

    BFC 是一块渲染区域,有一套渲染定位规则。决定子元素定位其他元素的关系和相互作用,是属于普通流的。具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。

    其实也不是什么新鲜东西,可能都在用但不知道这个概念。


    案例1:使浮动元素和周围内容等高

    对于以下代码:

    <style>
      .box {
        background-color: rgb(224, 206, 247);
        border: 5px solid rebeccapurple;
        /* overflow: auto; */
        /* display: flow-root; */
      }
      .float {
        float: left;
         400px;
        height: 150px;
        background-color: white;
        border: 1px solid black;
        padding: 10px;
      }
    </style>
    <div>
      <div class="box">
        <div class="float">I am a floated box!</div>
        <p>I am content inside the container.</p>
      </div>
    </div>
    

    显示的效果如下:

    因为浮动盒子脱离了文档流。浮动的div元素更大,就穿出了边框。

    一般是需要将盒子和浮动元素做成等高的,即浮动元素应该包含在box内部,要达到这个效果,可以这样:

    1. 使用display: flow-root

      一个新的display属性值,可以创建无副作用的BFC。在父级元素中使用display: flow-root就可以创建新的BFC。

      可以理解为和创建根元素一样,创建一个文档流的上下文

    2. 使用overflow:auto

      只要设置overflow为一个非visible的值就可以。使用overflow创建一个新的BFC,overflow会告诉浏览器如何处理超出部分的内容。

      但是如果只是用来创建BFC的话,可能引发其他情况。


    案例2: 清除外部浮动

    对于以下代码:

    <style>
      section {
        height: 150px;
      }
      .box {
        background-color: rgb(224, 206, 247);
        border: 5px solid rebeccapurple;
      }
      .box[style] {
        background-color: aliceblue;
        border: 5px solid steelblue;
      }
      .float {
        float: left;
        overflow: hidden; /* required by resize:both */
        resize: both;
        margin-right: 25px;
         200px;
        height: 100px;
        background-color: rgba(255, 255, 255, 0.75);
        border: 1px solid black;
        padding: 10px;
      }
    </style>
    
    
    <section>
      <div class="float">Try to resize this outer float</div>
      <div class="box"><p>Normal</p></div>
    </section>
    <section>
      <div class="float">Try to resize this outer float</div>
      <div class="box" style="display:flow-root"><p>	   	  	
        <code>display:flow-root</code><p>
      </div>
    </section>
    

    这里需要关注的是float元素上的margin-right这个属性。

    上面的两个元素之间,margin-right 没有生效。但是对box添加display:flow-root属性之后,margin-right 属性就生效了,左边的元素缩放的时候始终都保持有25px的距离。也就是display:flow-root对同级的外部元素的浮动也清除了

    如果对HTML部分写成这样:

    <section>
      <div class="float">Try to resize this outer float</div>
      <div class="float">Try to resize this outer float</div>
      <div class="box"><p>Normal</p></div>
    </section>
    <section>
      <div class="float">Try to resize this outer float</div>
      <div class="float">Try to resize this outer float</div>
      <div class="box" style="display: flow-root">
        <p><code>display:flow-root</code></p>
        <p>xx</p>
      </div>
    </section>
    

    消除同级元素的float, 显示出 margin-right 的效果就更明显了。

    需要注意的是:清除同一BFC中的浮动,只能清除在它前面元素的浮动。


    案例3: 外边距塌陷问题

    对于如下代码:

    <style>
      .blue,
      .red-inner {
        height: 50px;
        margin: 50px 0;
        background: blue;
      }
    
      .red-outer {
        /* display: flow-root; */
        /* overflow: hidden; */
        background: red;
      }
    </style>
    
    <body>
      <div class="blue"></div>
      <div class="red-outer">
        <div class="red-inner">red inner</div>
      </div>
    </body>
    

    显示的效果如下:

    可以看到,对red-inner的margin没法撑起盒子,两个蓝色盒子之间的距离是50px.

    使用display: flow-root;

    两个蓝色盒子就距离100px了,而且margin也完全显示了出来。


    创建BFC的方法

    使用这些BFC的特性,需要创建出BFC:

    • 根元素(<html>)
    • 浮动元素(元素的 float 不是 none
    • 绝对定位元素(元素的 positionabsolutefixed
    • 行内块元素(元素的 displayinline-block
    • 表格单元格(元素的 displaytable-cell,HTML表格单元格默认为该值)
    • 表格标题(元素的 displaytable-caption,HTML表格标题默认为该值)
    • 匿名表格单元格元素(元素的 displaytable、``table-rowtable-row-group、``table-header-group、``table-footer-group(分别是HTML table、row、tbody、thead、tfoot 的默认属性)或 inline-table
    • overflow 计算值(Computed)不为 visible 的块元素
    • display 值为 flow-root 的元素
    • contain 值为 layoutcontent 或 paint 的元素
    • 弹性元素(displayflexinline-flex 元素的直接子元素)
    • 网格元素(displaygridinline-grid 元素的直接子元素)
    • 多列容器(元素的 column-countcolumn-width (en-US) 不为 auto,包括 ``column-count1
    • column-spanall 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更Chrome bug

    什么又是 IFC?

    相对于块级格式化上下文,还有行内格式化上下文,Inline formatting context

    对于IFC,行内框一个接一个地排列,排列顺序和书写方向一致。

    • 水平书写模式,行内框从左边开始水平排列
    • 垂直书写模式,行内框从顶部开始水平排列

    一个行内框在被分割到多行中的时候,margin,border以及padding的设定不会在断裂处生效(边框跨行连续,不会产生两块border)

    Margin,border和padding的设置在行方向上生效。

    垂直方向上对齐

    垂直方向上的位置主要是用vertical-align

    <style>
      .horizontal {
        writing-mode: horizontal-tb;
       }
    
      .vertical {
        writing-mode: vertical-rl;
       }
    	span {
        font-size: 200%;
        /* vertical-align: top; */
        vertical-align: bottom;
       }
    </style>    
    
    <div class="example horizontal">
          Before that night—<span>a memorable night</span>, as it was to prove—hundreds of millions of
          people had watched the rising smoke-wreaths of their fires without drawing any special
          inspiration from the fact.”
    </div>
    

    显示效果:

    而如果将vertical-align: bottom设置为top,效果则是顶部对齐

    需要注意的是,如果文字方向是垂直书写模式的话,对齐方式不变,但实际上应该是左右对齐,与vertical-align的字面意思稍有出入。在vertical-align:top再加上writing-mode: vertical-rl

    水平方向上对齐

    行内元素在水平方向上的位置主要是用text-align

    <style>
       .horizontal {
        writing-mode: horizontal-tb;
       }
    
      .vertical {
        writing-mode: vertical-rl;
       }
    	.example {
        text-align: center;
      }
    </style>
    
    <div class="example horizontal" style="border: 1px solid">One Two Three</div>
    <div class="example vertical">One Two Three</div>
    

    显示效果:


    参考:

  • 相关阅读:
    pyqt pyside QLabel 显示图片
    圆周率pi π 与 角度的对应关系
    向量 dot cross product 点积叉积 几何意义
    Python 求点到直线的垂足
    Maya cmds pymel scriptJob() 和 undoInfo() 在回调中撤销(undo)
    Python 2 和 3 的区别记录
    Maya cmds filterExpand 列出 选择的 uvs vertices faces edges 等 component 类型
    maya shell 和 UV shell 的区别
    maya cmds pymel polyEvaluate 获取 bounding box
    挂载根目录注意事项
  • 原文地址:https://www.cnblogs.com/xuxiaowei/p/14639367.html
Copyright © 2011-2022 走看看