众所周知,BFC和haslayout是CSS布局基础之一,本文主要讲解下haslayout(拥有布局)属性,关于BFC我在下一篇文章做了总结
之前我们说过,给元素添加相关属性可激活BFC,进而解决诸如浮动引起的元素覆盖,外边距重叠,和清除浮动等问题。但是IE7及以下版本不支持BFC,但有私有属性haslayout,于是我们可以通过触发元素的haslayout来达成BFC的相似效果
虽然现在基本已经不用再适配IE5.5/6/7了,但理解hasLayout还是很有必要的。其实可以理解为从另一个角度学习BFC吧!
【引文】
我们都知道ie浏览器和其他一些浏览器有很多表现不同的地方,这确实让人头疼,ie的表现与其他浏览器不同的原因之一就是我们今天要说的这个熟悉又陌生的东西:layout是一个专门针对显示引擎内部工作方式的概念(听起来好像很官方),布局问题是许多ie显示bug的根源
另外在清除浮动的时候也经常提出触发haslayout
【简介】
haslayout 是IE渲染引擎的一个内部组成部分
在IE中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容
(即仅能通过line-height设置内容行距,通过行距来支撑元素的高度;也无法通过width设置元素宽度,仅能由内容来决定而已)
为了调节这两个不同的概念,渲染引擎采用了 hasLayout 的属性,属性值可以为true或false
当一个元素的 hasLayout 属性值为true时,我们说这个元素有一个布局(layout),它负责对自己和可能的子孙元素进行尺寸计算和定位
【由来】
在理想情况下,所有元素都控制自己的尺寸和定位
但 windows上的ie使用布局概念减少它的处理开销,在ie中不是全部的元素都可以控制自己的尺寸和定位
当然,这并不是没有原因的,官方给出的解释是:这样会在ie中导致很大的性能问题,ie开发团队决定只将布局应用于实际需要它的那些元素,这样就可以充分地减少性能的开销
【解析】
如果一个元素“没有拥有布局”,那么它的尺寸和位置由最近拥有布局的祖先元素控制。 ( 拥有了布局的元素会表现会矩形 )
在默认情况下,ie中本身自己就拥有布局的元素包括:
body
html(标准模式)
table
tr、td
img
hr
input、select、textarea、button
iframe、embed、object、applet
marquee
布局的概念是ie特有的,它不是css属性,但是可以通过javascript获取到hasLayout,这是一个只读属性,不可以设置,所以我们不能用js来设置这个属性。
但是我们可以通过设置一些css属性来使没有拥有布局的元素自动拥有布局,我们可以通过设置下面这些属性:
float: left|right;
display: inline-block;
width: any;
height:any;
zoom:any; // 用zoom来触发haslayout的扩展内容
writing-mode:tb-rl;
在ie7中以下的属性也成了布局触发器
overflow: hidden、scroll、auto
min-width: any
max-widht: 除了none以外的任何值
ie8已经放弃了hasLayout属性
【haslayout 问题的调试与解决】
当网页在 IE 中有异常表现时,可以尝试激发 haslayout 来看看是不是问题所在。常用的方法是给某元素 css 设定 zoom:1。使用 zoom:1 是因为大多数情况下,它能在不影响现有环境的条件下激发元素的 haslayout。而一旦问题消失,那基本上就可以判断是haslayout 的原因。然后就可以通过设定相应的 css 属性来对这个问题进行修正了。建议首先要考虑的是设定元素的width/height 属性,其次再考虑其他属性。
对 IE6 及更早版本来说,常用的方法被称为霍莉破解(Holly hack),即设定这个元素的高度为 1%(height:1%;)。需要注意的是,当这个元素的 overflow 属性被设置为 visible 时,这个方法就失效了。或者使用 IE的条件注释。
对 IE7 来说,最好的方法时设置元素的最小高度为 0 (min-height:0;)。
haslayout 问题引起的常见 bug
E6 的躲躲猫(peek-a-boo) bug
bug 修复: _height:1%;
【实际操作】
zoom:1; 是很不错的触发方法,不会改变原来的任何式样,而且仅仅是IE可以识别,但是唯一的坏处就是他不能通过W3C
设置 display:inline-block 然后再设置回原始的 display 属性,这样不会移除 layout,我们就可以达到设置 layout 而不使用IE的条件注释的目的(原理是利用haslayout触发不可逆)
下面是例子:
div { display: inline-block; } div { display: block; } /* 分别在两段 css 块中设置 */
【案例解析---hasLayout都会引发什么问题? 】
1. 浮动元素会被layout元素自动包含
正常情况下,浮动元素会按照left和top的设置偏离原来文档流中的位置,父元素是不会调整高宽去包含该浮动元素的(也就解释了为什么浮动元素不能撑开父容器),但在IE中,layout元素会自动调整高和宽以包含浮动元素(给父容器_height:1%;即可解决)
2.浮动元素旁边的元素。当一个块级元素紧跟在一个左浮动元素之后时,其中的文字内容应该沿着浮动元素的右边顺序排列并会滑到浮动元素下方。但是如果这个块级元素有 layout,那么这个元素就会表现为一个矩形,其中文字不会滑向浮动元素下方
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>IE6 hasLayout 会影响非浮动元素中的文字是否围绕浮动元素</title> <style> *{ margin:0; padding:0; } .box{ width:220px; overflow:auto; font-size:12px; } .leftbox{ background:#CCC; width:100px; height:100px; float:left; *margin-right:-3px; /*针对IE6 浮动元素水平右外边距移动-3px 即可解决*/ } .textbox{ background:#FFCCCC; height:1%;/*去掉后 IE6下 文字不会再围绕浮动*/ } </style> </head> <body> <div class="box"> <div class="leftbox">浮动元素</div> <p class="textbox">文本文本文本文本文本文本文本文本文 本文本文本文本文本文本文本文本文本文本文本文本文本文本文本 文本文本文本文本文本文本文本文本文本文本文本文本文 本文本文本文本文本文本文本文本</p> </div> </body> </html>
3. IE专有的滤镜属性filter是只适用于 layout 元素的,也就是说如果你给一个DIV设置透明用的是filter:alpha(opacity=80);如果你没有让DIV触发hasLayout,那么这个透明将无效
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>IE6 filter透明滤镜 需要触发该元素的hasLayout</title> <style> *{ margin:0; padding:0; } body{ background:#000; font-size:12px; } .textbox{ background:#FFCCCC; opacity:0.8; filter:alpha(opacity=80); zoom:1; } </style> </head> <body> <div class="textbox"> 文本文本文本文本文本 文本文本文本文本本文本文本文本文本文本文本文本文本 文本文文本文本文本文本文本文本文本文本文本文本文本文 本文本文本文本文本文本文本文本文本文本文本文本文本文 本文本文本</div> </body> </html>
【总结】
①hasLayout表现出来的特性跟BFC很相似,所以可以认为是IE中的BFC。上面的规则几乎都遵循,所以上面的问题在IE里都可以通过触发hasLayout来解决。
虽然 hasLayout 也会像 BFC 那样影响着元素的尺寸和定位,但它却又不是一套完整的标准,并且由于它默认只为某些元素触发,这导致了 IE 下很多前端开发的 bugs ,触发 hasLayout 更大的意义在于解决一些 IE 下的 bugs ,而不是利用它的一些“副作用”来达到某些效果。另外由于触发 hasLayout 的元素会出现一些跟触发 BFC 的元素相似的效果,因此为了统一元素在 IE 与支持 BFC 的浏览器下的表现,这里建议为触发了 BFC 的元素同时触发 hasLayout ,当然还需要考虑实际的情况,也有可能只需触发其中一个就可以达到表现统一
【IE下因为haslayout导致的bug】
1、浮动元素与普通元素之间产生3px bug
2、块级元素与浮动元素不会重叠
3、浮动闭合元素
4、ie下margin不塌陷
5、ie下margin-left/right失效
具体问题及解决方案我在后面文章http://570109268.iteye.com/admin/blogs/2410192里做了总结
【最后分享一个不错的文章------普遍定义】
在ie中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容。为了调节这两个不同的概念,渲染引擎采用了
hasLayout 的属性,属性值可以为true或false。当一个元素的
hasLayout属性值为true时,我们说这个元素有一个布局(layout)。如果它设置成了true,它就不得不去渲染它自己,因此元素不得不扩展去包含它的流出的内容。例如浮动或者很长很长的没有截断的单词,如果haslayout没有被设置成true,那么元素得依靠某个祖先元素来渲染它。这就是很多的ie
bugs诞生的地方。当一个元素有一个布局时,它负责对自己和可能的子孙元素进行尺寸计算和定位。简单来说,这意味着这个元素需要花更多的代价来维护自身和里面的内容,而不是依赖于祖先元素来完成这些工作。因此,一些元素默认会有一个布局。当我们说一个元素“拥有layout”或 “得到layout,
或者说一个元素“has layout” 的时候,我们的意思是指它的微软专有属性 hasLayout 被设为了 true。通过IE Developer Toolbar 可以查看 IE 下 HTML元素是否拥有haslayout,在 IE Developer Toolbar 下,拥有 haslayout的元素,通常显示为“haslayout = -1”。
值得注意的是,css下是没有haslayout这一个属性的,只能通过把某些属性设置特定值来使ie下的hasLayout属性触发。这个属性在ie8及以后版本中被抛弃。
激活“haslayout”的方式——调整下列css属性:
-
width
:非auto
任意值——优先考虑 -
height
:非auto
任意值——对 IE6 及更早版本来说很常用,该方法被称为霍莉破解(Holly hack),即设定这个元素的高度为 1% (height:1%;
)。但是要注意,当这个元素的overflow
属性被设置为visible
时,这个方法就失效了。 -
zoom
:非normal
任意值——该属性也为ie特有属性。一般测试的时候用zoom:1
。可以避免改变其他属性破坏布局。 -
position:absolute
——可能引发新问题。 -
float:left/right
——ie 常见bug很多都因为元素设置了浮动而触发haslayout产生的。 -
display:inline-block
——当一个内联元素想获得layout就要使用这个属性。 -
min-height
、max-height
(除none
)、min-width
、max-width
(除none
)设置任意值——针对ie7。 -
overflow
、overflow-x
、overflow-y
除visible
外任意值——针对ie7。 -
position:fixed
——针对ie7。
重置“haslayout”:需要没有其他属性激活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
")
注意:当用inline-block
激活了haslayout 属性时,就算在一条独立的规则中覆盖这个属性为block
或inline
,haslayout 这个标志位也不会被重置为 false。把 min-width
, min-height
设为它们的默认值"0"仍然会赋予 hasLayout,但是 IE 7 却可以接受一个不合法的属性auto
来重置 hasLayout。
.
相关推荐
如果父级元素存在触发了hasLayout布局的元素或者经过定位的元素,那么`offsetParent`返回的是距离自身最近的经过定位或触发hasLayout的父级元素。 ```html ;"> <div id='test'></div> console.log(document....
`hasLayout`是IE特有的行为,触发条件复杂,通常用于解决IE特定的布局问题,但随着现代浏览器的发展,其重要性逐渐减弱。 #### CSS list-style 属性详解 `list-style`属性用于设置列表项标记的类型、位置和图像。 ...
例如,`zoom:1`可以在某些情况下触发IE的`hasLayout`特性,从而帮助修复布局问题。当`hasLayout`被触发时,元素会自适应其内容大小,这在某些场景下能够清除浮动。但需要注意的是,`zoom`仅在IE浏览器中有效,对于...
今天被问起CSS中有个zoom属性是干什么用的,虽然我知道这个属性是用来清除浮动,来触发haslayout的。但具体的定义还不是很了解,就百度了一点关于zoom属性的资料,然后总结了一下。 CSS zoom属性 zoom:设置或检索...
此外,IE7及更高版本还有其他属性可以触发hasLayout,如设置`min-height`, `max-height`, `min-width`, `max-width`, `overflow`等。 五、图像格式的区别与应用场景 1. **JPEG(JPG)**:适用于高质量的连续色调图像...
`hasLayout` 是IE特有的概念,当一个元素满足某些条件(如设置 `width`、`height` 或 `zoom` 不为 `normal`)时,该元素会获得 `hasLayout`,这可能导致元素的行为发生变化,如自动调整大小以包含其内容。...
- **`hasLayout`机制**:IE6-7中,某些元素会触发`hasLayout`导致布局行为变化,通过调整布局方式或设置特定样式可以避免。 - **IE6的`z-index`无效**:在某些情况下,IE6的`z-index`不起作用,可以通过设置父元素...
此外,旧版的Internet Explorer浏览器(如IE6和IE7)在处理display属性时存在限制,特别是在非inline元素转换为inline-block时,需要先转换为inline元素并触发hasLayout属性,才能实现类似效果。 学习display属性是...
开发者可能需要借助`zoom:1`触发hasLayout来实现类似效果。 7. **CSS3选择器** IE7不支持许多CSS3选择器,如`nth-child()`、`nth-of-type()`等,而IE8在标准模式下支持了一部分,但不全面。这需要开发者在编写CSS...
在IE6中,为了触发hasLayout,还需要加上`*zoom: 1`。例如: ```css .news { overflow: hidden; *zoom: 1; } ``` ```html <p>some text ``` 这种方法代码简洁,不需要额外的HTML元素,但可能导致内容溢出时看...
同时使用`zoom: 1`触发IE浏览器的hasLayout特性。 ```css .box:after { content: ""; display: block; clear: both; } .box { zoom: 1; } ``` 5. **第五种方法:设定固定高度** 如果父元素的高度是已知的,...
- 利用`:after`伪元素,通过触发`hasLayout`(在IE6中)来清除浮动。 - 父元素也浮动,但这种方法并不常用。 - 使用`display`属性,如`display:table`或`display:flex`,也能达到清除浮动的效果。 **三、总结** ...
6. `zoom: 1`:针对IE6及更低版本的兼容性问题,通过触发hasLayout机制来实现清除浮动。在其他现代浏览器中,这个属性通常是不必要的。 7. 双伪元素清除浮动:`.clearfix`类的`:before`和`:after`伪元素结合使用,...
/* 触发hasLayout */ } ``` 需要注意的是,不同的解决方案可能对不同浏览器的兼容性有不同的影响,因此在选择方法时应充分考虑目标用户群体所使用的浏览器类型。 总结,理解inline-block元素的间隙来源是解决问题...
但在IE6和IE7中,需要配合`zoom:1`来触发hasLayout。代码示例:`.parent { overflow: hidden; *zoom: 1; }` 7. **使用`:after`伪类** 这是一种更现代的方法,通过在父级元素末尾添加`:after`伪元素,并设置相应的...
`触发hasLayout来实现兼容效果。 #### 二、背景透明问题 在不同的浏览器中,处理背景透明的方法有所不同。 **通用方法**: ```css /* IE7 */ .filter-alpha { filter: alpha(opacity=60); } /* IE8+, Firefox,...
### CSS清除浮动详解 #### 一、引言 在网页设计与前端开发中,CSS(层叠样式表)是用于定义HTML文档外观的关键技术之一。其中,“清除浮动”是一项非常重要的概念,它解决了布局中常见的一个问题——即由于元素...
### IE6十大兼容性问题详解 #### 一、使用正确的文档类型声明 为了确保IE6能够正确解析网页,首先需要在HTML文档的顶部添加正确的文档类型声明。这有助于浏览器识别文档所遵循的标准,并据此进行渲染。 **示例:*...
/* 需要在IE版本4-7中设置,或者设置width或height来触发"hasLayout" */ } ``` - **跨浏览器兼容性**: - **IE**:通过`filter`属性支持滤镜,但语法与其他浏览器不同。 - **非IE浏览器**(如Chrome、Firefox...