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

最近经常看到类似这样的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的问题被修复了。

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

时间: 2024-10-10 06:21:20

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

您可能不知道的CSS元素隐藏“失效”以其妙用

by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=2191 一.CSS元素隐藏 在CSS中,让元素隐藏(指屏幕范围内肉眼不可见)的方法很多,有的占据空间,有的不占据空间:有的可以响应点击,有的不能响应点击.后宫选秀——一个一个看. { display: none; /* 不占据空间,无法点击 */ } { visibility: hidden; /* 占据空间,无法点击

您可能不知道的CSS元素隐藏“失效”以其妙用——张鑫旭

一.CSS元素隐藏 在CSS中,让元素隐藏(指屏幕范围内肉眼不可见)的方法很多,有的占据空间,有的不占据空间:有的可以响应点击,有的不能响应点击.后宫选秀——一个一个看. { display: none; /* 不占据空间,无法点击 */ } { visibility: hidden; /* 占据空间,无法点击 */ } { position: absolute; clip:rect(1px 1px 1px 1px); /* 不占据空间,无法点击 */ } { position: absolut

你所不知道的SQL Server数据库启动过程(用户数据库加载过程的疑难杂症)

前言 本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的一些问题和解决方法,可点击查看,我们此篇主要介绍的是SQL Server启动过程中关于用户数据库加载的流程,并且根据加载过程中所遇到的一系列问题提供解决方案. 其实SQL Server作为微软的一款优秀RDBMS,它启动的过程中,本身所带的那些系统库发生问题的情况相对还是很少的,我们在平常使用中,出问题的大部分集中于我们自己建立的用户数据库. 而且,相对于侧重面而言,其实我们更关注的是我们自己建立的用户数

三剑客老大&quot;awk&quot;名不虚传——你所不知道的awk

三剑客老大"awk"名不虚传 --你所不知道的awk 我们都知道awk做统计非常方便,但是你知道awk也可以用于替换么?我们可以用awk实现sed的功能,甚至比sed更精确(因为可以精确到列). 例如:将配置文件的第5行和第7行注释: [[email protected] ~]# awk 'NR>4&&NR<8{gsub(/^/,"#")}{print NR,$0}' passwd.txt 1  root:x:0:0:root:/root

CSS你可能还不知道的一些知识点--转

作者:软谋教育出处:http://www.cnblogs.com/ruanmou CSS你可能还不知道的一些知识点 一.特殊选择器 1.* 用于匹配任何的标记 2.> 用于指定父子节点关系 3.E + F 毗邻元素选择器,匹配所有紧随E元素之后的同级元素F 4.E ~ F 匹配所有E元素之后的同级元素F 5.名称[表达式] 5.1 E[att] 匹配所有具有att属性的E元素([att]获取所有的定义了att的标签:E[att=val] 匹配所有att属性等于“val”的E元素: 5.2 [at

关于线性模型你可能还不知道的二三事(二、也谈民主)

目录 1 如何更新权值向量?2 最小均方法(LMS)与感知机:低效的民主3 最小二乘法:完美的民主4 支持向量机:现实的民主5 总结6 参考资料 1 如何更新权值向量? 在关于线性模型你可能还不知道的二三事(一.样本)中我已提到如何由线性模型产生样本,在此前提下,使用不同机器学习算法来解决回归问题的本质都是求解该线性模型的权值向量W.同时,我们常使用线性的方式来解决分类问题:求解分隔不同类别个体的超平面的法向量W.不论回归还是分类,都是求解向量W,而求解的核心思想也英雄所见略同:向量W倾向于指向

手机元件你可能不知道的那些事

据消息人士透露,富士康正玩命扩招100,000人力以满足iPhone6的量产需求,与此同时,iPhone6的公关团队又弄丢了工程样机.事实上,这个团队每年都会在iPhone上市前,或在酒吧,或在公园.或在写字楼弄丢一部宝贵的真机.从网络上流传的谍照来看,新一代iPhone势必要拉个大长脸,display尺寸有两个版本,一个是4.7英寸,一个是5.5英寸,严重违反了由果粉提出的"3.5英寸屏幕才是最好看手机"的黄金标准:后置camera由800万像素提升到1000万像素,前置VGA也有2

你所不知道的五件事情--java.util.concurrent(第二部分)

这是Ted Neward在IBM developerWorks中5 things系列文章中的一篇,仍然讲述了关于Java并发集合API的一些应用窍门,值得大家学习.(2010.06.17最后更新) 摘要:除了便于编写并发应用的集合API外,java.util.concurrent还引入了其它的预置程序组件,这些组件能辅助你在多线程应用中控制和执行线程.Ted Neward再介绍了五个来自于java.util.concurrent的Java编程必备窍门. 通过提供线程安全,性能良好的数据结构,并发

一些你可能不知道的JavaScript知识(知道了之后可是大大有用的哦)

1.!!将一个值方便快速转化为布尔值 console.log( !!window===true ); 2.不声明第三个变量实现交换 var a=1,b=2; a=[b,b=a][0];//执行完这句代码之后 a的值为2 b的值为1了 3.&&和||的用法 (学会了立马感觉高大尚了吧) 用代码说话吧 var day=(new Date).getDay()===0; //传统if语句 if (day) { alert('Today is Sunday!'); }; //运用逻辑与代替if da