zoukankan      html  css  js  c++  java
  • CSS定位之BFC背后的神奇原理

    BFC已经是一个耳听熟闻的词语了,网上有许多关于 BFC 的文章,介绍了如何触发 BFC 以及 BFC 的一些用处(如清浮动,防止 margin 重叠等)。

    什么是BFC

    在解释 BFC 是什么之前,需要先介绍 Box Formatting Context的概念。BFC这个东西说常见的话你可能不觉得,但是你肯定会常用,也许你在用的时候也没想到BFC这东西。

    css布局的基本单位

    Box 是 css 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。

    不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。让我们看看有哪些盒子:

    block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。

    并且参与 block fomatting context;inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context;run-in box: css3 中才有, 这儿先不讲了。

    Formatting context

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

    最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。

    css2.1 中只有 BFC 和 IFC, css3 中还增加了 GFC 和 FFC。

    BFC 定义

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

    BFC布局规则

    内部的Box会在垂直方向,一个接一个地放置。

    Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。

    每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。

    BFC的区域不会与float box重叠。

    BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

    计算BFC的高度时,浮动元素也参与计算

    资源网站大全 https://55wd.com 我的007办公资源网站 https://www.wode007.com

    哪些元素产生BFC

    > 根元素

    > float属性不为none

    > position为absolute或fixed

    > display为inline-block, table-cell, table-caption, flex, inline-flex

    > overflow不为visible

    BFC的作用

    1、阻止外边距折叠

    问题案例:margin塌陷问题:在标准文档流中,块级标签之间竖直方向的margin会以大的为准,这就是margin的塌陷现象。可以用overflow:hidden产生bfc来解决。

    <head>
    div{
         100px;
        height: 100px;
        background: lightblue;
        margin: 100px;
    }
    </head>
    <body>
        <div></div>
        <div></div>
    </body>
    

      

    从效果上看,因为两个div元素都处于同一个BFC容器下(这里指body元素),所以第一个div的下边距和第二个div的上边距发生了重叠,所以两个盒子之间距离只有100px,而不是200px。 首先这不是 css 的 bug,我们可以理解为一种规范,如果想要避免外边距的重叠,可以将其放在不同的 BFC 容器中。

    <div class="container">
        <p></p>
    </div>
    <div class="container">
        <p></p>
    </div>
    <style>
    .container {
        overflow: hidden;
    }
    p {
         100px;
        height: 100px;
        background: lightblue;
        margin: 100px;
    } 
    </style>
    

      

    2、包含浮动元素 

    问题案列:高度塌陷问题,在通常情况下父元素的高度会被子元素撑开,而在这里因为其子元素为浮动元素所以父元素发生了高度坍塌,上下边界重合,这时就可以用BFC来清除浮动了。

    <div style="border: 1px solid #000;">
        <div style=" 100px;height: 100px;background: grey;float: left;"></div>
    </div>
    

      

    由于容器内元素浮动,脱离了文档流,所以容器只剩下2px的边距高度。如果触发容器的BFC,那么容器将会包裹浮动元素。 

    <div style="border: 1px solid #000;overflow: hidden">
        <div style=" 100px;height: 100px;background: grey;float: left;"></div>
    </div>
    

      

    3、阻止元素被浮动元素覆盖 

     问题案例:div浮动兄弟这该问题:由于左侧块级元素发生了浮动,所以和右侧未发生浮动的块级元素不在同一层内,所以会发生div遮挡问题。可以给右侧元素添加 overflow: hidden,触发BFC来解决遮挡问题。

    <div style="height: 100px; 100px;float: left;background: lightblue">我是一个左浮动的元素</div>
    <div style=" 200px; height: 200px;background: grey">我是一个没有设置浮动, 
    也没有触发 BFC 元素,  200px; height:200px; background: grey;</div>
    

      

    这时候其实第二个元素有部分被浮动元素所覆盖,但是文本信息不会被浮动元素所覆盖,如果想避免元素被覆盖,可触发第二个元素的BFC特性,在第二个元素中加入overflow:hidden,就会变成:

    <div style="height: 100px; 100px;float: left;background: lightblue">我是一个左浮动的元素</div>
    <div style=" 200px; height: 200px;background: grey;overflow:hidden">我是一个没有设置浮动, 
    也没有触发 BFC 元素,  200px; height:200px; background: grey;</div>
    

      

    这个方法可以用来实现两列自适应布局,效果不错,这时候左边的宽度固定,右边的内容自适应宽度。  

    总结

    BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

    因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。 

  • 相关阅读:
    POJ 1659 Frogs' Neighborhood
    zoj 2913 Bus Pass(BFS)
    ZOJ 1008 Gnome Tetravex(DFS)
    POJ 1562 Oil Deposits (DFS)
    zoj 2165 Red and Black (DFs)poj 1979
    hdu 3954 Level up
    sgu 249 Matrix
    hdu 4417 Super Mario
    SPOJ (BNUOJ) LCM Sum
    hdu 2665 Kth number 划分树
  • 原文地址:https://www.cnblogs.com/ypppt/p/13370761.html
Copyright © 2011-2022 走看看