博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CSS魔法堂:hasLayout原来是这样的!
阅读量:5930 次
发布时间:2019-06-19

本文共 2448 字,大约阅读时间需要 8 分钟。

前言

过去一直听说旧版本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,因此这里可参考

默认hasLayout==true的元素

, 
,
,
, ,

,

触发hasLayout==true的方式

display: inline-blockheight: (除 auto 外任何值)width: (除 auto 外任何值)float: (left 或 right)position: absolutewriting-mode: tb-rlzoom: (除 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/fixedfloat:left/rightdisplay:inline-block/table-cell/table-caption/flex/inline-flexoverflow:(除visible外任意值)

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

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

  1. 使元素即生成了 block formatting context,又触发了 hasLayout

    对于触发 hasLayout 的元素,通过 CSS 设置,使它产生 block formatting context;

  2. 生成 block formatting context 但是没有触发 hasLayout 的元素,通过设置 'zoom:1',使其触发 hasLayout。

  3. 使元素即没有触发 hasLayout,又没有创建 block formatting context。

总结

虽然我现在已经不用再适配IE5.5/6/7了,但理解hasLayout还是很有必要的。其实可以理解为从另一个角度学习BFC吧!

尊重原创,转载请注明来自:肥仔john^_^

感谢

你可能感兴趣的文章
iOS检测系统弹窗并自动关闭
查看>>
助力APP尽情“撒币”!阿里云正式上线移动直播问答解决方案
查看>>
webpack动态创建入口
查看>>
聊聊Go工作空间
查看>>
ReactNative学习笔记1
查看>>
vue 开发 2048/围住神经猫 小游戏
查看>>
Android:Fragment懒加载的实现以及自己的封装思路
查看>>
k8s使用kube-router暴露集群中的pod和svc到外部
查看>>
ServiceWorker入门
查看>>
『中级篇』在centos上安装docker(九)
查看>>
Nodejs阿里云OSS获取STS 授权
查看>>
JavaScript this 绑定规则
查看>>
Vue.js单向绑定和双向绑定实例
查看>>
每天一道leetcode88-合并两个有序数组
查看>>
Netty学习笔记
查看>>
java B2B2C 仿淘宝电子商城系统-Spring Cloud与Dubbo对比
查看>>
新氧大数据:2.8%城市占53.7%医美医生,咋找靠谱医生?
查看>>
双重夹击之下,优信如何走出困局?
查看>>
SpringMVC学习笔记1(整合Mybatis&参数绑定)
查看>>
Apple Pay接入详细教程(转)
查看>>