锋言锋语

NferZhuang的自留地

一个由 linear-gradient 引起的 bug

CSS3 定义了两种类型的渐变(gradients):

  • 线性渐变(Linear Gradients)- 向下/向上/向左/向右/对角方向
  • 径向渐变(Radial Gradients)- 由它们的中心定义

这里记录一个由linear-gradient相关的bug。

问题描述

有下述一段代码:

#grad1 {
    height: 200px;
    /* Safari 5.1 - 6.0 */
    background: -webkit-linear-gradient(left, #5206d8, #d658ff);
    /* Opera 11.1 - 12.0 */
    background: -o-linear-gradient(left, #5206d8, #d658ff);
    /* Firefox 3.6 - 15 */
    background: -moz-linear-gradient(left, #5206d8, #d658ff);
    /* IE 11 */
    background: -ms-linear-gradient(left, #5206d8, #d658ff);
    /* 标准的语法 */
    background: linear-gradient(left, #5206d8, #d658ff);
}

这一段代码是兼容写法,考虑了很多低版本的浏览器,在开发环境下可以正常运行,但是通过 webpack 打包后在正式环境上却没有起作用。

问题分析

先看一下这段代码在 chrome 浏览器上最终的样式结果:

样式结果

可以看到,上述的 css 代码真正有效的是background: -webkit-linear-gradient(left, #5206d8, #d658ff);这一行,而标准的语法的background: linear-gradient(left, #5206d8, #d658ff);却提示格式错误,无法解析。

可以看到,带私有前缀和不带私有前缀的解析规则是不一样的。在 MDN 上有这个语法演变历史的说明。

最终Apple的提案显示,带前缀的语法都使用极坐标定义参数,导致了0deg指向东方。为了与CSS的其他部分保持一致,标准将0deg指向北方。

因此,上述的代码如果使用角度值来重写的话,代码如下:

#grad1 {
    height: 200px;
    background: -webkit-linear-gradient(0deg, #5206d8, #d658ff);
    background: linear-gradient(90deg, #5206d8, #d658ff);
}

可以看到,带前缀写法和不带前缀写法在处理渐变角度上是有差异的。

如果使用leftright等简写方位时,带前缀写法和不带前缀写法同样是有差异的:

在一项新的语法中,这个问题被修正。它仍然使用方向关键字,但是在关键字之前增加关键字 to 。这项语法被添加到CSS Images Values and Content Replacement Level 3 draft in 2011-09-08。

就是标准写法是需要加上to关键字的,而私有前缀为了保持和以前兼容,还是使用不带to关键字的,等价代码如下:

#grad1 {
    height: 200px;
    background: -webkit-linear-gradient(left, #5206d8, #d658ff);
    background: linear-gradient(to right, #5206d8, #d658ff);
}

解决方案

使用 webpack 打包的话,可以使用 postcss loader 的 autoprefixer 插件,在写代码的时候只关心标准写法,剩下的浏览器私有前缀兼容则交由 autoprefixer 插件自动补全。

#grad1 {
    height: 200px;
    background: linear-gradient(to right, #5206d8, #d658ff);
}
文 / nfer
LEAVE A REPLY

loading