Is it even possible to do two different transforms on an element and have them transition at different speeds?
The accepted answer suggests using a wrapper element, but you can achieve this effect most elegantly by simply deploying an animation rather than a transiton.
N.B. It is crucial to use animation-fill-mode: forwards;
(or the shorthand equivalent) in order that when the animation completes it does not revert back to the start values.
Working Example:
: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>
Unfortunately you have not stumbled on a bug in CSS implementation.
On :hover
the second transform
statement is simply overwriting the first one, this is CSS core. And the same applies to transforming the same parameter twice - rules defined later in the CSS or based on selector weight take precedence.
This would work:
div {
width: 100px;
height: 100px;
background: red;
transition: transform 1s linear;
}
div:hover {
transform: scale(1.5) rotate(45deg);
}
But for your desired different length transforms the route suggested by @OJay - transform one of the parameters on a wrapper - is a good way.
As suggested by @slynagh will not work as expected as animations/transformations on a single element are performed linearly.
But we can make @OJay sample even neater without any additional elements:
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);
}
Though being able to use a pseudo element depends on the content of your div.
Do take note, that you are missing browser specific prefixes and this is not cross browser proof.
You could try to use animations.
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); }
}
You would need to also set up the reverse for that hover out effect.
Don't think you can do it the way you are attempting. Possible solutions would be a wrapper object
eg
Multiple transitions
sample fiddle here
sample code (HTML)
<div class="wrap">
<div class="inner"></div>
</div>
and 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);
}
or use animations and keyframes as mentioned in answer by @slynagh
Just out of note, the transform property doesn't seem to work when used in transition on chrome (i.m on V33), but it works fine on IE11, thats all I have tested this on