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

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

转载于:https://www.cnblogs.com/tnnyang/p/4175690.html

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

  1. 关于ITSS,你可能不知道的那些事儿~

    ITSS信息技术服务运行维护标准符合性认证在市场上已经是非常普遍了,那么关于ITSS认证你又了解多少呢?下面小编跟大家说说关于ITSS认证,你可能不知道的那些事! 1.ITSS体系适用于哪些对象? ① ...

  2. swift与OC之间不得不知道的21点

    2019独角兽企业重金招聘Python工程师标准>>> swift与OC之间不得不知道的21点 原文  http://www.cnblogs.com/dsxniubility/p/4 ...

  3. String.split()方法你可能不知道的一面

    String.split()方法你可能不知道的一面 一.问题 java中String的split()是我们经常使用的方法,用来按照特定字符分割字符串,那么我们看以下一段代码: public void ...

  4. 14个你可能不知道的JavaScript调试技巧

    以更快的速度和更高的效率来调试JavaScript 熟悉工具可以让工具在工作中发挥出更大的作用.尽管江湖传言 JavaScript 很难调试,但如果你掌握了几个技巧,就能用很少的时间来解决错误和bug ...

  5. 关于 NIO 你不得不知道的一些“地雷”

    转载自 关于 NIO 你不得不知道的一些"地雷" 本文是笔者在学习NIO过程中发现的一些比较容易让人忽略的知识的一个总结,而这些让人忽略的小细节恰恰是NIO网络编程中必不可少.虽然 ...

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

    转http://www.cnblogs.com/zhijianliutang/p/4100103.html 前言 本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的 ...

  7. axure中出现小手_你所不知道的15个Axure使用技巧

    Axure 6.5已于4月18日发布,可直到上周我才发现,于是赶紧下载升级.等待下载的过程中,闲来无聊跑去看了Axure的版本历史,又浏览了一下官方的使用教程,忽然发现Axure竟如此博大精深,自己平 ...

  8. 关于多线程编程您不知道的 5 件事 有关高性能线程处理的微妙之处

    虽然很少有 Java™ 开发人员能够忽视多线程编程和支持它的 Java 平台库,更少有人有时间深入研究线程.相反地,我们临时学习线程,在需要时向我们的工具箱添加新的技巧和技术.以这种方式构建和运行适当 ...

  9. android 开源 高斯模糊_Android高斯模糊你所不知道的坑

    原标题:Android高斯模糊你所不知道的坑 本文作者 作者:mandypig 链接: https://www.jianshu.com/p/d29841b1a4d5 本文由作者授权发布. 如果你想了解 ...

  10. 关于ERP系统,你可能不知道的10件事

    谈到ERP系统,大多数人只是考虑ERP日常管理的核心功能,即财务.销售.采购.库存.生产和分销.保持对这些关键领域的控制对任何企业的成功都是不可或缺的.但这些只是冰山一角,如果深入挖掘ERP系统,你可 ...

最新文章

  1. R 循环中将变量作为对象名
  2. 学习笔记--Spark
  3. android开发 获取父控件的高宽
  4. html访问java接口出现缓存_一个牛逼的多级缓存实现方案
  5. 淘宝应对双11的技术架构分析
  6. 江西理工大学 微型计算机原理,江西理工大学-微机原理考试(wenwei)作业.docx
  7. Maven构建项目 — 知识点梳理
  8. adb命令查看手机电量_desired Capabilities和aapt命令查看手机包信息
  9. ppocr 源码阅读:ppocr.modeling.architecures 之build_model模块
  10. 溢出植入型木马(后门)的原型实现 作者:FLASHSKY(原创)
  11. 低代码平台对程序员产生的内卷,零代码、低代码系列之一「对于零代、低代码平台的思考」
  12. 怎样用html制作歌词字幕,爱剪辑可以制作歌词字幕吗 教你用爱剪辑加歌词字幕的方法--系统之家...
  13. 关于线程中断thread interrupt
  14. Holder不等式的证明
  15. 计算机考试 办公自动化,计算机等级考试,办公自动化考试试题
  16. j1_12_01.实现手机号计数功能关键算法.传入字符串数组,获取符合手机号格式的字符串.从键盘接收一行字符串,字符串中只包含数字和空格,统计其中所有的手机号码数量。
  17. 大型智慧校园系统源码 智慧校园源码 Android电子班牌源码
  18. 关系型数据库和非关系型的区别
  19. vue中打开一个新页面
  20. html文字段落分割,P段落标签

热门文章

  1. HTML PROGRESS 中显示百分比,在ProgressBar控件中显示进度百分比
  2. 简单的事情搞复杂:挂个版本到网站,拖了几个月还没做
  3. BAT中删除整个目录的办法
  4. 全网首发:WINDOWS某些文件夹,提供管理员权限后也无法删除,正确解决办法
  5. 分析一个JDK卡死问题,还真有点麻烦
  6. NoSuchMethod: ByteBuffer.position(I)
  7. 把c的char数组转换为python image的代码
  8. 上海项目危机经历与感想
  9. X86栈切换,任务切换
  10. allure 测试报告本地打开_自动化测试报告太丑?信息实用的Allure Report测试报告拯救你...