如何使 HTML parent 元素的边界框适合 CSS 转换后的 child?

How to fit HTML parent element's bounding box to a CSS transformed child?

有没有办法,最好不使用 JS,使以下代码片段中的容器包装缩放的,更一般地说,转换后的 child 元素,即红色实线外边框完全包含蓝色虚线边框?

顺便说一句,这似乎是一个浏览器错误,因为它违反了 parent 的大小自动调整以适合 children 的默认框模型行为。

#container {
  border: 1px solid red;
}

#scaled {
  border: 1px dashed blue;
  transform: scale(3, 3);
  transform-origin: 0 0;
}
<div id="container">
  container
  <div id="scaled">
    scaled 3x
  </div>
</div>

不使用 JavaScript 就无法做到这一点,但这也不是浏览器错误。 CSS 在计算页面流并确定每个未转换元素的位置和大小后,转换发生在图形管道中。

这意味着 CSS 转换不会导致重新计算任何其他元素的大小,这就是容器未调整大小以包含转换后的子元素的原因。这实际上是 transform 的一项功能,旨在通过完全避免布局重新计算来提高性能。

唯一可以干净地完成此操作的方法是将转换应用于父元素,您似乎正试图摆脱它。如果你想要它是动态的,又想远离JS,可惜没有别的办法。

#container {
  border: 1px solid red;
  transform: scale(3, 3);
  transform-origin: 0 0;
}

#scaled {
  border: 1px dashed blue;
  
}
<div id="container">
  container
  <div id="scaled">
    scaled 3x
  </div>
</div>

由于 给出的原因,未经转换的相同可见结果可能是:

#container {
  border: 1px solid red;
}

#scaled {
  border: 3px dashed blue;
  font-size:3em;
}
<div id="container">
  container
  <div id="scaled">
    scaled 3x
  </div>
</div>

但是由于某种原因这似乎并不能解决问题所以让我们尝试一下变换功能添加一点 javascript 来修复高度:

//JavaScript
var scale = 3;
var scaled = document.getElementById("scaled");
var container = document.getElementById("container");
container.style.height = //set the height of the container to
  container.clientHeight + //the old container height including the unscaled div
  (scale-1)*scaled.clientHeight + //add to that 2 more of the unscaled div
  (scale+scale/2|0) + //a kind of magic buffer to acount for border |0 converts to int
  "px";// make it css readable in pixls
/*CSS*/
#container {
  border: 1px solid red;
  /*height: 86px; tweakable magic number if not using JavaScript*/
}
#scaled {
  border: 1px dashed blue;
  transform: scale(3,3);
  transform-origin: 0 0;
  width: 33%
}
<div id="container">
 container
  <div id="scaled">
    scaled 3x
  </div>
</div>
<script>
  //insert JavaScript here
</script>

正如我在代码中指出的那样,您可以通过更改 css 中的高度来手动执行此操作,但如果您愿意使用 JavaScript,则此解决方案应该有效,但不应该每次添加内容都需要更改。

其他答案已经解释了为什么需要JS。 这是隐藏转换后遗留下来的 'extra' space 的方法。

  • 假设您想要 50% 的缩放比例
  • 您会在项目上设置 transform: scale(.5); transform-origin: 0 0
  • 如果您知道要调整大小的项目的原始大小,则可以通过将宽度和高度乘以比例因子来计算其新尺寸。
  • 在父级上设置这些新维度 div 以便页面上的其他所有内容都可以围绕它流动。

如果您不知道元素的大小,可以使用 ResizeObserver 找到它(它将是未缩放的大小),然后将缩放因子乘以 width/height 并设置父包装器 div.

上的那些新值