CSS溢出隐藏与父元素位置可见的奇怪效果[重复]

Posted

技术标签:

【中文标题】CSS溢出隐藏与父元素位置可见的奇怪效果[重复]【英文标题】:Strange effect of CSS overflow hidden vs. visible on position of parent element [duplicate] 【发布时间】:2019-12-29 04:07:07 【问题描述】:

我从未读过任何内容表明元素的溢出属性会对我在这里看到的元素定位产生奇怪的影响:

https://codepen.io/kshetline/pen/ZEzLVxN

切换示例中的切换按钮,观察<div> 的背景如何神秘地向上滑动,覆盖之前的内容,而其内容保持在相同的屏幕相对位置(意味着内容相对于其父母的背景)。

这个例子是我试图用一个 Angular 组件做的一个非常简化的版本,它旨在扩展它的<ng-content>——但这个例子只有 CSS 和 html,带有一点 javascript,没有 Angular,因为我正在尝试隔离相关变量。

HTML 元素的 内容 可以使用 transform: scale( 小于 1 的缩放因子 ) 缩小,但即使元素的内容渲染得更小,默认情况下元素的像素尺寸保持不变,内容(除非另有说明)向元素的中心收缩,并且在该内容周围留下空白空间,使元素保持其原始未缩放的尺寸..

您需要计算与缩放程度相匹配的负边距,以便将元素本身视为更小。我已经这样做了,但我发现除非缩放元素的容器将 CSS overflow 设置为 hidden,否则可能会出现一些奇怪的定位,就好像需要的额外空白空间应该由负边距仍然对其他元素的整体布局产生部分难以解释的影响。

我在 Chrome、Firefox、Safari 和 Edge 中看到了这种行为——所以我猜这是“正确”的 CSS 行为,但这对我来说毫无意义,我希望有人能解释发生了什么.我希望能够将overflow 设置为visible,以便缩放后的内容仍然可以执行诸如显示不会在元素边界处剪切的浮动下拉菜单之类的操作。

let hidden = true;
const inner = document.getElementById('inner')

function toggleOverflow() 
  hidden = !hidden;
  inner.style.overflow = hidden ? 'hidden' : 
  'visible'
html, body 
  height: calc(100vh - 10em);


.page 
  font: 32px Arial, Helvetica, sans-serif;
  height: calc(100% - 1em);


.container 
  background-color: #ACF;
  height: 100%;


.outer-wrapper 
  background-color: rgba(187, 255, 204, 0.5);
  font-size: 2em;
  margin: 0 1em;
  position: relative;


.inner-wrapper 
  overflow: hidden;
  position: relative;
  width: fit-content;


.ng-content 
  margin: -18.75px 0;
  transform: scale(0.5);


.container-text 
  display: inline-block;
  position: absolute;
  bottom: 1em;
<div class="page">
  <button onclick="toggleOverflow()">Toggle Overflow</button><br>
  Content outside of the<br>
  panel being scaled and its<br>
  containing &lt;div&gt;, 32pt font<br>
  <div class="container">
    <!--Angular component start tag goes here -->
    <div class="outer-wrapper">
      <div id="inner" class="inner-wrapper">
        <div class="ng-content">
          50% scaled content goes here, 64pt font
        </div>
      </div>
    </div>
    <!-- Angular component end tag goes here -->
    <span class="container-text">This is an absolutely positioned &lt;span&gt; in the same &lt;div&gt;</span>
  </div>
</div>

【问题讨论】:

【参考方案1】:

来自CSS 2.2 spec

建立新块格式化上下文的元素(例如浮动和具有“溢出”而不是“可见”的元素)的边距不会与其流入的子元素一起折叠。

所以添加overflow:hidden 可以阻止边距折叠。

【讨论】:

谢谢!此信息帮助我找到了防止边距崩溃的不同技巧:使用非常小但非零的填充量。具体来说,padding: 0.05px。在找到该建议后,我尝试了更小的 0.01 像素,但没有奏效,因此显然在某些时候非常小的数字有效地四舍五入为零。【参考方案2】:

您在 .ng 内容中设置了负边距。如果溢出设置为隐藏,它将隐藏负边距。将边距设置为正数,它将解决此跳跃问题。

.ng-content margin: 18.75px 0;

如果您尝试上下更改元素的高度,请尝试使用max-heightoverflow: hidden。当最大高度设置为 0 时,它将被隐藏。当设置为 500 像素时,您的内容就会显示出来!

【讨论】:

将边距从负数更改为正数将与我试图实现的方向完全相反,即缩放内部元素的内容而不获得缩放内容周围有很多空白区域。【参考方案3】:

跟进...

我在这里的第一个代码笔上创建了一个变体:

https://codepen.io/kshetline/pen/WNeRmOo

在这种情况下,我在缩放时使用transform-origin: top center,并将所有需要的负边距放在缩放元素的底部,而不是在顶部和底部之间平均分配。这消除了奇怪的垂直位置偏移。

overflow: hidden 仍然需要隐藏多余的背景颜色以防止其容器“泄漏”,但在缩放元素的背景是透明的(常见)情况下,使用不会有明显的效果overflow: visible 而不是,不用担心来自缩放元素内部的剪辑下拉菜单。

跟进 #2...

这是最好的解决方案,使用padding: 0.05px 来处理@Alochi 帮助我理解的真正问题——阻止边界崩溃:

https://codepen.io/kshetline/pen/zYONgzV

【讨论】:

以上是关于CSS溢出隐藏与父元素位置可见的奇怪效果[重复]的主要内容,如果未能解决你的问题,请参考以下文章

溢出-y:父元素上的auto隐藏位置固定的子元素

为啥一个元素在“溢出:可见”时消失,但在“溢出:隐藏”时可见? [复制]

其他样式

CSS溢出-x:可见;和溢出-y:隐藏;导致滚动条问题

使用css3显示/隐藏元素的css过渡效果[重复]

Chrome和Firefox溢出:隐藏的跳跃元素