前言

过去一直听说旧版本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 外任何值)
width: (除 auto 外任何值)
float: (left 或 right)
position: absolute
writing-mode: tb-rl
zoom: (除 normal 外任意值)

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

min-height: (任意值)
min-width: (任意值)
max-height: (除 none 外任意值)
max-width: (除 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-width: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 的元素在各浏览器中的表现会有差异

CSS魔法堂:hasLayout原来是这样!的更多相关文章

  1. CSS魔法堂:"那不是bug,是你不懂我!" by inline-block

    前言  每当来个需要既要水平排版又要设置固定高宽时,我就会想起display:inline-block,还有为了支持IE5.5/6/7的hack*display:inline;*zoom:1;.然后发 ...

  2. CSS魔法堂:Box-Shadow没那么简单啦:)

    前言  说起box-shadow那第一个想法当然就是用来实现阴影,其实它还能用于实现其他好玩的效果的,本篇就打算说说box-shadow的那些事. 二话不说看效果 3D小球 <style typ ...

  3. CSS魔法堂:重拾Border之——更广阔的遐想

    前言  当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-t ...

  4. CSS魔法堂:重拾Border之——不仅仅是圆角

    前言  当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-t ...

  5. CSS魔法堂:重拾Border之——图片作边框

    前言  当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-t ...

  6. CSS魔法堂:重拾Border之——解构Border

    前言  当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-t ...

  7. CSS魔法堂:小结一下Box Model与Positioning Scheme

    前言  对于Box Model和Positioning Scheme中3种定位模式的细节,已经通过以下几篇文章记录了我对其的理解和思考.  <CSS魔法堂:重新认识Box Model.IFC.B ...

  8. CSS魔法堂:说说Float那个被埋没的志向

    前言  定位系统中第一难理解就是Normal flow,而第二就非Float莫属了,而Float难理解的原因有俩,1. 一开头我们就用错了:2. 它跟Normal flow靠得太近了.本文尝试理清Fl ...

  9. CSS魔法堂:你一定误解过的Normal flow

    前言  刚接触CSS时经常听到看到一个词"文档流",那到底什么是"文档流"呢?然后会看到"绝对定位和浮动定位能脱离文档流",从这句可以看到文 ...

随机推荐

  1. 用javascript写Android和iOS naitve应用,实在炫酷。

    关注NativeScript有一段时间了,说好了的三月发第一个Beta版,终于发布了. // declare the extended NativeScriptActivity functionali ...

  2. SQL入门经典(十) 之事务

    事务是什么?事务关键在与其原子性.原子性概念是指可以把一些事情当作一个执行单元来看待.从数据库角度看待.他是指应该全部执行或者全部不执行一条或多条语句的最小组合.当处理数据时候经常确保一件事发生另一件 ...

  3. Oracle PL/SQL块

    PL/SQL块 简介 :PL/SQL是 Procedure Language & Structured Query Language 的缩写,是ORACLE公司对标准数据库语言的扩展 PL/S ...

  4. 软将工程课设day9

    UI设计demo2.0. 在昨日demo的基础上进行了优化. 撰写美工设计报告,个人报告

  5. 分享google的技能的11个级别,大家看看自己到哪个级别了?

    you are unfamiliar with the subject area. you can read / understand the most fundamental aspects of ...

  6. 淘宝UWP--自定义图片缓存

    一.应用场景 在淘宝应用首页,会有很多张图片,而这些首页图片不会经常改变,所以就需要缓存下来.这样就不必每次都从网络获取. 二.比较对象 1.系统缓存 对于系统缓存,我们不需要做什么处理.只需要把网络 ...

  7. 消息中间件与JMS标准

    初识消息中间件 维基百科上对于消息中间件的定义是"Message-oriented middleware(MOM) is software infrastructure focused on ...

  8. IO完成端口

    从MSDN中翻译了IO完成端口的文章,不得不说翻译的很烂,英语需要继续提高啊... 在一个多处理器系统上,IO完成端口提供一个非常高效的线程模型来处理多个异步IO请求.当一个进程创建了一个IO完成端口 ...

  9. 招聘:有兴趣做一个与Android对等的操作系统么?

    招聘:有兴趣做一个与Android对等的操作系统么? 前不久我发了一篇<八一八招聘的那些事儿>讲了我自己作为求职者对招聘的一些看法.那个时候我还在求职,对求职的结果还是挺满意的,五家公司面 ...

  10. Redis学习笔记~StackExchange.Redis实现分布式Session

    回到目录 对于多WEB的环境现在已经是必须的了,很难想像一台WEB服务器面对百万并发的响应,所以,我们需要多台WEB服务器集群合作,来缓解这种高并发,高吞吐的场景,而对于多WEB的场景又会有个问题出现 ...