CSS Hack

什么是 CSS Hack

CSS Hack 的分类

  1. CSS 属性前缀法:利用不同浏览器对某些 CSS 属性识别的差异,添加浏览器前缀实现 hack。比如 -webkit--moz--ms--o- 等。

    .box {
      -webkit-transform: rotate(30deg);
      -moz-transform: rotate(30deg);
      -ms-transform: rotate(30deg);
      transform: rotate(30deg);
    }
    
  2. IE 条件注释法:IE 支持根据版本对 CSS 进行条件注释解析,可以针对 IE 添加样式。

    <!--[if IE 8]>
    <link rel="stylesheet" type="text/css" href="ie8.css">
    <![endif]-->
    
  3. 选择器 hack:不同浏览器对某些选择器的识别支持不同,比如 IE6-7 不识别 :first-child 选择器。

    .box :first-child {
      color: red;
    }
    
    body:nth-of-type(1) .iehack {
      color: #f00; /* 对 Windows IE9/Firefox 7+/Opera 10+/所有 Chrome/Safari 的 CSS hack,选择器也适用几乎全部 Mobile/Linux/Mac browser*/
    }
    
  4. CSS 属性值 hack:不同浏览器对应某些属性值解析不同,比如 IE6 对 display:inline-block 不识别,但识别 _display:inline; zoom:1

    .box {
      display: inline;
      zoom: 1;
    }
    
    .element {
      background-color: orange; /* all IE/FF/CH/OP*/
    }
    .element {
      *background-color: blue; /* IE6+7, doesn't work in IE8/9 as IE7 */
    }
    .element {
      _background-color: red; /* IE6 */
    }
    .element {
      background-color: green\0; /* IE8+9+10  */
    }
    :root .element {
      background-color: pink\0;
    } /* IE9+10 */
    
  5. CSS 属性 hack:某些属性不同浏览器支持不同,比如 IE6-7 支持 _width,Chrome 支持 -webkit-text-size-adjust

    .hacktest {
      background-color: blue; /* 都识别,此处针对 firefox */
      background-color: red\9; /*all ie*/
      background-color: yellow\0; /*for IE8/IE9/10 最新版 opera 也认识*/
      +background-color: pink; /*for ie6/7*/
      _background-color: orange; /*for ie6*/
    }
    
  6. 媒体查询 Hack:使用媒体查询可以根据屏幕宽度或其他条件应用不同的样式,

    @media screen and (min-width: 0) {
      .hacktest {
        background-color: black\0;
      } /*opera*/
    }
    @media screen and (min-width: 0) {
      .hacktest {
        background-color: purple\9;
      } /*  for IE9/IE10  PS:国外有些习惯常写作\0,根本没考虑 Opera 也认识\0的实际 */
    }
    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
      .hacktest {
        background-color: green;
      } /* for IE10+ 此写法可以适配到高对比度和默认模式,故可覆盖所有 ie10 的模式 */
    }
    @media screen and (-webkit-min-device-pixel-ratio: 0) {
      .hacktest {
        background-color: gray;
      }
    } /*for Chrome/Safari*/
    

CSS Hack 的缺点

  1. 不优雅:CSS Hack 需要针对不同浏览器编写不同的样式代码,不仅增加了代码量,也使代码变得不够简洁和优雅。
  2. 维护困难:针对不同浏览器编写 hack 代码会使维护变得非常困难。代码变得复杂且冗余,不利于后期的修改和扩展。
  3. 不稳定,容易被新浏览器覆盖:针对旧浏览器的 hack 可能被新浏览器的标准特性和功能覆盖,导致 hack 失效。需要持续更新 hack 代码。
  4. 难理解,开发体验较差:编写及维护 hack 代码的过程令开发者感到痛苦,开发体验较差。

替代方案

<!DOCTYPE html>
<html>
  <head>
    <style>
      .my-element {
        /* 共用样式 */
        width: 200px;
        height: 100px;
        background-color: lightgray;
      }

      .flexbox-supported .my-element {
        /* 适用于支持 Flexbox 的浏览器 */
        display: flex;
        justify-content: center;
        align-items: center;
      }

      .flexbox-not-supported .my-element {
        /* 适用于不支持 Flexbox 的浏览器 */
        display: block;
        text-align: center;
        line-height: 100px;
      }
    </style>
  </head>
  <body>
    <div class="my-element">This is a flexible element.</div>

    <script>
      function isFlexboxSupported() {
        const element = document.createElement("div");
        element.style.display = "flex";
        return element.style.display === "flex";
      }

      if (isFlexboxSupported()) {
        document.body.classList.add("flexbox-supported");
      } else {
        document.body.classList.add("flexbox-not-supported");
      }
    </script>
  </body>
</html>

样式书写顺序

/* 通用样式 */
.my-element {
  background-color: lightgray;
}

/* IE hack */
* html .my-element {
  background-color: blue;
}