Given these two examples.
You need to set an initial rotate(0)
, so there can be animation between the two states. Set the div
's initial transform to:
transform: translateX(-50%) rotate(0);
Transition:
div {
position: absolute;
width: 150px;
height: 40px;
background: orange;
left: 50%;
top: var(--top);
transition: transform 2s;
transform: translateX(-50%) rotate(0);
text-align: center;
line-height: 40px;
font-size: 1.2em;
}
div:hover {
transform: translateX(-50%) rotate(var(--deg));
}
div:nth-child(1) {
--deg: 180deg;
--top: 20%;
}
div:nth-child(2) {
--deg: -180deg;
--top: 40%;
}
div:nth-child(3) {
--deg: 360deg;
--top: 60%;
}
body {
overflow: hidden;
}
<div>180deg</div>
<div>-180deg</div>
<div>360deg</div>
Animation:
div {
position: absolute;
width: 150px;
height: 40px;
background: orange;
left: 50%;
top: var(--top);
transform: translateX(-50%) rotate(0);
text-align: center;
line-height: 40px;
font-size: 1.2em;
animation: rotate 2s linear 2s forwards;
}
@keyframes rotate {
to {
transform: translateX(-50%) rotate(var(--deg));
}
}
div:nth-child(1) {
--deg: 180deg;
--top: 20%;
}
div:nth-child(2) {
--deg: -180deg;
--top: 40%;
}
div:nth-child(3) {
--deg: 360deg;
--top: 60%;
}
body {
overflow: hidden;
}
<div>180deg</div>
<div>-180deg</div>
<div>360deg</div>
It seems a browser bug (at least on Chrome) as it works fine if your try the code on Firefox.
Let refer to the the specification to explain this. Here is all the different cases of how interpolation between transform should work.
In our case, we will consider the last point where we don't have the same number of transform functions and the browser should handle this by adding the identity transform function from the missing list and in our case it should be rotate(0)
.
So technically a transition from translate(-50%)
to translate(-50%) rotate(360deg)
should be the same as a transition from translate(-50%) rotate(0)
to translate(-50%) rotate(360deg)
.
Unless, I am missing something this is for sure a bug as in the case when rotate(360deg)
is used alone, Chrome is handling this fine using the second point (when one value is none
) which is almost the same as the last point.