Internet Explorer 7中的层叠样式表兼容性

Markus Mielke
Dave Massy
Microsoft Corporation(本文转自MSDN)

本页内容
简介 简介
认真地考虑兼容性 认真地考虑兼容性
针对IE7中的问题页面 针对IE7中的问题页面
我的页面被破坏了,我应该做什么? 我的页面被破坏了,我应该做什么?
我们一直在关注兼容性的需求 我们一直在关注兼容性的需求

简介

Internet Explorer 7包含了许多有关于层叠样式表(CSS)解析与呈现的改进。这些改进意在提高Internet Explorer解释层叠样式表的一致性,以达到W3C的推荐的标准,同时为开发者提供一个可以依赖的功能集合。

在某些情况下,当使用与IE6不兼容的方式来呈现现有的内容时,这些改变可能会产生影响。这种现象常见于在IE7中将元素移动到纸张的不同区域或者出现重叠内容时。这些问题通常是由于为了解决在IE6的strict模式下出现的小错误,而使用了特殊的CSS内容(例如常见的”hacks”或者filters)而造成的。在这篇文章中我们将讨论为什么因为CSS的升级会导致页面被破坏以及去解决导致这些结果的问题的最好方法。

认真地考虑兼容性

在Internet Explorer团队中,我们认为在推出一个可供开发人员构建优秀解决方案的平台时,兼容性是很重要的一部分。我们需要在新的版本中继续显示已经存在的内容,而同时还要增加和改进新的功能。为了实现这个表面看上去很矛盾的目标,我们参考了quirks and strict mode。IE6中引入了对strict模式的支持,这个内容被HTML页面开始部分的一个声明决定。在quirks模式中,我们可以确保兼容性,所以已经存在的内容可以像在以前的IE版本中一样被呈现。而在strict模式中,我们的工作是向W3C推荐的方向去改进一致性,在这个过程中,包含了有可能影响现有内容的改变。

在Internet Explorer6中出现的和CSS解析与显示相关的许多问题在很多网站上都有很好的文档来说明,例如www.quirksmode.orgwww.positioniseverything.net

在IE中使用CSS的情况下,我们相信我们修复出现在IE6 strict模式中的问题是正确的选择,即使这会导致在页面呈现上发生一些改变。

针对IE7中的问题页面

如果当一个页面在Internet Explorer7中呈现时不同于以前版本的IE,第一步要做的就是诊断错误的原因,以便我们可以快速找到有效的解决办法。

User Agent Strings以及浏览器检测

在着眼于IE7中的CSS的带来的影响之前,我们应该首先排除一个常见的兼容性问题。一些站点基于用来访问它们的浏览器的类型和版本来提供不同的内容,这些站点不知道将被IE7访问。当检测User Agent String时会出现这个问题,更多的细节可以在Detecting Internet Explorer More Effectively找到。

影响CSS Box Model的XML Prolog问题

XML prolog对正在使用的XML版本进行说明,当与XHTML联合时常被使用。正向上面解释的,我们在IE6中引入了一个开关来在quirks模式与strict模式间进行切换。这个开关必须放在页面的第一行。不幸的是,XML prolog也需要这个位置,而且大多数使用XML prolog的作者会将它放在strict模式开关前面。这会导致IE6忽略作者的意图并且IE6会采用quirks模式来呈现页面,而不是strict模式。我们在IE7中修复了这个问题。现在,可以将XML prolog紧跟strict模式开关来正确的显示XHTML页面。可是一些页面在呈现它们的内容时,默认认为IE不处在strict模式(即使IE应该符合HTML spec)。由于XML prolog导致的呈现问题很容易判别:打开页面的查看源文件,找到最前面的两行。如果看到XML prolog和一个<!DOCTYPE>限定,并且页面呈现时出现问题,那么大多数情况下作者需要更新页面内容了。

Box Model的改变

在IE7中,为了适应CSS2.1 box model,我们修改了溢出的行为。溢出是一种方法,用来描述当一个块元素的内容溢出它的区域时,这些内容是否被省略。默认是可见的。这个值(可见)表明内容不被省略,也就是,它有可能呈现在区域以外。过去的IE不支持这个行为。内容总是需要适合区域的大小。想象一个宽和高都是100px的区域,如果内容小于100px,那么没有问题。如果内容超过了尺寸,我们需要自动增长区域大小来适合内容。要想演示这个行为,请看下面的代码示例。

<style type="text/css">
            div        { width : 100px; height: 100px; border: thin solid red;}
            blockquote { width: 125px; height: 100px;
            margin-top: 50px; margin-left: 50px;
            border: thin dashed black}
            cite       { display: block;
            text-align: right;
            border: none}
            p          { margin: 0;}
            </style>
            <div>
            <blockquote>
            <p>some text long enough to make it interesting.</p>
            <cite>- anonymous</cite>
            </blockquote>
            </div>
            

下面的图片说明了这个示例代码在IE6中的呈现情况。

.

与其对比,下面的图片说明了同样的代码在IE7中的呈现情况。

.

正如你所见,<blockquote>的内容在呈现时超出了其父标签<div>(红色边框的区域)的边界。

CSS Filters

虽然像CSS一样的标准已经存在,但是并不保证所有的浏览器用同样的方式呈现页面。这些标准可能含有未经定义的部分,并不是所有的组件等会被所有的浏览器去执行,并且已知的执行也可能存在问题。CSS标准并不提供一个方法去指定一个特定的浏览器版本,所以网络开发者社区开发了CSS filter(也被称作”CSS hacks”)。这些filter利用浏览器的问题或者未执行的特性来隐藏针对特殊浏览器的CSS样式规则。当我们修复了这些问题并且改进了CSS支持后,一些CSS filter将不再可用。

如果你使用这些filters,你应该了解它们的效果。这个可以帮助你做出针对以后版本的Internet Explorer和其它浏览器的更有效的并且适应改进后的CSS的设计。

在IE7中,我们修改了许多潜在解析错误,这些错误有可能会阻止下面的filter在以前的IE版本中正常工作。如果你的页面中包含这些filter,请去除或者更换它们。

*HTML filter

这个CSS filter基于一个解析错误。它被用于显示排除内容。这些内容将被Internet Explorer7和以后的版本忽略。

/* The following rules used to apply only to
            IE but now get ignored by IE7 and higher */
            * html{
            }
            * html body{
            }
            * html .foo{
            }
            

下划线filter

这个CSS filter基于一个解析错误。它被用来显示被排除的属性。这个内容现在被Internet Explorer以及之后的版本认为是一个自定义属性。自定义属性意味着它仍然可以使用,但是并不默认就拥有一个值。

/* The following rule used to apply min-height
            to browser who understand this property and
            height to IE.  In IE7, _height will be treated
            as a custom property (no height will be applied) */
            .myclass {
            min-height: 300px;
            _height: 300px;
            ...
            }
            

/**/注释filter

这个CSS filter基于一个解析错误。它被用来在strict模式下隐藏属性(这个filter在quirk模式下不起作用)。在Internet Explorer7中,这个属性可以被解析和使用。

/* The following rule used to hide the height
            property to Internet Explorer. In IE7, the
            value will be applied */
            .myclass {
            height/**/: 300px;
            ...
            }
            

"html > body" 子节点 filter

这个CSS filter基于Internet Explorer中一个以前的未被执行的特性。它被用来隐藏声明排除。从版本7开始,Internet Explorer可以在声明中使用属性。

注意:当被用来检测浏览器或者浏览器的版本时,依赖子节点的CSS样式规则仅被认为是CSS filter。

/* The following rule used to hide the height
            property to Internet Explorer. In IE7, the
            value will be applied */
            html > body {
            height: 300px;
            ...
            }
            

"head + body" 相邻节点 filter

这个CSS filter基于Internet Explorer中一个以前的非未被执行的特性。它被用来隐藏声明排除。从版本7开始,Internet Explorer可以在声明中使用属性。

注意:当被用来检测浏览器或者浏览器的版本时,依赖相邻节点的CSS样式规则仅被认为是CSS filter。

/* The following rule used to hide the height
            property from Internet Explorer. In IE7,
            the value will be applied */
            Head + body {
            height: 300px;
            ...
            }
            

"head:first-child + body" 第一子节点和相邻节点 filter

这个CSS filter基于Internet Explorer中两个以前的非未被执行的特性(:first-child伪类和相邻节点)。它被用来隐藏声明排除。从版本7开始,Internet Explorer可以在声明中使用属性。

注意:当被用来检测浏览器或者浏览器的版本时,将:first-child节点和相邻节点连接的CSS样式规则仅被认为是CSS filter。

/* The following rule used to hide the height
            property from Internet Explorer. In IE7,
            the value will be applied */
            head:first-child + body {
            height: 300px;
            ...
            }
            

我的页面被破坏了,我应该做什么?

这部分内容说明了处理问题时可能的策略。

处理overflow:visible的默认行为

如果没有设置宽和高,那么在你的版面中的区域应该可以像在IE6中一样正常显示(除非太多的词语或者预先的内容可能导致了溢出),这样应该就很好了。

由于新的行为,你的版面在两种情况下有可能被破坏:

1.

已经设置了宽和高,并且没有意识到内容的多少实际上比设置的值要大。

这种情况很好解决。只要了解内容的正确多少(开发人员工具栏上面的尺子可以帮助你),并且为区域制定合适的尺寸。

2.

有需要改变区域大小的动态内容。当动态的插入内容时、或者当没有指定字体大小并且用户修改了它们时,会出现这种情况。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
                        <html>
                        <title>
                        CSS: Overflow:visible and Min/Max
                        </title>
                        <style>
                        .DivClass1
                        {
                        background:orange;
                        width:150px;
                        height:100px;
                        }
                        </style>
                        <body>
                        <div contenteditable=true class=DivClass1>
                        this is a DIV with a fixed width and height
                        of 100 pixels, in IE 6, the height of the DIV will extend to the
                        height of the content. In IE7, the height of the DIV is 100px as
                        specified, but the text overflows outside of the box.
                        </div>
                        </body>
                        </html>
                        

可以使用像IE7一样的现代浏览器中新的min-height属性来改正这个行为。为了确保这些行为在更老的IE中不会发生改变,我们推荐使用条件注释。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
                        <html>
                        <title>
                        CSS: Overflow:visible and Min/Max
                        </title>
                        <!-- Will only be read by IE versions less then IE 7-->
                        <!--[if lt IE 7]>
                        <link rel="stylesheet" type="text/css" href="Demo/iestyles.css" />
                        <![endif]-->
                        <style>
                        .DivClass1
                        {
                        background:orange;
                        width:150px;
                        min-height:100px; // will be ignored by IE6
                        }
                        </style>
                        <body>
                        <div contenteditable=true class=DivClass1>
                        this is a DIV with a fixed width and height
                        of 100 pixels, in IE 6, the height of the DIV will extend to the
                        height of the content. In IE7, the height of the DIV is 100px as
                        specified, but the text overflows outside of the box.
                        </div>
                        </body>
                        </html>
                        

在iestyles.css,应该指定IE6以及一下版本的行为。

.DivClass1
                        {
                        height:100px; // applies only to versions that do not understand min-height
                        }
                        

使用conditional comments是一个简单、可维护的方法,用来将更老的IE版本中的行为从IE7中的更加标准的行为中分离出来。

由于CSS filter的改进而导致的错误页面

如果页面设计在IE7 strict模式下无法正常显示,您下列三个选项:

a.第一,尝试建立标准的、可以跨浏览器使用的设计。通过简化页面、你可以解决这些问题并且减少维修费用。

b.使用条件注释。

c.如果不得不使用CSS filter,考虑那些业可以在以前版本的浏览器上面正常运行的filter。这可以将工作中未来遇到问题的风险降到最低。

使用条件注释

从Internet Explorer 5开始Conditional comments就可用了,并且提供了简单、可维护的方法来检测IE的浏览器类型和版本。因为语法是基于注释的,其它的浏览器只会忽略这种情况。这是一个将*HTML filter替换的好方法。为了保证它是清楚的,我们建议大家使用条件注释来设置一个联接。

<!--[if IE]>
            <link rel="stylesheet" type="text/css" href="iestyles.css" />
            <![endif]-->
            

有效的使用CSS filter

我们已经了解了由于处理浏览器行为的不同而带来的痛处。CSS filter如果和两个指导方针一起使用,那么使用它是很好的。

a.仅考虑面向“老于现在”版本浏览器中的filter,这可以确保您的filter不会在新版本出现时出现问题。有一些filter,例如仅面向IE5.5甚至更早,那么使用起来是安全的。

b.要知道它们是filter。确保在它们出现问题时候,及时进行修复。并提供能够明确标示它们是filter的注释。

我们一直在关注兼容性的需求

我们从开发人员社区了解到,一些反馈一直在要求更符合标准的呈现行为。我们正在处理这些要求,同时也需要考虑用户不想破坏页面的要求。为了找到一个平衡点,我们在IE6中引入了strict模式,使得作者可以进行更加符合标准的页面呈现。在IE7 中,页面作者使用非strict模式(quirks模式)将不会改变行为,并且不会被破坏的CSS filter所影响。在strict模式下,我们已经,并将继续确保改变更加的复合标准。作为副产品,当我们的改变更加符合标准时,在旧的strict版本中的内容可能被破坏。这会发生在被破坏的CSS filter上。这依赖于执行特定的行为,而不是CSS规范。

我们希望这篇文章可以帮助大家理解IE7中CSS兼容性问题的根本原因,并且提供足够的建议帮助您减少问题。


posted @ 2006-12-16 12:01  萍踪侠影  阅读(843)  评论(0编辑  收藏  举报