深度css: DIV+CSS两种盒子模型及IE的 haslayout
对网页前端来说DIV+css还有其引发的各浏览器兼容性问题是一个值得永恒探讨的问题。设计人员需要UI实现对css固然是该深入研究的;而研发人员有 时候也不得不自己写或修改一些简单的css;因此网上收集整理了一些css至关重要的基础知识;也许你心中总会想为什么一句简单的CSS代码写下去跟实际 表现有如此大差距?根源就在于浏览器是根据怎样的标准来渲染各元素的排版,希望这文章能给大家带来思考和答案。
DIV+CSS两种盒子模型
利用CSS来布局页面布局DIV有点逻辑性!
重点理解盒子模型,标准流和非标准流的区别,还有定位原理!把这3个攻破了,就非常简单了!多实践多参考!
最后就是兼容问题了,在实践中自然就有经验了!这些兼容技巧都是经验来的!
盒子模型有两种,分别是 IE 盒子模型和标准 W3C 盒子模型。他们对盒子模型的解释各不相同,
先来看看我们熟悉的标准盒子模型:
从上图可以看到标准 W3C 盒子模型的范围包括 margin、border、padding、content,并且 content 部分不包含其他部分。
从上图可以看到 IE 盒子模型的范围也包括 margin、border、padding、content,和标准 W3C 盒子模型不同的是:IE 盒子模型的 content 部分包含了 border 和 pading。
例:一个盒子的 margin 为 20px,border 为 1px,padding 为 10px,content 的宽为 200px、高为
50px,如果用标准 W3C 盒子模型解释,那么这个盒子需要占据的位置为:宽 20*2+1*2+10*2+200=262px、高
20*2+1*2*10*2+50=112px,盒子的实际大小为:宽 1*2+10*2+200=222px、高
1*2+10*2+50=72px;如果用IE 盒子模型,那么这个盒子需要占据的位置为:宽 20*2+200=240px、高
20*2+50=70px,盒子的实际大小为:宽 200px、高 50px。
那应该选择哪中盒子模型呢?当然是“标准 W3C
盒子模型”了。怎么样才算是选择了“标准 W3C 盒子模型”呢?很简单,就是在网页的顶部加上 DOCTYPE 声明。如果不加 DOCTYPE
声明,那么各个浏览器会根据自己的行为去理解网页,即 IE 浏览器会采用 IE 盒子模型去解释你的盒子,而 FF 会采用标准 W3C
盒子模型解释你的盒子,所以网页在不同的浏览器中就显示的不一样了。反之,如果加上了 DOCTYPE 声明,那么所有浏览器都会采用标准 W3C
盒子模型去解释你的盒子,网页就能在各个浏览器中显示一致了。
IE的layout属性详解
要想更好的理解 css, 尤其是 IE 下对 css 的渲染,haslayout 是一个非常有必要彻底弄清除的概念。大多 IE下的显示错误,就是源于 haslayout。
什么是 haslayout ?
haslayout
是Windows Internet Explorer渲染引擎的一个内部组成部分。在Internet
Explorer中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容。为了调节这两个不同的概念,渲染引擎采用
了 hasLayout 的属性,属性值可以为true或false。当一个元素的 hasLayout
属性值为true时,我们说这个元素有一个布局(layout)
当一个元素有一个布局时,它负责对自己和可能的子孙元素进行尺寸计算和定位。简单
来说,这意味着这个元素需要花更多的代价来维护自身和里面的内容,
而不是依赖于祖先元素来完成这些工作。因此,一些元素默认会有一个布局。当我们说一个元素“拥有layout”或“得到layout”,或者说一个元素
“has layout” 的时候,我们的意思是指它的微软专有属性 hasLayout 被设为了 true
。一个“layout元素”可以是一个默认就拥有 layout 的元素或者是一个通过设置某些 CSS 属性得到 layout
的元素。如果某个HTML元素拥有 haslayout 属性,那么这个元素的 haslayout 的值一定只有 true,haslayout
为只读属性 一旦被触发,就不可逆转。通过 IE Developer Toolbar 可以查看 IE 下 HTML
元素是否拥有haslayout,在 IE Developer Toolbar 下,拥有 haslayout
的元素,通常显示为“haslayout = -1”。
负责组织自身内容的元素将默认有一个布局,主要包括以下元素(不完全列表):
1 body and html 2 table, tr, th, td 3 img 4 hr 5 input, button, file, select, textarea, fieldset 6 marquee 7 frameset, frame, iframe 8 objects, applets, embed
对于并非所有的元素都默认有布局,微软给出的主要原因是“性能和简洁”。如果所有的元素都默认有布局,会对性能和内存使用上产生有害的影响。
如何激发 haslayout?
大部分的 IE 显示错误,都可以通过激发元素的 haslayout 属性来修正。可以通过设置 css 尺寸属性(width/height)等来激发元素的 haslayout,使其“拥有布局”。如下所示,通过设置以下 css 属性即可。
1 display: inline-block 2 height: (任何值除了auto) 3 float: (left 或 right) 4 position: absolute 5 width: (任何值除了auto) 6 writing-mode: tb-rl 7 zoom: (除 normal 外任意值) 8 Internet Explorer 7 还有一些额外的属性(不完全列表): 9 min-height: (任意值) 10 max-height: (除 none 外任意值) 11 min-width: (任意值) 12 max-width: (除 none 外任意值) 13 overflow: (除 visible 外任意值) 14 overflow-x: (除 visible 外任意值) 15 overflow-y: (除 visible 外任意值) 16 position: fixed
其中 overflow-x 和 overflow-y 是 css3 盒模型中的属性,目前还未被浏览器广泛支持。
对于内联元素(默认即为内联的元素,如 span,或 display:inline; 的元素),
• width
和 height 只在 IE5.x 下和 IE6 或更新版本的 quirks 模式下触发 hasLayout 。而对于
IE6,如果浏览器运行于标准兼容模式下,内联元素会忽略 width 或 height 属性,所以设置 width 或 height
不能在此种情况下令该元素具有 layout。
• zoom 总是可以触发 hasLayout,但是在 IE5.0 中不支持。
具
有“layout” 的元素如果同时 display: inline ,那么它的行为就和标准中所说的 inline-block
很类似了:在段落中和普通文字一样在水平方向和连续排列,受 vertical-align
影响,并且大小可以根据内容自适应调整。这也可以解释为什么单单在 IE/Win 中内联元素可以包含块级元素而少出问题,因为在别的浏览器中
display: inline 就是内联,不像 IE/Win 一旦内联元素拥有 layout 还会变成 inline-block。
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
IE6 及更低版本的双空白边浮动 bug
1 bug 修复: display:inline;
IE5-6/win 的 3 像素偏移 bug
1 bug 修复: _height:1%;
E6 的躲躲猫(peek-a-boo) bug
1 bug 修复: _height:1%;