• BFC和IFC


    Box: CSS布局的基本单位

      Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。让我们看看有哪些盒子:

    • BFC  快级格式化上下文 block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context;                         (块元素参与BFC)
    • IFC  内联格式化上下文   inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context;        (行内元素参与IFC)
    • run-in box: css3 中才有, 这儿先不讲了。

    Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。

    一、什么是BFC

    BFC  (Block formatting context直译为"块级格式化上下文")   它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。通俗地讲,BFC是一个容器,用于管理块级元素。

    二、如何创建BFC

    • float为 left|right
    • overflow为 hidden|auto|scroll
    • display为 table-cell|table-caption|inline-block|inline-flex|flex
    • position为 absolute|fixed
    • 根元素

    三、BFC布局规则:

    • 内部的Box会在垂直方向,一个接一个地放置(即块级元素独占一行)。
    • BFC的区域不会与float box重叠(利用这点可以实现自适应两栏布局)。
    • 内部的Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠(margin重叠三个条件:同属于一个BFC;相邻;块级元素)。
    • 计算BFC的高度时,浮动元素也参与计算。(清除浮动 haslayout)
    • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

    四、 BFC有哪些特性

    特性1:BFC会阻止垂直外边距折叠

    按照BFC的定义,只有同属于一个BFC时,两个元素才有可能发生垂直margin的重叠,这个包括相邻元素或者嵌套元素,只要他们之间没有阻挡(比如边框、非空内容、padding等)就会发生margin重叠。

    ①相邻兄弟元素margin重叠问题

    <style>
    p{
            color: #fff;
            background: #888;
             200px;
            line-height: 100px;
            text-align:center;
            margin: 100px;
      }
    </style>
    <body>
        <p>ABC</p>
        <p>abc</p>
    </body>
    

    相邻兄弟元素margin重叠问题

    上面两个p元素同在一个BFC容器(这里指body)下,且是相邻的块元素,发送margin重叠
    上面例中两个P元素之间距离本该为200px,然而实际上只有100px,发生了margin重叠。遇到这种情形,我们如何处理?
    只需要在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin重叠了。

    下面在第二个p元素外,再包裹一层容器。或者可以两个p元素外都包裹一层容器。

    <style>
    p{
            color: #fff;
            background: #888;
             200px;
            line-height: 100px;
            text-align:center;
            margin: 100px;
        }
    .wrap{
      overflow:hidden;
    }
    </style>
    <body>
       <p>ABC</p>
      <div class="wrap">
        <p>abc</p>
      </div>
    </body>
    

    bug修补后

    ②父子元素margin重叠问题

    <style>
    .box{
    100px;
    height:100px;
    background:#ccc;
    }
    .wrap {
      background:yellow;
    }
    .wrap h1{
      background:pink;
      margin:40px;
    }
    </style>
    <body>
    <div class="box">box</div>
    <div class="wrap">
      <h1>h1</h1>
    </div>
    </body>
    

    父子元素margin重叠问题
    上图wrap元素与h1元素之间l理论上本该有个40px的上下margin值,然而实际上父子元素并没有存在margin值,与此同时,两个div元素的间距为40px。遇到这种情形,我们如何处理?
    处理方法其实有很多,**在wrap元素中添加:overflow:hidden;或者overflow:auto;使其父元素形成一个BFC;也可以在wrap元素中添加border:1px solid;或是padding:1px;**这些都可以有效解决父子元素margin重叠问题。

    bug修补后

     

    特性2:BFC不会重叠浮动元素

    利用这个特性,我们可以创造自适应两栏布局。

    <style>
    .box1{
      height: 100px;
       100px;
      float: left;
      background: lightblue;
    }
    .box2{ 200px;
      height: 200px;
      background: #eee;
    }
    </style>
    <body>
    <div class="box1">我是一个左浮动的元素</div>
    <div class="box2">喂喂喂!大家不要生气嘛,生气会犯嗔戒的。悟空你也太调皮了,
    我跟你说过叫你不要乱扔东西,你怎么又……你看,我还没说完你就把棍子给扔掉了!
    月光宝盒是宝物,你把它扔掉会污染环境,要是砸到小朋友怎么办,就算砸不到小朋友,
    砸到花花草草也是不对的。</div>
    </body>
    

    文字围绕浮动元素排列
    上图中,文字围绕着浮动元素排列,不过在这里,这显然不是我们想要的。此时我们可以为.box2元素的样式加上overflow:hidden;使其建立一个BFC,让其内容消除对外界浮动元素的影响。

    自适应布局
    这个方法可以用来实现两列自适应布局,效果不错,此时左边的宽度固定,右边的内容自适应宽度。如果我们改变文字的大小或者左边浮动元素的大小,两栏布局的结构依然没有改变!

     

    特性3:BFC可以包含浮动----清除浮动

    我们都知道浮动会脱离文档流,接下来我们看看下面的例子:

    <style>
    .box1{
      100px;
      height:100px;
      float:left;
      border: 1px solid #000;
    }
    .box2{
      100px;
      height:100px;
      float:left;
      border: 1px solid #000;
    }
    .box{
      background:yellow
    }
    </style>
    <body>
    <div class="box">
      <div class="box1"></div>
      <div class="box2"></div>
    </div> 
    </body>
    

    出现bug

    由于容器内两个div元素浮动,脱离了文档流,父容器内容宽度为零(即发生高度塌陷),未能将子元素包裹住。解决这个问题,只需要把把父元素变成一个BFC就行了。常用的办法是给父元素设置overflow:hidden。

    修补后

    参考文章

    【CSS】深入理解BFC原理及应用

    10 分钟理解 BFC 原理

    补充IFC

    IFC Inline Formatting Contexts,也就是“内联格式化上下文”。

    符合以下任一条件即会生成一个IFC

    • 块级元素中仅包含内联级别元素

    形成条件非常简单,需要注意的是当IFC中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个IFC,这里不做过多介绍。

    IFC布局规则

    • 子元素水平方向横向排列,并且垂直方向起点为元素顶部。
    • 子元素只会计算横向样式空间,【padding、border、margin】,垂直方向样式空间不会被计算,【padding、border、margin】。
    • 在垂直方向上,子元素会以不同形式来对齐(vertical-align)
    • 能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的行框(line box)。行框的宽度是由包含块(containing box)和与其中的浮动来决定。
    • IFC中的“line box”一般左右边贴紧其包含块,但float元素会优先排列。
    • IFC中的“line box”高度由 CSS 行高计算规则来确定,同个IFC下的多个line box高度可能会不同。
    • 当 inline-level boxes的总宽度少于包含它们的line box时,其水平渲染规则由 text-align 属性值来决定。
    • 当一个“inline box”超过父元素的宽度时,它会被分割成多个boxes,这些 oxes 分布在多个“line box”中。如果子元素未设置强制换行的情况下,“inline box”将不可被分割,将会溢出父元素。

    相比较于BFC,IFC的规则噼里啪啦一大堆,很少有人会耐心看下去,举几个例子,花几分钟就可以大概明白其特性。

    很多时候,上下间距不生效可以使用IFC来解释

    .warp { border: 1px solid red; display: inline-block; }
    .text { margin: 20px; background: green; }
    <div class="warp">
        <span class="text">文本一</span>
        <span class="text">文本二</span>
    </div>

    clipboard.png
    左右margin撑开,上下margin并未撑开,符合IFC规范,只计算横向样式控件,不计算纵向样式空间。

    多个元素水平居中

    .warp { border: 1px solid red;  200px; text-align: center; }
    .text { background: green; }
    <div class="warp">
        <span class="text">文本一</span>
        <span class="text">文本二</span>
    </div>

    clipboard.png

    水平排列规则根据IFC容器的text-align值来排列,可以用来实现多个子元素的水平居中。

    float元素优先排列

    .warp { border: 1px solid red;  200px; }
    .text { background: green; }
    .f-l { float: left; }
    <div class="warp">
        <span class="text">这是文本1</span>
        <span class="text">这是文本2</span>
        <span class="text f-l">这是文本3</span>
        <span class="text">这是文本4</span>
    </div>

    clipboard.png
    IFC中具备float属性值的元素优先排列,在很多场景中用来在文章段落开头添加“tag”可以用到。

    最后总结

    利用IFC还可以做很多其他的事情,例如:解决元素垂直居中、多个文本元素行高不一致排列混乱。

  • 相关阅读:
    java处理数据库date类型数据
    in与exist , not in与not exist 的区别
    Eclipse的调试功能的10个小窍门
    关于Synchornized,Lock,AtomicBoolean和volatile的区别介绍
    推荐使用concurrent包中的Atomic类
    深入 Java 调试体系: 第 1 部分,JPDA 体系概览
    dom 绘制正方形
    dom 拖拽div
    dom 按着shift多选
    dom select选单
  • 原文地址:https://www.cnblogs.com/zjx304/p/10185324.html
Copyright © 2020-2023  润新知