关于HTML条件注释你可能不知道的一些事儿

关于HTML条件注释你可能不知道的一些事儿,第1张

概述最近经常看到类似这样的HTML代码片段,很多前端开发人员应该都熟悉:1 <!--[if lt IE 7]> <html class="ie6"> <![endif]-->2 <!--[if IE 7]> <html class="ie7"> <![endif]-->3 <!--[if IE 8]> <html clas…

最近经常看到类似这样的HTML代码片段,很多前端开发人员应该都熟悉:

1 <!--[if lt IE 7]>      <HTML class="ie6"> <![endif]-->2 <!--[if IE 7]>         <HTML class="ie7"> <![endif]-->3 <!--[if IE 8]>         <HTML class="ie8"> <![endif]-->4 <!--[if gt IE 8]><!--> <HTML>         <!--<![endif]-->

  这段代码包含了一些条件注释,它会根据浏览器的不同选择性地给<HTML>标记添加(或不添加)一个包含浏览器版本信息的class属性。具体来说,对于IE5-ie8,<HTML>标记会增加一个class属性,属性值由IE的版本来决定。对于IE9、较IE9更高的IE版本以及非IE浏览器,<HTML>保持原样。这样,我们就可以针对IE5-ie8这些老式浏览器来编写只对它们生效的CSS代码,比如:

1 .foo { color: red;}2 .ie6 .foo { color: yellow;}3 .ie7 .foo { color: blue;}

进一步地,我们就可以避免类似这样的CSS Hack:

1 /***** 选择器(Selector) Hacks ******/2 .foo { color: red;}3 * HTML .foo { color: yellow; }  4 *:first-child+HTML .foo { color: blue; } 5 6 /***** 属性(Attribute) Hacks ******/7 .foo { color: red; *color: blue;  _color: yellow;}

  使用“HTML条件注释”来避免CSS Hack,这是一种目前比较流行而且比较安全稳定的技术。这种技术的代码有很多版本,再介绍一个比较有意思的,来自于HTML5 Boilerplate:  

1 <!--[if lt IE 7]>      <HTML class="lt-IE9 lt-ie8 lt-ie7"> <![endif]-->2 <!--[if IE 7]>         <HTML class="lt-IE9 lt-ie8">        <![endif]-->3 <!--[if IE 8]>         <HTML class="lt-IE9">               <![endif]-->4 <!--[if gt IE 8]><!--> <HTML>                              <!--<![endif]-->

   文章写到这里,我感觉,写了这么多,全是大家可能都知道的事儿。其实,这篇文章的主题,不是讨论条件注释和CSS Hack孰优孰劣,也不是讨论哪种条件注释方案最好,我想讲一些条件注释技术实现代码的细节。

  我们聚焦文章的第一段示例代码。看这段代码的第一行:

<!--[if lt IE 7]> <HTML class="ie6"> <![endif]-->

就算我们没有条件注释的知识,凭字面我们也能大概猜出这行代码的作用:在ie6或更低版本的浏览器中,这行注释会被解析成<HTML class="ie6">。在其他IE浏览器(ie7-9)中,它会被解析成空。在非IE浏览器中,毫无疑问,它会被当做我们所熟知的一般HTML注释,它会被忽略。事实上,浏览器的确是这样做的。

  在IE条件注释的概念体系中,一共有两种条件注释类型。这种条件注释的类型被称作downlevel-hIDden。它的语法是这样的:

<!--[if Expression]> HTML <![endif]-->

语法的细节说明可以查看文章结尾的参考资源。

  在将要讨论语法怪异的第四行代码之前,让我们先思考一个问题。凭借现有的HTML条件注释的特性,我们能够实现“IE9、较IE9更高的IE版本以及非IE浏览器中,<HTML>保持原样”这一目标吗?

1 <!--[if gt IE 8 | !IE]> <HTML> <![endif]-->2 ...3 </HTML>

这样可以吗?不可以。IE9浏览器中,注释条件为真,代码会解析为<HTML>。但是,IE10以及非IE浏览器中,这行代码会被忽略,这会导致HTML文档缺少起始<HTML>标记。从高亮的HTML上,我们可以明显地看出来。特别强调一下,微软已经宣布,IE10不再支持条件注释。

  凭借现有的HTML条件注释的特性,我们没有办法实现我们的目标。怎么办?

  在IE条件注释的概念体系中,还有另外一种条件注释类型叫downlevel-revealed,它的语法(具体语法细节请查看文章结尾的参考资源)是这样的:

<![if Expression]> HTML <![endif]>

很幸运,我们可以利用downlevel-revealed类型的条件注释来实现之前的目标。

<![if gt IE 8]> <HTML> <![endif]>

  对于这行代码浏览器的解析是这样的:在IE9中,浏览器会识别出这是一段条件注释,并且条件为真,所以这段代码会解析为<HTML>。在ie8-IE5中,注释的条件为假,故解析为空。在IE10以及非IE浏览器中,<![if gt IE 8]> 以及 <![endif]>会被当做无法识别的标签,整条代码最终被解析为<HTML>。感谢微软,我们的目标实现了。

  但是,这段代码,是无法通过(X)HTML验证的。为了能够通过通过(X)HTML验证,我们可以使用一种改进的语法,代码可以修改为:

<!--[if gt IE 8]--> <HTML> <!--[endif]-->

 我们增加了4个 --,这使得代码看起来非常的怪异,这与downlevel-hIDden类型有点差别,但它能被IE5-IE9识别为条件注释别并处理。对于改进过的代码,IE5-ie8的解析方式不变。IE10以及非IE浏览器会把<!--[if gt IE 8]-->  <!--[endif]-->当作一般注释来解析,最终结果不变。但是,IE9出问题了:注释条件仍然为真,解析结果却变成了--> <HTML>。我们再次改进一下语法,代码可以修改为:

<!--[if gt IE 8]<!--> <HTML> <!--[endif]-->

 我们只是增加了一个 <! 。 对于再次改进过的代码,IE5-ie8的解析方式不变。IE10以及非IE浏览器会把<!--[if gt IE 8]<!-->  <!--[endif]-->当作一般注释来解析,最终结果不变。IE9的问题被修复了。

   至此,我们所得到这行代码,其实就是示例中的第四行代码。

  嗯,这行怪异的代码的由来原来是这样的。

参考资源About Conditional Comments HTML5 Parsing in IE10 总结

以上是内存溢出为你收集整理的关于HTML条件注释你可能不知道的一些事儿全部内容,希望文章能够帮你解决关于HTML条件注释你可能不知道的一些事儿所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1020939.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存