BFC(块级格式化上下文)

它是页面中一块独立的渲染区域。并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。具有BFC特性的元素可以看成是一个隔离的独立容器,让处于BFC内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。


IE浏览器下为hasLayout,一般可以通过zoom:(除normal外任意值)来触发,hasLayout是IE浏览器渲染引擎的一个内部组成部分。在IE浏览器中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和和组织内容。为了调节这两个不同的概念,渲染引擎采用了hasLayout的属性,属性值可以为true或false。当一个元素的hasLayout属性为true时,我们就说这个元素有一个布局(Layout)。当拥有布局后,它会负责对自己和可能的子孙元素进行尺寸计算和定位,而不是依赖于祖先元素来完成这些工作。

如何实现BFC(Block Fromatting Context)

  • 根元素(<html>)
  • 浮动元素(元素的float)
  • 绝对定位元素(元素的position为absolute或fixed)
  • 行内块元素(元素的display为inline-block)**
  • 表格单元格(元素的display为table-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的display为table-caption,HTML表格标题默认为该值)
  • display值为flow-root的元素
  • overflow属性的值不为visible
  • 弹性元素(display为flex或inline-flex元素的直接子元素)
  • 网格元素(display为grid或者inline-grid元素的直接子元素)

布局规则

普通文档流布局规则:

  1. 浮动元素是不会被父元素计算高度的【其他盒子会无视这个元素,但其他盒子内的文本依然会为这个元素让出位置,环绕在周围。】
  2. 非浮动元素会覆盖浮动元素的位置
  3. margin会传递给父级
  4. 两个相邻元素上下margin会发生重叠

BFC布局规则:

  • 浮动的元素会被父级计算高度(父级触发了BFC)
  • 非浮动元素不会覆盖浮动元素的位置(非浮动元素触发了BFC)
  • margin不会传递给父级(父级触发了BFC)
  • 两个相邻元素上下margin不会发生重叠(给其中一个元素增加一个父级,并让它的父级触发BFC)

双飞翼布局

.content {
    float: left;
    width: 100%;
}

.main,
.left,
.right {
    height: 200px;
    line-height: 200px;
    text-align: center;
    font-size: 20px;
    color: #fff;
}

.main {
    margin-left: 160px;
    margin-right: 110px;
    background: green;
}

.left {
    float: left;
    margin-left: -100%;
    width: 150px;
    background: red;
}

.right {
    float: left;
    margin-left: -100px;
    width: 100px;
    background: blue;
}

<div class="content">
    <div class="main">中</div>
</div>
<div class="left">左</div>
<div class="right">右</div>
  • .content【主列】:浮动左侧,宽度100%(宽度全让它给占了,左右两侧的层该怎么办?)
  • .left【子列】:浮动左侧,宽度150,左边界为-100%(此处是关键:浮动情况下,负边界值会导致DIV上移,而使用-100%可以确实它移动到最左侧。
  • .right【附加列】:左浮动,宽度100px,左边界为-100px
    1.道理同上,注意的是,负左边界一定要大于或等于该DIV的宽度,才能靠到上一行去;
    2.在这里margin-left: -100px;而不是-100%的原因是。我们希望它在右侧,而它是左浮动;
    3.第一行的宽度已经被中这个盒子占了,它只能在第二行从左到右;
    4.但是一旦我们给它设置一个margin-left负值,它就开始向左移动,一直移动到margin-left的值的绝对值是大于等于它的宽度,这样它就跑到上面去了。
    5.但是需要注意的点是:在对.right盒子设置margin-left负值成立的前提都是要给.left设置 margin-left: -100%;

小结:

优点:比较经典的一种方式,通用性强,没有兼容性问题,而且支持主要内容优先加载。
缺点:元素脱离了文档流,要注意清除浮动,防止高度塌陷,同时额外增加了一层DOM结构,即增加了渲染树生成的计算量。

清除浮动


   .container::after{
            content: '';
            display: block;
            font-size: 0;
            height: 0;
            line-height: 0;
            clear: both;
            visibility: hidden;
        }
        .container{
         // 注意此处是为了兼容IE6和IE7浏览器,即触发hasLayout
            zoom: 1;
        }

圣杯布局

.container {
    margin-left: 160px;
    margin-right: 110px;
}

.left,
.main,
.right {
    height: 200px;
    line-height: 200px;
    text-align: center;
    font-size: 20px;
    color: #fff;    
}

.main {
    float: left;
    width: 100%;
    background: green;        
}

.left {
    position: relative;
    left: -160px;
    margin-left:  -100%;
    float: left;
    width: 150px;
    background: red;
}

.right {
    position: relative;
    right: -110px;
    margin-left:  -100px;
    float: left;
    width: 100px;
    background: blue;
}

<div class="container">
    <div class="main">中</div>
    <div class="left">左</div>
    <div class="right">右</div>
</div>

优点:相比于双飞翼布局,结构更加简单,没有多余的DOM结构层,同样支持主要内容优先加载。
缺点:元素同样脱离了文档流,要注意清除浮动,防止高度塌陷。


素素
37 声望0 粉丝

« 上一篇
ES6-Promise
下一篇 »
es6总结