Search code examples
cssgoogle-chromecss-transitionscss-transforms

transform-origin (css) Chrome (88) bug


There are several sources that describes this issue in different ways, but they are too complex (a lot of js) and narrow-focused. And there is no definite answer why does it happens and why Google didn't fix it by now.

I decided to make the most simplest example. Here it is and once again below in snippet: https://codepen.io/backtosoulfire/pen/vYyOJJe

If you are Mozilla user (not only Mozilla I guess) you will find nothing strange and unusual. But if you are exploring the internet with Chrome, try to press marked block.

We have a little transition time and a specific transform-origin property.

let element = document.querySelector('.menu-btn');

element.onclick = function() {
  element.classList.toggle('menu-btn_active');
};
.section {
    width: 300px;
    height: 300px;
    background-color: cyan;
    position: relative;
}

.menu-btn {
  display: flex;
  align-items: center;
  justify-content: center;
    width: 100px;
    height: 30px;
    background-color: black;
    position: absolute;
    top: 50%; margin-top: -15px;
    left: 50%; margin-left: -50px;
}

.menu-btn_active {
    transform: rotate(-90deg);
    transition: 0.5s;
    transform-origin: left bottom;
}

p {
  color: white;
  text-align: center;
}
<div class="section">
  <div class="menu-btn">
    <p>Press me</p>
  </div>
</div>

You will find that rotate is made without considering 'transform-origin' property and at the end of animation the block suddenly "jumps" to a position where it must be if 'transform-origin' was taken into account and effected it.

The quetion sounds like this:

  1. Why does it happen?
  2. Is there simple way (as simple as the example) to fix it?
  3. Should someone contact the Chrome developers with this trouble? Becouse we can find some complex examples of this bug dates several years ago.

P.S. I forgot to share some "strange" "feature". If we resize the element's width at second class, Chrome starts to "render" it like it suppose to. The problem only maintains if the element is the same width.


Solution

  • It isn't a bug, transform-origin should be in your original class declaration:

    .menu-btn {
      display: flex;
      align-items: center;
      justify-content: center;
        width: 100px;
        height: 30px;
        background-color: black;
        position: absolute;
        top: 50%; margin-top: -15px;
        left: 50%; margin-left: -50px;
        transform-origin: left bottom; // add here
    }
    
    .menu-btn_active {
        transform: rotate(-90deg);
        transition: 0.5s;
        transform-origin: left bottom; // remove here
    }
    

    Initially, the transform-origin is set by default. That default is center center. You add a class to the item, and after the class is added, change the location to left bottom, hence the jump.

    https://codepen.io/EightArmsHQ/pen/f7b4dab6b40a1ff945b79e11c4ce6863?editors=1100