• BFC给我的帮助以及对hasLayout的认识


    布局的时候经常想让一个或几个元素并并排的放在一起,有时给其中的一个浮动,元素是在一行了,可还是都左边重叠了,总是这样那样改来改去,小白的我也是醉了!

    今天偶然间看到了了BFC这个东东,虽然现在还是不是很深入的了解,但至少一行不用在在上面的问题上浪费时间了(捂脸)。

    一、什么是BFC?

    BFC(Block Formatting Context)直译为“块级格式化范围”。

     W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个BFC就是一个独立的行政单位的意思。也可以说BFC就是一个作用范围。可以把它理解成是一个独立的容器,并且这个容器的里box的布局,与这个容器外的毫不相干。

    另一个通俗点的解释是:在普通流中的 Box(框) 属于一种 formatting context(格式化上下文) ,类型可以是 block ,或者是 inline ,但不能同时属于这两者。并且, Block boxes(块框) 在 block formatting context(块格式化上下文) 里格式化, Inline boxes(块内框) 则在 inline formatting context(行内格式化上下文) 里格式化。任何被渲染的元素都属于一个 box ,并且不是 block ,就是 inline 。即使是未被任何元素包裹的文本,根据不同的情况,也会属于匿名的 block boxes 或者 inline boxes。所以上面的描述,即是把所有的元素划分到对应的 formatting context 里。

     二、怎样产生BFC?

     当一个HTML元素满足下面条件的任何一点,都可以产生

    float值不为none;

    overflow值不为visible;

    display值为inline-block,table-cell,table-caption中的任意一个;

    postion值不为relative和static;

    三、BFC的作用

    记录一下自己刚写的时候常遇到的情况:

    情况1:一个浮动元素后面跟着一个没有浮动的元素,两个元素会重叠在一起。当时为了拆散他俩,内边距,外边距什么都用了,想想也是够难为自己的。

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="utf-8"/>
    <title>生成BFC元素和浮动元素在一起不会重叠</title>
    <style type="text/css">
    * { padding:0; margin:0; color:#fff; text-decoration:none; list-style:none; font-family:"微软雅黑" }

    .div1{
    float:left;
    200px;
    height:400px;
    background:red;

    }
    .div2{
    overflow:hidden;//生成BFC
    300px;
    height:500px;
    background:blue;
    }
    </style>
    </head>
    <body>

    <div class="div1"></div>
    <div class="div2"></div>

    </body>
    </html>

     

    根据 CSS 2.1 9.5 Floats 中的描述,创建了 Block Formatting Context 的元素不能与浮动元素重叠。

       表格的 border-box、块级的替换元素、或是在普通流中创建了新的 block formatting context(如元素的 'overflow' 特性不为 'visible' 时)的元素不可以与位于相同的 block formatting context 中的浮动元素相重叠。所以给div2添加overfl:hidden.

    ie的原因需要再加一个解发haslayout的zoom:1

    情况2:让拥有浮动子元素的父元素获取高度。

    如果一个父元素的子元素浮动的话,其父元素是不计算其的高度的,情况就成了这样的了,o(╯□╰)o

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="utf-8"/>
    <title>生成BFC元素的浮动子元素也参与高度计算</title>
    <style type="text/css">
    * { padding:0; margin:0; color:#fff; text-decoration:none; list-style:none; font-family:"微软雅黑" }
    .big{
    overflow:hidden;//针对图片3
    300px;
    border:1px solid #666;
    padding:10px;
    }
    .div1{
    float:left;
    200px;
    height:50px;
    background:red;

    }
    .div2{
    float:left;
    200px;
    height:50px;
    background:blue;

    }
    </style>
    </head>
    <body>
    <div class="big">
    <div class="div1"></div>
    <div class="div2"></div>
    </div>

    </body>
    </html>

         图片2

    根据 CSS2.1 规范第 10.6.3 部分的高度计算规则,在进行普通流中的块级非替换元素的高度计算时,浮动子元素不参与计算。

    同时 CSS2.1 规范第10.6.7部分的高度计算规则,在计算生成了 block formatting context 的元素的高度时,其浮动子元素应该参与计算。

    所以,触发外部容器BFC,高度将重新计算。比如给big加上属性overflow:hidden触发其BFC。

     生成BFC之后的效果:

           图片3

     情况3:两个上下相邻元素设置分别给其设置margin-bottom和margin-top值时会重叠。

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="utf-8"/>
    <title>相邻的两个盒子的margin值会重叠</title>
    <style type="text/css">
    * { padding:0; margin:0; color:#fff; text-decoration:none; list-style:none; font-family:"微软雅黑" }
    .div1{
    200px;
    height:50px;
    background:red;
    margin-bottom:20px;
    }
    .div2{
    200px;
    height:50px;
    background:blue;
    margin-top:20px;
    }
    </style>
    </head>
    <body>

    <div class="div1"></div>
    <div class="div2"></div>
    </body>
    </html>

         图片4

    根据 CSS 2.1 8.3.1 Collapsing margins 第一条,两个相邻的普通流中的块框在垂直位置的空白边会发生折叠现象。也就是处于同一个BFC中的两个垂直窗口的margin会重叠。

    根据 CSS 2.1 8.3.1 Collapsing margins 第三条,生成 block formatting context 的元素不会和在流中的子元素发生空白边折叠。所以解决这种问题的办法是要为两个容器添加具有BFC的包裹容器。

    所以解这个问题的办法就是,把两个容器分别放在两个据有BFC的包裹容器中,IE里就是触发layout的两个包裹容器中!

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="utf-8"/>
    <title>相邻的两个盒子的margin值会重叠</title>
    <style type="text/css">
    * { padding:0; margin:0; color:#fff; text-decoration:none; list-style:none; font-family:"微软雅黑" }
    .big{
    overflow:hidden;
    }
    .div1{
    200px;
    height:50px;
    background:red;
    margin-bottom:20px;
    }
    .div2{
    200px;
    height:50px;
    background:blue;
    margin-top:20px;
    }
    </style>
    </head>
    <body>
    <div class="big">
    <div class="div1"></div>
    </div>
    <div class="big">
    <div class="div2"></div>
    </div>

    </body>
    </html>

        图片5

     平时也会看到很多这些情况,但很少自己动手做的,今天就给自己加深加深也学习学习BFC东东!

    BFC篇完结了!

    关于更详细的请查看穆乙 http://www.cnblogs.com/pigtail/

    什么是IE的haslayout

    上面的例子中我们用到了IE的zoom:1;实际上是触发了IE的layout。Layout 是 IE 浏览器渲染引擎的一个内部组成部分。在 IE 浏览器中,一个元素要么自己对自身的内容进行组织和计算大小, 要么依赖于包含块来计算尺寸和组织内容。为了协调这两种方式的矛盾,渲染引擎采用了 ‘hasLayout’ 属性,属性值可以为 true 或 false。 当一个元素的 ‘hasLayout’ 属性值为 true 时,我们说这个元素有一个布局(layout),或拥有布局。可以通过 hasLayout 属性来判断一个元素是否拥有 layout ,

    如 object.currentStyle.hasLayout 。

    hasLayout 与 BFC 有很多相似之处,但 hasLayout 的概念会更容易理解。在 Internet Explorer 中,元素使用“布局”概念来控制尺寸和定位,分为拥有布局和没有布局两种情况,拥有布局的元素由它控制本身及其子元素的尺寸和定位,而没有布局的元素则通过父元素(最近的拥有布局的祖先元素)来控制尺寸和定位,而一个元素是否拥有布局则由 hasLayout 属性告知浏览器,它是个布尔型变量,true 代表元素拥有布局,false 代表元素没有布局。简而言之,hasLayout 只是一个 IE 下专有的属性,hasLayout 为 true 的元素浏览器会赋予它一系列的效果。

    特别注意的是,hasLayout 在 IE 8 及之后的 IE 版本中已经被抛弃,所以在实际开发中只需针对 IE 8 以下的浏览器为某些元素触发 hasLayout。

    五、怎样触发layout

    一个元素触发 hasLayout 会影响一个元素的尺寸和定位,这样会消耗更多的系统资源,因此 IE 设计者默认只为一部分的元素触发 hasLayout (即默认有部分元素会触发 hasLayout ,这与 BFC 基本完全由开发者通过特定 CSS 触发并不一样),这部分元素如下:

    复制代码
    <html>, <body>
    <table>, <tr>, <th>, <td>
    <img>
    <hr>
    <input>, <button>, <select>, <textarea>, <fieldset>, <legend>
    <iframe>, <embed>, <object>, <applet>
    <marquee>
    复制代码

    除了 IE 默认会触发 hasLayout 的元素外,Web 开发者还可以使用特定的 CSS 触发元素的 hasLayout 。

    通过为元素设置以下任一 CSS ,可以触发 hasLayout (即把元素的 hasLayout 属性设置为 true)。

    复制代码
    display: inline-block
    height: (除 auto 外任何值)
     (除 auto 外任何值)
    float: (left 或 right)
    position: absolute
    writing-mode: tb-rl
    zoom: (除 normal 外任意值)
    min-height: (任意值)
    min- (任意值)
    max-height: (除 none 外任意值)
    max- (除 none 外任意值)
    overflow: (除 visible 外任意值,仅用于块级元素)
    overflow-x: (除 visible 外任意值,仅用于块级元素)
    overflow-y: (除 visible 外任意值,仅用于块级元素)
    position: fixed
    复制代码

    对于内联元素(可以是默认被浏览器认为是内联元素的 span 元素,也可以是设置了 display: inline 的元素),width 和 height 只在 IE5.x 下和 IE6 或更新版本的 quirks 模式下能触发元素的 hasLayout ,但是对于 IE6,如果浏览器运行于标准兼容模式下,内联元素会忽略 width 或 height 属性,所以设置 width 或 height 不能在此种情况下令该元素触发 hasLayout 。但 zoom 除了在 IE 5.0 中外,总是能触发 hasLayout 。zoom 用于设置或检索元素的缩放比例,为元素设置 zoom: 1 既可以触发元素的 hasLayout 同时不会对元素造成多余的影响。因此综合考虑浏览器之间的兼容和对元素的影响, 建议使用 zoom: 1 来触发元素的 hasLayout 。

    六、能解决的问题

    hasLayout表现出来的特性跟BFC很相似,所以可以认为是IE中的BFC。上面的规则几乎都遵循,所以上面的问题在IE里都可以通过触发hasLayout来解决。

    虽然 hasLayout 也会像 BFC 那样影响着元素的尺寸和定位,但它却又不是一套完整的标准,并且由于它默认只为某些元素触发,这导致了 IE 下很多前端开发的 bugs ,触发 hasLayout 更大的意义在于解决一些 IE 下的 bugs ,而不是利用它的一些“副作用”来达到某些效果。另外由于触发 hasLayout 的元素会出现一些跟触发 BFC 的元素相似的效果,因此为了统一元素在 IE 与支持 BFC 的浏览器下的表现,Kayo 建议为触发了 BFC 的元素同时触发 hasLayout ,当然还需要考虑实际的情况,也有可能只需触发其中一个就可以达到表现统一,下面会举例介绍。

    这里首先列出触发 hasLayout 元素的一些效果:

    a、阻止外边距折叠

     如上面例子:

    复制代码
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>无标题文档</title>
    <style>
    html, body { height:100%; }
    * { padding:0; margin:0; color:#fff; text-decoration:none; list-style:none; font-family:"微软雅黑" }
    .mg {zoom:1}
    .rowone { background:#f00; height:100px; margin-bottom:20px; }
    .rowtow { background:#090; height:100px; margin-top:20px; }
    </style>
    </head>
    
    <body>
    <div class="mg">
        <div class="rowone">
        </div>
    </div>
    <div class="mg">
        <div class="rowtow">
        </div>
    </div>
    </body>
    </html>
    复制代码

    需要触发.mg的layout才能解决margin重叠问题

    运行效果如下:

  • 相关阅读:
    运算符重载
    简单函数template max
    const static extern
    python 关闭垃圾回收
    Easy and cheap cluster building on AWS backup
    [转] Maven更新父子模块的版本号, mvn versions:set
    [转] ansible批量执行命令展示
    HBase 批量删除表 disable_all drop_all
    自动添加 ssh key 到远程主机的脚本,应用sshpass和ssh-copy-id
    MongoDB ver 4 几个常用命令
  • 原文地址:https://www.cnblogs.com/wine/p/4599819.html
Copyright © 2020-2023  润新知