使用CSS过渡和变换时,需要针对不同浏览器添加前缀

12
根据 caniuse.com 的数据,对于那些同时支持 CSS 的 transition 和 CSS 的 transform 的浏览器,至少有三种不同类型:
  1. 需要在 transitiontransform 上都加上 -webkit- 前缀(例如 Safari 6,Android browser < 4.4)。
  2. 只需要在 transform 上加上 -webkit- 前缀(例如 Chrome 3x)。
  3. 不需要前缀(例如 FF 和 IE10/11)。
如何才能安全地编写我的 transition 样式以便在每个类型中正确解析它们?我看到了两个选项:
-webkit-transition: -webkit-transform 300ms;
        transition: -webkit-transform 300ms, transform 300ms;
或者
-webkit-transition: -webkit-transform 300ms;
        transition: -webkit-transform 300ms;
        transition: transform 300ms;

现在由于第二型和第三型浏览器,我需要为两个属性 -webkit-transformtransform都使用无前缀的过渡。第一个选项的问题是,我担心第二型和第三型浏览器将无法解析第二行,因为它们始终包含一个未识别的属性。问题是,浏览器如何处理transition中的无效属性--忽略整个transition样式还是跳过无效属性?

我认为通过将其分成两个属性,可以减轻这种情况,这样如果一个属性无法解析,它就会被忽略。除了第二个选项有点冗长外,我仍然想知道,在第二型浏览器的情况下,第三个transition是否无法解析并将transition“重置”为null。

这些选项通常如何表现?另外,哪一种对于Chrome 等转换到无前缀transform 时是符合未来标准的?

2个回答

15

更新通知很遗憾,在发布本文时,Safari并没有遵循下面W3规范所提供的标准。在过渡之后包含既有webkit前缀属性又有无前缀属性会导致它不能被动画化。我仍在探讨一个很好的通用解决方案,但看起来除非Safari解决了这个问题,否则可能没有一种可以在所有情况下工作,并且适用于所有未来属性而不需要使用JavaScript动态调整CSS规则。


如果您将一个未被识别或无效的属性添加到过渡属性列表中,列表中的有效属性仍会被添加(除了Safari,请参见上文的通知)。

根据CSS过渡的W3规范第2.1节:

如果列出的标识符之一不是被认可的属性名称或不是可动画的属性,则实现必须仍使用各自在“transition-duration”、“transition-delay”和“transition-timing-function”的列表中的索引处的持续时间、延迟和计时功能在可动画属性的过渡上开始过渡。

CSS过渡的W3规范

如果您采用以下样式,宽度属性仍将被动画化,尽管在其前面有一个无效且未被识别的属性。

transition: unrecognizedProperty 2s, width 2s;
如果您使用另一个转换规则(具有相同的前缀或缺乏前缀)遵循转换规则,则第一个规则将被覆盖,并且即使右侧列出的第二个规则仅具有无效属性,也不再适用。 如果您尝试以下样式,则宽度将不会进行动画处理,因为第一个规则将被第二个规则覆盖,该规则实际上什么都不做,因为“unrecognizedProperty”无法识别。
transition: width 2s;
transition: unrecognizedProperty 2s;

根据这个,我相信你的第一种方法是正确的。

-webkit-transition: -webkit-transform 300ms;
        transition: -webkit-transform 300ms, transform 300ms;

如果浏览器识别-webkit-transition,则仅应用第一条规则,在这种情况下,由于transform是在transition之后推出的,因此它肯定必须加前缀,我们可以省略未经前缀的transform属性(尽管我认为保留它也不会有问题)。如果识别到未经前缀的过渡,则仅应用第二条规则,在这种情况下,无论列表中的其他属性是否被识别,都将应用浏览器识别的右侧属性。

您的第二种方法存在缺陷,因为第二条规则始终会被第三条规则覆盖,而与右侧属性是否被识别无关。

我认为要确保在所有能力的浏览器上应用2秒转换过渡的完整浏览器前缀属性列表如下,但请阅读以下理性,因为仅对于这个属性对而言这只是偶然的方便:

-webkit-transition: -webkit-transform 2s;
   -moz-transition:    -moz-transform 2s;
     -o-transition:      -o-transform 2s;
        transition:         transform 2s;
  1. 请注意,-ms-transition 并不存在,但有 -ms-transform。也就是说,在 IE10 之前,transition 并未添加,而 -ms-transform 也已被不带前缀的 transform 取代。因此,在 IE 中,我们只需要一条规则:“transition: transform”。

  2. 我还要指出,每当我们为 transition 添加浏览器前缀时(< Chrome 26、< Firefox 16、< Safari 6.1、< Opera 12.1),那么 transform 也肯定仍然带有前缀(< Chrome 36、< Firefox 16、所有 Safari、< Opera 23),这意味着我们可以在带前缀的规则后省略不带前缀的 transform 版本。

  3. 由于 Firefox 在发布不带前缀的 transition 同时也发布了不带前缀的 transform,所以我们在不带前缀的“transition”右侧不需要加上前缀“-moz-transform”。

  4. 某个版本的 Opera 还额外使用了 -webkit- 前缀来添加 transform,不过在版本 15 开始,他们开始使用 -webkit-transform,此前在版本 12.1 中使用了带前缀的 transition,因此我们不需要在 -o-transition 之后包含 -webkit-transform。而且由于 Opera 在版本 12.1 之后仅使用不带前缀或 -webkit-transform,因此我们不需要在不带前缀的 transition 后包含 -o-transform。

  5. 在这种情况下,我们不必在不带前缀的 transition 右侧添加 -webkit-transform,因为只识别 -webkit-tranform 的浏览器会回退到 -webkit-transition 并仍然应用该属性。


但如果你不介意 CSS 的长度,以下内容是确保过渡和右手属性带有正确浏览器前缀的安全通用解决方案。 更新通知:由于 Safari 不遵循 W3 标准,在转换属性右侧存在一个带有前缀和一个不带前缀的属性时,忽略未识别的属性,因此这种方法在 Safari 上可能不安全。

-webkit-transition: -webkit-property,
                            property;
   -moz-transition:    -moz-property,
                            property;
    -ms-transition:     -ms-property,
                            property;
     -o-transition:      -o-property,
                    -webkit-property,
                            property;
        transition: -webkit-property,
                       -moz-property,
                        -ms-property,
                         -o-property,
                            property;

非常出色、經過深入研究的回答。不過關於這個錯誤,即使 Safari 不正確地無效整個 transition 規則,它還是會退回到 -webkit-transition: -webkit-transform 規則嗎?或者你是說 transition 中無法識別的屬性無效了兩個規則嗎? - Kevin Christopher Henry
2
@Kevin Christopher Henry:是的,它仍然会回退到“-webkit-transition: -webkit-transform”规则。您还可以通过将无前缀的“transition”声明拆分为两个来解决此问题:一个用于“-webkit-transform”,另一个用于“transform”。值得注意的是,所有 WebKit变种,包括Blink,都受到此问题的影响,而不仅仅是Safari。 - BoltClock
还有,我怎么今天才注意到这个问题和答案?最终我自己回答了一个后来的问题。 - BoltClock
已在iOS 7.1上进行了测试。一旦出现错误,Safari确实会回退到“-webkit-transition”并正常工作。 - tfE

2

我认为未被识别的转换前缀会被简单地跳过,直到找到一个被识别的前缀。

目前,我正在为一个网站使用它,并且对我们来说它很有效。

CSS

.viewElement{
   -webkit-transform: translatex(0) translatey(500px);
   -moz-transform: translatex(0) translatey(500px);
   -o-transform: translatex(0) translatey(500px);
   -ms-transform: translatex(0) translatey(500px);
   transform: translatex(0) translatey(500px);
   -ms-filter: "progid: DXImageTransform.Microsoft.Alpha(Opacity=0)";
   filter: alpha(opacity=0);
   opacity: 0.0;
   -webkit-transition: all .8s ease-out;
   -moz-transition: all .8s ease-out;
   -o-transition: all .8s ease-out;
   -ms-transition: all .8s ease-out;
   transition: all .8s ease-out;
}

嗯,我认为你是正确的,但这并没有回答一个无效的过渡属性是否会使整个过渡无效,还是只会使该属性的过渡无效。另外,我不能使用“all”,因为有些属性我不想过渡。 - 0x24a537r9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接