您应该如何为 CSS3 动画中的变换属性添加前缀?

How should you prefix transform properties in CSS3 animations?

我有以下 Sass 的片段,效果很好,但我想知道我是否需要为我的转换属性添加前缀,如果需要,怎么办? (如果不是,为什么不呢?)

@mixin expand-o-band() {
    0%   { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(2); }
}

@-webkit-keyframes expand-o-band { @include expand-o-band(); }
@-moz-keyframes expand-o-band { @include expand-o-band(); }
@-o-keyframes expand-o-band { @include expand-o-band(); }
@keyframes expand-o-band { @include expand-o-band(); }


.circle-thing {
    -webkit-animation: expand-o-band 1.5s infinite; /* Safari 4+ */
    -moz-animation:    expand-o-band 1.5s infinite; /* Fx 5+ */
    -o-animation:      expand-o-band 1.5s infinite; /* Opera 12+ */
    animation:         expand-o-band 1.5s infinite; /* IE 10+, Fx 29+ */
}

请注意,我不是在询问使用自动前缀等工具来为我执行此操作,而是我需要添加哪些内容才能使其与最广泛的浏览器兼容?

鉴于:

Im not asking about using something like autoprefixer

这取决于浏览器和which versions you want to support:

-ms- 可用于 IE9(完全不支持 IE9 以下)但是,动画仅在 IE10+ 中受支持,因此,如果您正在为包含 ms 前缀的变换设置动画是多余的

-webkit- 可用于 Chrome 35、31、Safari 和 android 浏览器

@mixin expand-o-band() {
    0%   { 
       opacity: 1; 
       -ms-transform: scale(1); /* <--- not necessary */
       -webkit-transform: scale(1); 
       transform: scale(1); 
    }
    100% { 
       opacity: 0; 
       -ms-transform: scale(2);  /* <--- not necessary */
       -webkit-transform: scale(2); 
       transform: scale(2); 
    }
}

通常强烈推荐像 autoprefixer 这样的解决方案,因为它们允许您编写干净 CSS 然后明确定义您希望支持的浏览器及其(旧)版本。这样做的好处是你的源代码不太可能包含以后可能与你(和你的最终用户群)无关的项目,并且正确包含正确实现的担忧被抽象化了。

这是标准化功能的供应商前缀变得 极度 问题的情况之一,因为您需要考虑所有不同的前缀 and/or 不带前缀的不同实现不同浏览器不同版本的特性。

真是一口。然后你必须组合这些的各种排列。多么一把.

简而言之,您需要弄清楚每个浏览器的哪些版本需要为每个单独的属性添加前缀,除非您不介意膨胀,否则您需要为各个浏览器应用不同的前缀。幸运的是,出色的最新资源 caniuse.com 使这部分变得非常简单;这是 2D transforms and animations.

的兼容性表

好消息是浏览器在实现转换和动画的稳定(即无前缀)实现方面通常非常一致:

  • IE9 实现了 -ms-transform,并且仅开始在 IE10 中使用 RTM 的稳定无前缀语法以及无前缀转换实现动画。 IE 是唯一在动画中添加前缀转换毫无意义的浏览器,因为除了作为唯一需要转换前缀的浏览器之外,IE9 根本无法识别 CSS 动画。

    当然,这不会阻止您在其他地方使用 -ms-transform 和将动画作为一种渐进增强的形式,但是将其包含在 动画中是没有意义的。此外,您可能已经阅读过 @-ms-keyframes 前缀,但它仅用于 IE10 的预发布版本,该版本早已过期并且将不再 运行。

  • Firefox 早在 3.5 版就发布了 -moz-transform,动画在版本 5 中出现的时间要晚得多,然后在版本 16 中同时删除了两个功能的前缀。

  • 基于 WebKit 的浏览器(包括 Opera 15 及更高版本)如今仍然需要 -webkit- 动画前缀,而转换仅在 Chrome 的最新版本中没有前缀。这两个功能都需要前缀。

  • Opera 12.00 是唯一使用 @-o-keyframes 的版本。 -o-transform 也用到了那个版本。 12.10 删除了两者的前缀,然后它通过移动到版本 15 中的 WebKit 直接回归到再次需要这两个前缀,如上所述。

不幸的是,由于您的 CSS 动画中有所有这些前缀,并且您对所有这些都使用相同的混合,因此您的 CSS 转换需要同样多的前缀您的前缀动画实际上有任何用处:

@mixin expand-o-band() {
    0%   {
        opacity: 1;
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -o-transform: scale(1);
        transform: scale(1);
    }
    100% {
        opacity: 0;
        -webkit-transform: scale(2);
        -moz-transform: scale(2);
        -o-transform: scale(2);
        transform: scale(2);
    }
}

如果你使用一个带有前缀参数的混入,并在每个 @keyframes 规则中将适当的前缀传递给混入,你可以大大减少膨胀,但这可能超出了这个问题的范围(但这主要是因为我真的不知道Sass)。

简短的回答是:不要自己动手。 BoltClock 已经很好地解释了为什么您的实现对所有场景都不够好(前缀属性与前缀值)。

好消息是 Compass have already solved this problem for you.

的好人
@include keyframes(expand-o-band) {
    0% {
      /* prefixed property */
        @include border-radius(0);
    }

    100% {
        @include border-radius(1em);
        /* prefixed value */
        @include background(linear-gradient(to bottom, black, white));
    }
}

.circle-thing {
    @include animation(expand-o-band 1.5s infinite);
  background: yellow;
    padding: 5em;
    border: 1px solid;
}

输出:

@-moz-keyframes expand-o-band {
  0% {
    /* prefixed property */
    -moz-border-radius: 0;
    border-radius: 0;
  }
  100% {
    -moz-border-radius: 1em;
    border-radius: 1em;
    /* prefixed value */
    background: -moz-linear-gradient(top, #000000, #ffffff);
    background: linear-gradient(to bottom, #000000, #ffffff);
  }
}
@-webkit-keyframes expand-o-band {
  0% {
    /* prefixed property */
    -webkit-border-radius: 0;
    border-radius: 0;
  }
  100% {
    -webkit-border-radius: 1em;
    border-radius: 1em;
    /* prefixed value */
    background: -webkit-linear-gradient(top, #000000, #ffffff);
    background: linear-gradient(to bottom, #000000, #ffffff);
  }
}
@keyframes expand-o-band {
  0% {
    /* prefixed property */
    -moz-border-radius: 0;
    -webkit-border-radius: 0;
    border-radius: 0;
  }
  100% {
    -moz-border-radius: 1em;
    -webkit-border-radius: 1em;
    border-radius: 1em;
    /* prefixed value */
    background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #000000), color-stop(100%, #ffffff));
    background: -moz-linear-gradient(top, #000000, #ffffff);
    background: -webkit-linear-gradient(top, #000000, #ffffff);
    background: linear-gradient(to bottom, #000000, #ffffff);
  }
}
.circle-thing {
  -moz-animation: expand-o-band 1.5s infinite;
  -webkit-animation: expand-o-band 1.5s infinite;
  animation: expand-o-band 1.5s infinite;
  background: yellow;
  padding: 5em;
  border: 1px solid;
}

http://sassmeister.com/gist/2413d0894bf609e80b5d

默认情况下,Compass 将最大化浏览器兼容性(和 is fully configurable)。 他们发出前缀的所有 mixin 都与他们的关键帧 mixin 兼容。我什至无法粘贴相关代码来重现其中的魔力,因为它太多了。