为什么 CSS 转换会影响站点宽度?

Why does CSS transform influence Site width?

我一直觉得 CSS 转换是纯粹的视觉效果,不会以任何方式影响实际的网站布局。我最近在我的项目中发现了一个奇怪的错误,其中转换出视口(稍后飞入)的图像改变了页面的宽度。

我和我的同事对此感到非常困惑。我在下面提供了一个示例(也托管在这里:https://transform-confusion.netlify.app/),它显示了将 transform: scale(2) 应用于 div 完全改变浏览器宽度的现象。

我只是误解了 CSS 的工作原理,这是一个奇怪的浏览器错误还是这里发生了什么?

使用的源代码 here 并且在视频中:

<!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>

我刚刚在规格中找到了重要信息。我的误解是溢出行为:

For elements whose layout is governed by the CSS box model, the transform property does not affect the flow of the content surrounding the transformed element. However, the extent of the overflow area takes into account transformed elements. This behavior is similar to what happens when elements are offset via relative positioning. Therefore, if the value of the overflow property is scroll or auto, scrollbars will appear as needed to see content that is transformed outside the visible area. Specifically, transforms can extend (but do not shrink) the size of the overflow area, which is computed as the union of the bounds of the elements before and after the application of transforms.

来自 https://drafts.csswg.org/css-transforms/#transform-property

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

这是正确的,因为转换不会影响任何其他元素的位置,布局将保持不变。

您遇到的问题与溢出有关:

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

所以转换是 Scrollable Overflow

的一部分

您会发现某些属性是 Ink Overflow 的一部分,而这个不会生成卷轴:

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.

例如box-shadow永远不会创建卷轴

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

晚会有点晚了,但这是我对问题的解决方案:

html {
    overflow-x: hidden;
}

可能有点老套,但对我有用!