多个同步CSS3变换以不同的速度转换

时间:2014-02-27 23:09:30

标签: html css css3 transform css-transitions

问题:

是否可以对元素进行两种不同的变换并让它们以不同的速度进行过渡?

没有变换的示例(Fiddle):

div {
  width: 100px;
  height: 100px;
  background: red;
  transition: width 1s linear, height 2s linear;
}

div:hover {
  width: 200px;
  height: 400px;
}

注意宽度扩展到200px需要1秒钟,高度扩展到400px需要2秒。

变换示例(Fiddle):

div {
  width: 100px;
  height: 100px;
  background: red;
  transition: transform 1s linear, transform 2s linear;
}

div:hover {
  transform: scale(1.5);
  transform: rotate(45deg);
}

注意它只执行第二次转换。如何指定要为转换执行哪个转换?这是CSS转换设计的疏忽吗?我怎样才能完成这个?

4 个答案:

答案 0 :(得分:9)

不要以为你可以按照你的方式去做。可能的解决方案是包装器对象

例如

Multiple transitions

示例小提琴here

示例代码(HTML)

<div class="wrap">
<div class="inner"></div>
</div>

和CSS

.wrap {
    width: 100px;
    height: 100px;
    transition: transform 1s linear;
}
.inner {
    width: 100%;
    height: 100%;
    background: red;
    transition: transform 2s linear;
}
.wrap:hover {
    transform: scale(1.5);
}
.wrap:hover .inner {
    transform: rotate(45deg);
}

或使用@slynagh

回答中提到的动画和关键帧

只是没有注意,转换属性在chrome(在V33上的i.m)上使用时似乎不起作用,但它在IE11上工作正常,这就是我所有测试过的

答案 1 :(得分:5)

您可以尝试使用动画。

div {
  width: 100px;
  height: 100px;
  background: red;
}

div:hover {
  -webkit-animation: anim1 2s linear;
}

@-webkit-keyframes anim1{
  0% { -webkit-transform: scale(1) rotate(0deg); }
  50% {-webkit-transform: scale(1.5) rotate(22.5deg); }  
  100% { -webkit-transform: scale(1.5) rotate(45deg); }
}

您还需要为该悬停效果设置反向。

答案 2 :(得分:4)

不幸的是,您没有偶然发现CSS实现中的错误。

:hover上,第二个transform语句只是覆盖第一个,这是CSS核心。这同样适用于两次转换相同的参数 - 稍后在CSS中定义的规则或基于选择器权重的规则优先。

这样可行:

div {
  width: 100px;
  height: 100px;
  background: red;
  transition: transform 1s linear;
}

div:hover {
  transform: scale(1.5) rotate(45deg);
}

但是对于你想要的不同长度,转换@OJay建议的路径 - 转换包装器上的一个参数 - 是一个好方法。

@slynagh建议不会按预期工作,因为单个元素的动画/转换是线性执行的。

但我们可以让@OJay样本更整洁,没有任何其他元素:

div {
    width: 100px;
    height: 100px;
    position: relative;
    transition: transform 1s linear;
}
div:before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: red;
    transition: transform 2s linear;
}
div:hover {
    transform: scale(1.5);
}
div:hover:after {
    transform: rotate(45deg);
}

虽然能够使用伪元素取决于div的内容。

请注意,您缺少浏览器特定的前缀,这不是跨浏览器证明。

答案 3 :(得分:0)

可接受的答案建议使用包装器元素,但是您只需部署动画而不是转乘,就可以最优雅地实现此效果。

N.B。至关重要的是使用animation-fill-mode: forwards;(或简写形式),以使动画完成时不会恢复到初始值。

工作示例:

:root {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}

div {
  width: 60px;
  height: 60px;
  background: red;
}

div:hover {
  animation: scaleRotate 2s linear forwards;
}

@keyframes scaleRotate {

   0% {transform: scale(1) rotate(0deg);}
  50% {transform: scale(1.5) rotate(22.5deg);}
 100% {transform: scale(1.5) rotate(45deg);}
<div></div>