Search code examples
htmlcsscss-transforms

Why does CSS transform influence Site width?


I was always under the impression that CSS transforms are purely visual and don't influence the actual site layout in any way. I recently found a weird bug in my project, where an image which is transformed out of the viewport (to later fly in) changed the width of the page.

My coworkers and I are extremely confused by this. I provided an example below (also hosted here: https://transform-confusion.netlify.app/) that shows the phenomenon with a transform: scale(2) applied to a div completely changing the width of the browser.

Video of weird behaviour in action

Do I just misunderstand how CSS works, is this a weird browser bug or what is going on here?

Source code used here and in the video:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <style>
        body {
            border: 2px dotted black;
        }
      .scale {
        transform: scale(2);
        transform-origin: top left;
      }
      .scalable{
          background: lightblue;
          padding: 5px;
      }
    </style>
  </head>
  <body>
    <h1>This is a test</h1>
    <button>Toggle transform</button>
    <div class="scalable">
      Why does the Site start scrolling horizonally from a simple transform?
      <pre>transform: scale(2)</pre>
    </div>
    <script>
        const scalable = document.querySelector(".scalable");
        document.querySelector("button").addEventListener("click", () => {
            scalable.classList.toggle("scale");
        })
    </script>
  </body>
</html>


Solution

  • I was always under the impression, that CSS transforms are purely visual and don't influence the actual site layouting in any way

    This is correct since transformation will not affect the position of any other element and the layout will remain the same.

    What you are facing is related to overflow:

    The scrollable overflow of a box is the set of things extending outside of that box’s padding edge for which a scrolling mechanism needs to be provided.

    The scrollable overflow area is the non-rectangular region occupied by the scrollable overflow, and the scrollable overflow rectangle is the minimal rectangle whose axes are aligned to the box’s axes and that contains the scrollable overflow area.

    .. the border boxes of all boxes for which it is the containing block and whose border boxes are positioned not wholly outside its block-start or inline-start padding edges, accounting for transforms by projecting each box onto the plane of the element that establishes its 3D rendering context. ref

    So transform is a part of the Scrollable Overflow

    You will find that some properties are part of the Ink Overflow and this one doesn't generate a scroll:

    The ink overflow of a box is the part of that box and its contents that creates a visual effect outside of the box’s border box. Ink overflow is the overflow of painting effects defined to not affect layout or otherwise extend the scrollable overflow area, such as box shadows, border images, text decoration, overhanging glyphs (with negative side bearings, or with ascenders/descenders extending outside the em box), outlines, etc.

    For example box-shadow will never create a scroll

    .box {
      width:100px;
      height:100px;
      background:red;
      box-shadow:0 0 0 1000vmax blue;
    }
    <div class="box"></div>