那些年,我们被耍过的bug——haslayout
你被IE的bug耍过几次了?
IE,这个令所有网站设计人员讨厌,但又不得不为它工作的浏览器。不论是6、7还是8,它们都有一个共同的渲染标准haslayout,所以haslayout 是一个非常有必要彻底弄清除的概念。大多 数IE下的显示错误,就是源于它。
什么是Layout呢?
"Layout" 是IE特有的一个属性,并不是W3C标准,很多的ie下的css bug都与其息息相关。它决定了一个对象(就是一个标签div、li等)在内容中如何显示、与周围对象的位置关系、以及怎样响应程序或用户产生的事件。
这个属性可以被一些css强制激活。一些HTML标签默认具有haslayout。
PS:一个对象的layout属性被激活,它的具体表现就是haslayout=true。我们可以用IE Developer Toolbar工具看到被激活的对象带有"haslayout = -1"的属性。
特别注意的是,hasLayout 在 IE 8 及之后的 IE 版本中已经被抛弃,所以在实际开发中只需针对 IE 8 以下的浏览器为某些元素触发 hasLayout 。
一个元素触发 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>
很多情况下,我们把 hasLayout的状态改成true 就可以解决很大部分ie下显示的bug。
hasLayout属性不能直接设定,你只能通过设定一些特定的css属性来触发并改变 hasLayout 状态。下面列出可以触发hasLayout的一些CSS属性值。
-------------------------------------
display
启动haslayout的值:inline-block
取消hasLayout的值:其他值
--------------------------------------
width/height
启动hasLayout的值:除了auto以外的值
取消hasLayout的值:auto
---------------------------------------
position
启动hasLayout的值:absolute
取消hasLayout的值:static
----------------------------------------
float
启动hasLayout的值:left或right
取消hasLayout的值:none
---------------------------------------
zoom
启动hasLayout的值:有值
取消hasLayout的值:narmal或者空值
(zoom是微软IE专有属性,可以触发hasLayout但不会影响页面的显示效果。zoom: 1常用来除错,不过 ie 5 对这个属性不支持。)
----------------------------------------
writing-mode: tb-rl
这也是微软专有的属性。
ie7还有一些额外的属性可以触发该属性(不完全列表):
min-height: (任何值)
max-height: (任何值除了none)
min-width: (任何值)
max-width: (任何值除了none)
overflow: (任何值除了visible)
overflow-x: (任何值除了visible)
overflow-y: (任何值除了visible)5
position: fixed
重置haslayout
在没有其它属性激活layout的情况下,使用下面的css可以重置haslayout属性:
- width, height (设为 "auto")
- max-width, max-height (设为 "none")(在 IE 7 中)
- position (设为 "static")
- float (设为 "none")
- overflow (设为 "visible") (在 IE 7 中)
- zoom (设为 "normal")
- writing-mode (从 "tb-rl" 设为 "lr-t")
display 属性的不同:当用"inline-block"激活了haslayout 属性时,就算在一条独立的规则中覆盖这个属性为"block"或"inline",haslayout 这个标志位也不会被重置为 false。
把 mid-width, mid-height 设为它们的默认值"0"仍然会赋予 hasLayout,但是 IE 7 却可以接受一个不合法的属性"auto"来重置 hasLayout。
haslayout 问题引起的常见 bug
IE6 及更低版本的双空白边浮动 bug
bug 修复: display:inline;
IE5-6/win 的 3 像素偏移 bug
bug 修复: _height:1%;
IE6 的躲躲猫(peek-a-boo) bug
bug 修复: _height:1%;
这里列出触发 hasLayout 元素的一些效果
1.阻止外边距折叠
两个相连的 div 在垂直上的外边距会发生叠加,而触发 hasLayout 的元素之间则不会有这种情况发生,如下图:

也可以查看 Demo 。
上图的例子中,三个 div 各包含一个 p 元素,三个 div 及其包含的 p 元素都有顶部和底部的外边距,但只有第三个 div 的边距没有与它的子元素 p 的外边距折叠。这是因为第三个 div 使用 zoom: 1 触发了 hasLayout ,阻止了它与它的子元素的外边距折叠。
另外,例子中也使用了 overflow: hidden 触发元素的 BFC ,这利用了 BFC 阻止外边距折叠的特性达到元素在 IE 与现代浏览器下的表现统一。
2.可以包含浮动的子元素,即计算高度时包括其浮动子元素
效果如图:

上图的例子中,有两个 div ,它们各包含一个设置了浮动的 p 元素,但第一个 div 实际被浏览器判断为没有高度和宽度,即高度为 0 ,上下边框重叠在一起。而第二个 div 使用 zoom: 1 触发了 hasLayout ,可以包含浮动元素,因此能正确表现出高度,其边框位置也正常了。
本例子中也使用了 overflow: hidden 触发 BFC ,跟上例相似,这利用了 BFC 可以包含浮动子元素的特性达到元素在 IE 与现代浏览器下的表现统一。
3.背景图像显示问题
元素背景图不能正确显示是网页重构中最常见的问题之一了,在 IE 7 及以下的 IE 版本中,没有设置高度、宽度的元素往往不能显示出背景图(背景色则显示正常),这实际上与 hasLayout 有关。实际的情况是,没有触发 hasLayout 的元素不能显示背景图,上面有说过,触发 hasLayout 也就是使到元素拥有布局,换句话说,拥有布局的元素才能正确显示背景图。如下图:

也可以看 Demo (在 IE 7 或更低版本的 IE 下查看以观察背景图问题)。
上图两个 div 都设置了背景图,但只有使用 zoom: 1 触发了 hasLayout 的第二个 div 才能正确显示背景图。
本例子中没有触发元素的 BFC ,这是因为在现代浏览器中,元素本身并没有背景图显示问题。
可以看出,上面的第一、二个例子中,为了使到元素在 IE (包括低版本 IE 以及较新版本的 IE)和现代浏览器中表现尽量统一同时触发了 hasLayout 和 BFC ,而第三个例子中的问题因为只在低版本 IE 中出现,所以只需为低版本 IE 触发 hasLayout ,这些技巧在实际项目中需要特别注意。
上面也有说道,hasLayout 与很多 IE 下的显示 bugs 都有关,实际上很多莫名奇妙的 bugs 都因 hasLayout 而起,因此只要适当的触发元素的 hasLayout ,很多 IE bugs 往往就能解决。
那些年,我们被耍过的bug——haslayout的更多相关文章
- input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has
input屏蔽历史记录 设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处 ;(function($){$.ex ...
- vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结
vue—你必须知道的 目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...
- IE_haslayout_与众多bug的纠缠
haslayout是什么: haslayout是IE的特有属性,就是has(有)layout(布局样式)! 在IE浏览器中,有的元素是默认“has” layout(有布局样式的),而有的元素是没有la ...
- IE下css bug集合-翻译自haslayout.net
概述IE浏览器以不支持大量的css 属性出名,同时也因其支持的css属性中存在大量bug. 本页列举了IE下的一些问题,实例样本和一些我们已知的解决方法. 尽管我已经尽力按照它们本来的性质对它们进行分 ...
- IE6 7 8BUG锦集
1.浮动元素的双倍margin 说明:这是IE6及其以下版本的一个经典的BUG,触发这个BUG产生的条件是给元素设置了浮动并且同一方向设置了margin值.来看以下代码: <style type ...
- CSS 技术关键字
CSS 技术关键字 元素 替换元素 非替换元素------替换元素和非替换元素的分类是CSS范畴内的,其它的分类都不属于CSS定义的 替换元素和非替换元素的定义是出于“我 ...
- IE CSS Bugs 列表和解决方法
我们在开发中我们常会在IE中遇到很多莫名的bug,尤其是老态龙钟的IE6浏览器.为了提高我们的开发效率,需要经常总结,整理工作中遇到的问题.我们在网络上找到的IE Bugs 资料是零散的.不过,在老外 ...
- 关于 Chrome 浏览器中 onresize 事件的 Bug
我在写插件时用到了 onresize 事件,在反复地测试后发现该事件在 Chrome 及 Opera(内核基本与 Chrome 相同,以下统称 Chrome)浏览器打开时就会执行,这种情况也许不能算作 ...
- 小博客| 登录 | 注册 | 留言 | 提Bug 小博客
浏览(1502) 赞(29) 一直以来都想开发一个自己的网站,总想做一个网站然后让千千万万的人去访问,去使用,然后收到热烈的好评, 再然后某某著名机构有意投资我的网站(其实收购也是没有问题的), ...
随机推荐
- C++ multimap容器访问同一键值元素的不同方法
multimap是一种多元map容器,允许一个键对应多个值. 本文介绍了 multimap访问同一键值元素的三种不同方法,详细看下面代码: typedef multimap<string,int ...
- 模块化开发AraeRegistration
.NET/ASP.NET MVC(模块化开发AraeRegistration) 阅读目录: 1.开篇介绍 2.AreaRegistration注册路由(传递路由上下文进行模块化注册) 1]开篇介绍 A ...
- Dynamicaly Typed(动态定型), Objective-C Runtime Programming
Objective-C跟C最大的差别,应该是动态定型(dynamicaly typed),支持在运行时动态类型决议(dynamic typing),动态绑定(dynamic binding)以及动态装 ...
- php面试题中的约瑟夫环
最近忙着做面试题,看到一道题感觉比较有兴趣,查阅相关资料后发现这是一个约瑟夫环的问题. 一群猴子围成一圈,按1,2,3,4,....n一次编号.然后从第1值开始数,数到第m只,把它踢出圈,从它后面再开 ...
- c语言:将二进制数按位输出
问题: 1.输入int 20,其二进制为10100,按位输出10100; 2.或者将1转化为“+”,0转化为“-”,输出就是” + - + - - “; int biTofh(int bi,int l ...
- 程序处理数据库中值字段值为null的查询显示
1.如果你做了一个简单的注册界面,需要用户进行注册,但有些项是不必要填的,当用户完成注册时,数据库表中的相应字段的值会写入null,但如何将查询的字段的值null显示出来? 2.首先我们学习一下如何向 ...
- C# IE代理操作
public class IPProxy { [System.Runtime.InteropServices.DllImport("wininet.dll", SetLastErr ...
- 通过xib自定义UITableViewCell
通过xib自定义UITableViewCell 一.新建iOS Application工程,选择Single View Application,不要选中Use Storyboard.假设指定的是pro ...
- UI基础UIButton
UI基础UIButton 前面写了UIWindow.UIViewController,那些都是一些框架,框架需要填充上具体的view才能组成我们的应用,移动应用开发中UI占了很大一部分,最基础的UI实 ...
- WCF双工学习笔记
WCF双工的作用在于服务端执行某个方法的时候调用客户端的方法,有点类似委托的感觉,实际项目中在什么情况下使用还没想到. WCF双工支持两种bind,一是nettcp.另一个是wsDualHttp,这里 ...