Search code examples
csscss-transforms

How to center object with CSS transform scale


I'm trying to implement a zoom in/out functionality, just like you would have on a document editor like google docs or any word processor application. The problem I'm having is that I cannot keep the "document" centered and also be able to scroll all of its parts into view. Here is a small demonstration of the problem: https://codepen.io/liviu_vasut/pen/dyGbwwO

document.getElementById('objectToScale').style.transform = "scale(3)";
.container {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5px;
  width: 300px;
  height: 200px;
  border: 1px solid #000000;
  left: 0px;
  top: 0px;
  margin: 10px;
  overflow: auto;
}

.object {
  position: relative;
  width: 120px;
  height: 120px;
  display: inline-block;
  background-color: grey;
  border-radius: 25px;
  padding: 5px;
  transform-origin: center;
  transform: scale(1);
}
<div class="container">
  <div id="objectToScale" class="object">x</div>
</div>

Thanks for your time.


Solution

  • You scale only some inner element inside the whole box, but expect see the whole box scaled. if you want to scale the white padding and all the inner content to stay visible (and be able to scroll to) you should add some wrapper inside with width: 100% and height: 100%, and scale it, so the whole content become scaled.

    Also, as @HaoWu mentioned, you should set the transform-origin to 0 0.

    The final product should look somewhat like this:

    var scaled = false;
    
    function toggleScale() {
      var objects = document.getElementsByClassName('wrapper');
      for (var i = 0; i < objects.length; i++) {
        objects[i].style.transform = scaled ? 'scale(1)' : 'scale(3)';
      }
      scaled = !scaled;
    }
        .container {
          width: 300px;
          height: 200px;
          border: 1px solid #000000;
          left: 0px;
          top: 0px;
          margin: 10px;
          overflow: auto;
        }
        .wrapper {
          width: 100%;
          height: 100%;
          display: flex;
          box-sizing: border-box;
          align-items: center;
          justify-content: center;
          padding: 5px;
          transform-origin: 0 0;
        }
        .object {
          position: relative;
          width: 120px;
          height: 120px;
          display: inline-block;
          background-color: grey;
          border-radius: 25px;
          padding: 5px;
          transform-origin: center;
          transform: scale(1);
        }
    <input type="button" onclick="toggleScale()" value="Toggle Scale" />
    
    <div class="container">
        <div class="wrapper">
            <div id="objectToScale" class="object">x</div>
        </div>
    </div>