zoukankan      html  css  js  c++  java
  • CSS魔法堂:hasLayout原来是这样!

    前言

    过去一直听说旧版本IE下很多诡异bug均由一个神秘角色引起的,那就是hasLayout。趁着最近突然发神经打算好好学习CSS,顺便解答多年来的疑惑。

    hasLayout到底是何方神圣?

    hasLayout可以简单看作是IE5.5/6/7中的BFC(Block Formatting Context)。也就是一个元素要么自己对自身内容进行组织和尺寸计算(即可通过width/height来设置自身的宽高),要么由其containing block来组织和尺寸计算。而IFC(即没有拥有布局)而言,则是元素无法对自身内容进行组织和尺寸计算,而是由自身内容来决定其尺寸(即仅能通过line-height设置内容行距,通过行距来支撑元素的高度;也无法通过width设置元素宽度,仅能由内容来决定而已)
    当hasLayout为true时(就是所谓的"拥有布局"),相当于元素产生新BFC,元素自己对自身内容进行组织和尺寸计算;
    当hasLayout为false时(就是所谓的"不拥有布局"),相当于元素不产生新BFC,元素由其所属的containing block进行组织和尺寸计算。
    和产生新BFC的特性一样,hasLayout无法通过CSS属性直接设置,而是通过某些CSS属性间接开启这一特性。不同的是某些CSS属性是以不可逆方式间接开启hasLayout为true。并且默认产生新BFC的只有html元素,而默认hasLayout为true的元素就不只有html元素了。
    另外我们可以通过object.currentStyle.hasLayout属性来判断元素是否开启了hasLayout特性。

    到这里我们应该了解到若要理解hasLayout则必须理解BFC,因此这里可参考CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins

    默认hasLayout==true的元素

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

    触发hasLayout==true的方式

    display: inline-block
    height: (除 auto 外任何值)
     (除 auto 外任何值)
    float: (left 或 right)
    position: absolute
    writing-mode: tb-rl
    zoom: (除 normal 外任意值)
    

    IE7 还有一些额外的属性(不完全列表)可以触发 hasLayout :

    min-height: (任意值)
    min- (任意值)
    max-height: (除 none 外任意值)
    max- (除 none 外任意值)
    overflow: (除 visible 外任意值,仅用于块级元素)
    overflow-x: (除 visible 外任意值,仅用于块级元素)
    overflow-y: (除 visible 外任意值,仅用于块级元素)
    position: fixed
    

    IE6 以前的版本(也包括 IE6 及以后所有版本的混杂模式,其实这种混杂模式在渲染方面就相当于 IE 5.5), 通过设置任何元素的 'width' 或 'height'(非auto)都可以触发 hasLayout ; 但在 IE6 和 IE7 的标准模式中的行内元素上却不行,设置 'display:inline-block' 才可以。

    其中通过display:inline-blockmin-0min-height:0将不可逆地启用hasLayout特性。而在没有其他属性启用hasLayout时,可通过以下方式关闭hasLayout

    max-width, max-height (设为 "none")(在IE7中)
    position (设为 "static")
    float (设为 "none")
    overflow (设为 "visible") (在IE7中)
    zoom (设为 "normal")
    writing-mode (从 "tb-rl" 设为 "lr-t")
    

    而产生新BFC的CSS属性

    position:absolute/fixed
    float:left/right
    display:inline-block/table-cell/table-caption/flex/inline-flex
    overflow:(除visible外任意值)
    

    可以看到导致产生新BFC的方式和触发hasLayout==true的方式不完全重叠。因此hasLayout==true所引发的问题,很大程度可以理解为在不应该的或没有预料到的地方产生新的BFC导致的。

    如何兼容?

    仅当一个元素即在 IE 早期版本中触发了 hasLayout,又在其他浏览器中创建了 block formatting context 时,才能避免上述问题的发生。即同时启用上述两者以保证各浏览器的兼容,或者相反,两者皆不启用。

    1. 使元素即生成了 block formatting context,又触发了 hasLayout
      1.1 对于触发 hasLayout 的元素,通过 CSS 设置,使它产生 block formatting context;
      1.2 生成 block formatting context 但是没有触发 hasLayout 的元素,通过设置 'zoom:1',使其触发 hasLayout。
    2. 使元素即没有触发 hasLayout,又没有创建 block formatting context。

    总结

    虽然我现在已经不用再适配IE5.5/6/7了,但理解hasLayout还是很有必要的。其实可以理解为从另一个角度学习BFC吧!
    尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/5291166.html肥仔john_

    感谢

    谈谈BFC与ie特有属性hasLayout
    RM8002: 不能同时在 IE6 IE7 IE8(Q) 中触发 hasLayout 并在其他浏览器中创建 Block Formatting Context 的元素在各浏览器中的表现会有差异

  • 相关阅读:
    将 Shiro 作为应用的权限基础
    CMD命令名详细大全
    使用jquery模拟请求,测试项目是否存在跨域限制
    springboot 2.1.4 源码默认logback-spring.xml
    IDEA 代码风格设置
    springboot 实现配置文件给常量赋值
    IDEA Can't Update No tracked branch configured for branch master or the branch doesn't exist.
    @EnableFeignClients 注解
    springboot 定时任务
    SpringCloud 学习网址记录
  • 原文地址:https://www.cnblogs.com/fsjohnhuang/p/5291166.html
Copyright © 2011-2022 走看看