Home > database >  Why does 'transform:rotate(Xdeg)' cause the animation to stop?
Why does 'transform:rotate(Xdeg)' cause the animation to stop?

Time:04-05

I tried to rotate an animated font arrow when the window reached a min/max size, but when the rotate takes place the animation stops, also just for testing I tried replacing transform: rotate(90deg) to transform: rotate(0deg) which maintains the same arrow's direction but it causes to stop the animation too. The issue is with transform: rotate() and it can be easily tested by inspecting the element and activating/deactivating it in the browsers developer tools.

An easy way to bypass this can be using two <p> each one with an arrow in different direction and with vertical and horizontal animation each, and using display: none; to alternate between them when the min/max size switches, but what I want is to know why this is happening and how to solve this using this approach

.text-center {
  text-align: center;
}

.lnr-x3 {
  font-size: 2.4rem;
}

@media (max-width: 991px) {
  #catalogArrow_h {
    transform: rotate(90deg) !important;
    transform-origin: center !important;
  }
}

.animated-h {
  text-decoration: none;
  outline-style: none;
  -webkit-animation: movingHorizontally 1.7s ease-in-out infinite;
  animation: movingHorizontally 1.7s ease-in-out infinite;
}

@keyframes movingHorizontally {
  0% {
    transform: translateX(0px);
    -webkit-transform: translateX(0px);
  }
  50% {
    transform: translateX(-10px);
    -webkit-transform: translateX(-10px);
  }
  100% {
    transform: translateX(0px);
    -webkit-transform: translateX(0px);
  }
}

@-webkit-keyframes movingHorizontally {
  0% {
    transform: translateX(0px);
    -webkit-transform: translateX(0px);
  }
  50% {
    transform: translateX(-10px);
    -webkit-transform: translateX(-10px);
  }
  100% {
    transform: translateX(0px);
    -webkit-transform: translateX(0px);
  }
}
<!-- Font Icons -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" type="text/css">
<link rel="stylesheet" href="https://cdn.linearicons.com/free/1.0.0/icon-font.min.css">

<div >
  <p >
    <span id="catalogArrow_h" ></span>
  </p>
</div>

CodePudding user response:

Why does this happen

The transform property is "shared" for many transform functions and css doesn't combine any property's values.

Because your animation is made with transform: translateX(..), adding transform: rotate(..) will overwrite the property's value, not combine them. I.e. the resulting style is transform: rotate(..), not transform: translateX(..) rotate(..).

It would be the same if you were animating the box-shadow and then wanted an inset box-shadow too, it would overwrite one with the other. Or more simply - if you have .box { color: red; color: blue; } css will choose the last value (blue) to apply to the color property.

If there were css properties rotate: 90deg and translate: 4px (there are but not widely supported), then your animation would work, because the translate animation would be applying to a different property than the rotation, not overwriting one that is essentially shared amongst many transform functions.

Ways around it

There are many ways around this problem.

  • You can set the translate or rotate on the parent element
<div >
  <span ></span>
</div>
  • You can add the rotate to your translate animation properties:
@keyframes movingHorizontallyRotated {
  0%, 100% { transform: translateX(0px)   rotate(90deg); }
  50%      { transform: translateX(-10px) rotate(90deg); }
}
  • You can animate a different property to translate the element:
@keyframes movingHorizontally {
  0%, 100% { padding: 5px 10px 5px 0px; }
  50%      { padding: 5px 0px 5px 10px; }
}
  • You can use/make an already rotated arrow if your framework/ assets provides one.
  • Related