CSS 独立变换属性

CSS 变换(CSS Transforms)与 CSS 动画(CSS Animations)和 CSS 过渡(CSS Transitions)一起出现在 Web 上,用于在 Web 上添加视觉效果和运动。这些技术在 Web 平台和 Web 开发人员的工具包中已经存在了十多年。事实上,CSS transform 属性首次在 Safari 中推出是在 2008 年 7 月,当时 iPhone OS 2.0 发布。你可以找到一些关于 WebKit 早期支持的历史文章(2007 年 10 月),以及 2009 年 7 月另一篇专注于 3D 变换的文章,当时 CSS 变换在 Mac OS X Leopard 中发布。

现在,CSS 变换领域有一些新消息:独立变换属性Safari 技术预览版 117 中默认启用。这意味着,与 Firefox 和 Chrome Canary 一样,你现在可以使用新的 translaterotatescale CSS 属性来指定迄今为止一直是 transform 属性函数的功能,包括 3D 操作。

使用这些属性很简单,应该会让 Web 开发人员感到得心应手。考虑这两个等效示例:

div.transform-property {
    transform: translate(100px, 100px) rotate(180deg) scale(2);
}

div.individual-properties {
    translate: 100px 100px;
    rotate: 180deg;
    scale: 2;
}

但为什么要使用这些新属性而不是 transform 属性呢?一个原因是方便,因为当你只想缩放一个元素时,你可能会觉得写 scale: 2 比写 transform: scale(2) 更简单。

但我认为这里的主要吸引力在于,你现在可以自由地以任何你认为合适的方式组合这些不同的变换属性。例如,你可以轻松编写一个 CSS 类,使用 scale 属性翻转一个元素,而无需担心会覆盖其他与变换相关的属性。

.flipped {
    scale: -1;
}

即使 rotatetransform 属性对元素应用了旋转,你的 flipped 类也能正常工作。

此功能在动画变换时也派上用场。假设你正在编写一个动画,该动画在整个持续时间内放大一个元素,但在动画的后半部分也应用旋转。使用 transform 属性,你将不得不预先计算旋转开始和结束时缩放的中间值应该是多少。

@keyframes scale-and-rotate {
    0%   { transform: scale(1) }
    50%  { transform: scale(1.5) rotate(0deg) }
    100% { transform: scale(2) rotate(180deg) }
}

虽然这看起来不是什么大问题,但对这些关键帧进行任何进一步的更改都需要重新计算这些值。现在,考虑使用独立变换属性编写的相同动画:

@keyframes scale-and-rotate {
    0%   { scale: 0 }
    50%  { rotate: 0deg } 
    100% { scale: 1; rotate: 180deg; }
} 

你可以根据需要轻松更改关键帧并添加其他属性,让浏览器自行计算如何正确应用这些独立变换属性。

但这还不是全部;还有一种情况是你想同时将单独的动画应用于一个元素。你可以将这一组关键帧拆分成两组不同的关键帧,然后调整时间。

.animated {
    /* Apply the scale keyframes for 1s and the rotate
       keyframes for 500ms with a 500ms delay. */
    animation: scale 1s, rotate 500ms 500ms;
}

@keyframes scale {
    from { scale: 0 }
    to   { scale: 1 }
}

@keyframes rotate {
    from { rotate: 0deg }
    to   { rotate: 180deg }
}

现在,应用于变换的关键帧不仅更容易编写,而且通过组合多个变换动画,你可以更好地分离时间和关键帧。如果你是一位经验丰富的 CSS 动画开发人员,你会知道在考虑时间函数时这有多么重要。

此外,动画新的独立变换属性与动画 transform 属性具有相同的出色性能,因为这些属性支持硬件加速。

transform 属性呢?它与这些新的独立变换属性有什么关系?

首先,请记住 transform 属性支持不作为独立变换属性表示的变换函数。没有与 skew()skewX()skewY() 函数等效的 CSS 属性,也没有与 matrix() 函数等效的属性。

但当你同时指定一些独立变换属性和 transform 属性时会发生什么?CSS 变换级别 2 规范解释了独立变换属性以及 transform-origintransform 属性如何组合形成当前变换矩阵。总而言之,首先应用*独立*变换属性——translaterotate,然后是 scale——然后应用 transform 属性中的函数。

这意味着存在一个清晰的模型,可以同时使用这些独立变换属性和 transform 属性,以增强你在 Web 平台上变换内容的能力。

在你开始使用这些新属性之前,重要的是要知道如何检测它们的可用性,并使用 transform 作为备用方案。在这里,@supports 规则将允许你实现所需功能。

@supports (translate: 0) {
    /* Individual transform properties are supported */
    div {
        translate: 100px 100px;
    }
}

@supports not (translate: 0) {
    /* Individual transform properties are NOT supported */
    div {
        transform: translate(100px, 100px);
    }
}

我们鼓励你开始在项目中探索如何在 Safari 技术预览版中使用这三个新属性,如果遇到意外问题,请在 bugs.webkit.org 上提交错误报告。你也可以向 @webkit@jonathandavis 发送推文,分享你对独立变换属性的看法。