zoukankan      html  css  js  c++  java
  • CSS中文注释引起IE样式失效问题的解决方案

    先看DEMO,在chrome、safari、firefox下,页面显现正常的绿色背景,而在IE下,页面背景为白色。经过分析引起的原因是:

    1、HTML页面编码与CSS编码不同(DEMO中HTML为gbk,CSS为utf-8)

    2、CSS文件中未指定@charset头声明,导致IE默认使用页面编码来解码CSS文件(DEMO中IE浏览器使用gbk来解码一个utf-8的CSS文件)

    3、中文注释中的汉字为奇数个数时,会与结尾的“*/”组合成新的合法字符,导致注释未能正确关闭,造成紧跟其后的样式被自动注释,从而引起样式失效。

    例如,该DEMO中CSS代码为

    /*叶落花*/
    body{background-color:green;}

    如果你问我为什么IE中会有这个问题,kevinxue告诉过我,经研究表明“用IE的人会变蠢”……(IE同学蹲地下默默画圈:其实safari4的早期版本中也存在这个BUG- -!)。

    解决方案有以下几种:

    • 方案一:在中文注释两边加空格(其实只用在右侧加空格),例如 /*叶落花*/改为/* 叶落花 */。或者通过css压缩工具删除所有注释。
    • 方案二:将CSS编码与HTML页面编码统一(DEMO里将CSS另存为GBK格式即可),主要看实施起来是否方便了。
    • 方案三:在CSS文件头部增加@charset的声明,明确告诉浏览器文件编码是什么。

    基于方案三,我写了个python的命令行小工具,取名叫utf8css,它的作用是:

    • 将指定目录中的所有CSS文件(包括子目录),转码为utf-8编码
    • 同时为CSS增加@charset “utf-8″的头部
    • 该脚本已经过Win7与Mac的测试,支持SVN只读文件的修改

    如果你的CSS原本就是utf-8编码并且已经包含@charset头,则不会做任何改动。如果你问我为何要转utf-8而不是转成gbk,你去看看为啥我这么简单的DEMO还要用PHP来写就知道了,简单的来说,更洋气~

    有装python的同学,可以先安装下chardet模块(据说该模块是作者是从firefox的自动编码检测模块中移植过来的,所以知道为什么firefox没有这个BUG了吧……),然后下载utf8css的python源码使用。没有python的同学,直接下载绿色版zip包即可在windows下使用。这里有张运行示意图

    接下来会分析下:为何奇数汉字会造成解码出错呢?有兴趣的同学可以继续往下看。

    首先得从文件编码说起,不太了解的同学先google一下gbk与utf-8编码的区别吧,这里直接引用其中相关的部分:

    GBK的文字编码是双字节来表示的,即不论中、英文字符均使用双字节来表示。UTF-8编码则是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码。

    以汉字“叶”字为例:

    其unicode编码为 \u53f6 ,utf-8编码为\xe5\x8f\xb6,存储空间占用3个字节,gbk编码为\xd2\xb6,存储空间占用2个字节。

    如果将utf-8编码当做gbk编码来做unicode解码(这就是DEMO中的CSS在IE中所发生的悲剧),则会因为字节数不为偶数,而发生解码异常(前面说的gbk编码是双字节的),如果抑制异常,则会将utf-8编码中最后一个字节码(“\xb6”)忽略掉,并将其剩余部分(\xe5\x8f)转为新的unicode码,即\u9359 。这个新的字符是什么?在firebug console中,敲上一句“s = “\u9359″”得到“鍙”字,不知道怎么读。总之,长的就是一副乱码相- -!

    以上推论源于python GUI中的实验,见截图:

    可以看到DEMO中的注释“/*叶落花*/”被IE解码过之后的unicode为:“/*\u9359\u60f0\u60e4\u947a/”,在firebug里看看是什么?

    /*鍙惰惤鑺/

    长得就是一副乱码相,更重要的是注释结尾的“*”被转丢了,从而导致其后的样式被注释掉失效

    事情发生的经过是,注释中的三个utf-8汉字占用了 3×3=9个字节,而gbk要求每个字符为2个字节,即总数需要为偶数。因此IE将其后占用1个字节的utf-8字符“*”,与前面的9个字节加在一起,当成10个字节的gbk字符进行转码。但很显然“花”的第三个字节“\x8a”与单字节“*”一起,连乱码都组合成不了。因此最后得到的乱码字数为 (3×3+1)/2 -1 = 4。

    讲到这里基本就全都明了了,“至于你信不信,我反正信了”。留下一个小练习:

    如果CSS中的注释改为“/*叶落花开*/”,那么得到的乱码是什么,是否会导致样式失效?

    欢迎关注我的微信公众号「猫哥学前班」

  • 相关阅读:
    LeetCode 79. 单词搜索
    LeetCode 1143. 最长公共子序列
    LeetCode 55. 跳跃游戏
    LeetCode 48. 旋转图像
    LeetCode 93. 复原 IP 地址
    LeetCode 456. 132模式
    LeetCode 341. 扁平化嵌套列表迭代器
    LeetCode 73. 矩阵置零
    LeetCode 47. 全排列 II
    LeetCode 46. 全排列
  • 原文地址:https://www.cnblogs.com/kaiye/p/3039045.html
Copyright © 2011-2022 走看看