什么是haslayout?
haslayout是IE浏览器的私有概念。从CSS的角度看,IE使用这个属性来区别一个元素是自己决定自己的尺寸和内容还是依赖祖先元素来决定自己的尺寸和内容。
对于haslayout = true的元素,自己决定自己的尺寸和内容。
对于haslayout = flase的元素,依赖祖先元素决定自己的尺寸和内容。
haslayout只存在于IE6和7浏览器中(IE6以下的版本不考虑,IE8及更高的版本废除了这一属性)。
为什么不让所有的元素都自己决定尺寸和内容?微软给出的答案是:让所有元素自己决定尺寸和内容会导致性能下降,并且浏览器会有额外的内存开销。
如何查看一个元素的haslayout?
两种方法:
1.在IE Develop Toolbar中,haslayout = true的元素的haslayout属性都是-1。
2.使用js脚本。下面的脚本输出元素的haslayout属性(true or false)。虽然在IE8及更高的版本废除了这个属性,但是在IE8及以后的浏览器中还是可以调用这个脚本来查看元素的haslayout属性的。
var dv = document.getElementById("testdiv"); alert(dv.currentStyle.hasLayout);
什么元素haslayout = true ? 什么元素haslayout = flase ?
下面的元素默认haslayout = true(不是全部的元素,只列举了最常用的元素)
<img>
<table> <tr> <td> <th>
<hr>
<input> <select> <textarea>
<html> <body>
下面的元素默认haslayout = false(不是全部的元素,只列举了最常用的元素)
<form>
<div>
<span>
<h1>~<h6>
<p>
<a>
<ul> <li>
如何让haslayout = false的元素变成haslayout = true?
对于haslayout = false的元素,通过设置特定的CSS属性可以使其haslayout = true.
下面的方法(不全,只列举了常用的方法)对IE6和IE7都能改变haslayout = true。
position : absolute;
float : left/right;
display : inline-block;
width/height : 10px;(设定特定的值就可以)
zoom : 1;(设定特定的值就可以)
下面的方法只对IE7起作用(IE6和IE7一般都是同时改变元素的haslayout属性,因此下面的方法用的不是很多)
overflow/overflow-x/overflow-y : auto/hidden/scroll;
min-width/min-height : 10px;(包含0在内的任意值)
max-width/max-height : 10px;(除none外的任何值)
position : fixed;
(在很多讲解haslayout的文章中都有这么一句话“如果某个HTML元素拥有 haslayout 属性,那么这个元素的 haslayout 的值一定只有 true,haslayout 为只读属性 一旦被触发,就不可逆转”,但是通过简单demo就可以测试这句话的真实性。 div#testdiv{height: 60px;display: inline;},实际测试中,这个div的haslayout = false。所以,如果不是我的理解有问题,那么上面的那句话是有问题的)
改变元素的haslayout属性有什么用处?
众所周知,IE6和IE7下的众多CSS的bug让每一个前端工程师头疼,而许多bug的产生就和haslayout属性有关。对于很多bug,只要设置元素的haslayout = true就能解决问题,下面列举几种常见。
1. 清除浮动
清除浮动,这个词对于每个前端工程师再熟悉不过了。
<div id="father-div"> <div id= "son-div"> 这是内部的浮动div <br> 蓝色是外部div的边框 </div> </div>
#father-div{ border: 1px solid blue; /* 300px;*/ } #son-div{ height: 60px; width: 200px; background-color: red; float: left; }
效果图:
内部div的浮动导致内部div脱离文档流,而外部div的haslayout = false,也就是根据祖先元素决定自己的尺寸和位置。内部div的脱离导致外部div不包含任何内容,所有外部div的高度是0。
如果给外部div添加CSS属性使其haslayout = true,那么外部div自己决定尺寸和位置,就能包含内部的子元素。
#father-div{ border: 1px solid blue; /* 300px;*/ /*zoom:1;*/ /*height: 100px;*/ /*float: left;*/任何一个都可以,实际中使用较多的是设置zoom、float、display display: inline-block; } #son-div{ height: 60px; width: 200px; background-color: red; float: left; }
效果图:
2.与浮动元素相邻的元素会被浮动元素遮挡,设置元素的haslayout = true避免与浮动元素重合。
下面的应用很常见,在许多社交网站很多。
头像左浮动,右边的是一个div。如果按照常规的思路写出下面的代码:
<div id="left-div"></div> <div id="right-div"> 我以前在国内读研上课时,可怜的老师时不时被学生这样质问:老师你说我们学这些有什么用呢?能不能教点对我们找工作有帮助的东西? 我很想知道当年牛顿讲授重力原理和月亮轨迹时,是不是也有一帮这么讨厌的人在问:老师你说我们学这些有什么用呢?而如果有人这样问,牛顿会不会反问:难到仅仅满足我们的好奇心还不够吗? </div>
#left-div{ float: left; width: 40px; height: 40px; background-color: red; } #right-div{ background-color: blue; }
那么出现的效果图如下:
可见,右侧的div会被浮动的元素遮挡住一部分,并且右侧div内的文字无法对齐。可以设置右侧div的haslayout = true(下面的效果图使用的是zoom:1;)让其和浮动元素不重叠。
题外话:
如果您觉得文章有用,倍感荣幸;
如果发现错误,欢迎提出指正;
个人学习笔记,不喜勿喷,文明讨论!