Goodbye to CSS Hack

看看下面这段代码,是否倍感亲切但又觉得很陌生呢:

.test {
    background-color: black; /* firefox, opera, ie8 */
    [;background-color: green;] /* safari, chrome */
    *background-color: blue; /* ie7 */
     _background-color: red; /* ie6 */
}
html*~/**/body .test {
    border: 5px solid red; /* ie8 */
}

随着浏览器的更新换代,CSS Hack 变得越来越诡异和不可靠了-.-

相对来说,IE 的条件注释是值得信赖的:

<!--[if lt IE 7 ]><body class="ie6"><![endif]-->
<!--[if IE 7 ]><body class="ie7"><![endif]-->
<!--[if IE 8 ]><body class="ie8"><![endif]-->>
<!--[if !IE]>--><body><!--<![endif]-->

<style type="text/css">
    body.ie6 .test { background-color: blue }
    body.ie7 .test { background-color: red }
    body.ie8 .test { background-color: green }
</style>

注意,上面的代码虽然也是 hack,但大大简化和规范了 css hack 的写法。

最近看 ExtCore 3.0 的代码,发现 Ext 初始化时会自动给 body 添加浏览器信息:

//Initialize doc classes
(function(){

    var initExtCss = function(){
        // find the body element
        var bd = document.body || document.getElementsByTagName('body')[0];
        if(!bd){ return false; }
        var cls = [' ',
                Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
                : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
                : Ext.isOpera ? "ext-opera"
                : Ext.isWebKit ? "ext-webkit" : ""];

        if(Ext.isSafari){
            cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
        }else if(Ext.isChrome){
            cls.push("ext-chrome");
        }

        if(Ext.isMac){
            cls.push("ext-mac");
        }
        if(Ext.isLinux){
            cls.push("ext-linux");
        }
        if(Ext.isBorderBox){
            cls.push('ext-border-box');
        }
        if(Ext.isStrict){ // add to the parent to allow for selectors like ".ext-strict .ext-ie"
            var p = bd.parentNode;
            if(p){
                p.className += ' ext-strict';
            }
        }
        bd.className += cls.join(' ');
        return true;
    }

    if(!initExtCss()){
        Ext.onReady(initExtCss);
    }
})();

比如在 IE8 下,会添加以下信息:

将浏览器信息添加到 body 和 html 上后,我们书写 CSS Hack 就会变得很容易了。

通过 JS 添加浏览器信息,需要将 JS 放在头部执行,以确保渲染前就添加好。另外,对于不支持 JS 的用户代理,此方法无效。

还有一个方案是在服务器端处理,比如 browscap 方案。优点的是没有 JS 方案的缺点,缺点是遇上 proxy cache 就不准确了。

个人觉得 JS 方案可行。因为禁用 JS 的浏览器用户,自身已是高手,不用我们担心。对于不支持 JS 的用户代理,比如手机等浏览器,则有对应的 WAP 版本给用户使用。这样,我们可以:

  1. 在 head 部分加载一个非常小巧精简的 js,该 js 在 body 可用时,能立刻给 body 添加浏览器信息。
  2. 在 css 里,通过body.ie6 .test { ... }来书写 css hack

这样,无论浏览器如何更新换代,我们都不必去记忆或发掘那一堆诡异的 css hack 的写法了。

Goodbye to CSS Hack

相关文章:

你感兴趣的文章:

标签云: