CSS:“溢出:隐藏”替代方案不会破坏 3D 转换

Rad*_*ski 9 css 3d overflow parallax

我正在尝试制作具有视差效果的水平剖面。背景中应该有一个图像,其滚动速度与页面不同。

问题是:我希望视差元素包含在父元素中,因此父元素的工作方式有点像子元素的掩码:子元素仅在父元素的边界内可见。

我知道这可以通过在两个背景元素之间设置视差元素来实现,这些元素的背景位于视差元素“上方”并遮挡它,但此方法不适用于我的情况。

我想到的一个明显的想法是在父级上使用溢出:隐藏。然而,这会破坏 3D 变换,因此不存在视差。

如何达到所描述的效果?

这是一个代码笔: https: //codepen.io/rradarr/full/mdwgard。我希望红色矩形在带有黑色边框的“视差容器”之外不可见。

* {
      margin: 0;
    }
    
    html, body {
      height: 100%
    }
    
    main {
      position: relative;
      width: 100%;
      
      perspective: 1px;
      transform-style: preserve-3d;
      overflow-y: auto;
      overflow-x: hidden;
      height: 100vh;
      
      background-color: blue;
    }
    
    .static {
      min-height: 800px;
    }
    
    .parallax-container {
      border: solid black 3px;
      height: 600px;
      width: 100%;
      transform-style: preserve-3d;
      position: relative;
    }
    
    .parallax-child {
      position: relative;
      width: 100%;
      height: 100%;
      transform: translateZ(-2px) scale(2.01);
      z-index: -1;
    }
    
    #img-or-whatever {
      height: 900px;
      width: 100%;
      background-color: red;
      position: relative;
      z-index: -1;
    }
Run Code Online (Sandbox Code Playgroud)
<main>
      <div class="static"></div>
        
      <div class="parallax-container">
        <div class="parallax-child">
          <div id="img-or-whatever"></div>
        </div>
      </div>
    
      <div class="static"></div>
    </main>
Run Code Online (Sandbox Code Playgroud)

Ber*_*rci 2

据我所知,使用translateZ 无法达到所描述的效果。这是因为根据这篇关于 CSS 3D 的文章

...给overflow任何除visible之外的值都会有效地强制transform-style的值变为平坦,即使我们已明确将其设置为preserve-3d。

put something "above" the parallax element据我所知,隐藏溢出的唯一选择是(你说你想避免)。

如果确实没有选择将某些内容放置在视差元素“上方”,您可以尝试使用 js 执行类似的操作(例如类似这样的操作)。这并不理想,因为它意味着大量的计算和变量,并且可能需要一些时间才能完全完成您想要的任务(并且您会丢失容器内的 3D,因为您无论如何都需要溢出:隐藏)。

如果你确实需要里面的 3d,你可以使用 javascript 创建一个更复杂的解决方案,overflow: hidden也可以跳过。但我会尽量避免 if 不是强制性的(我宁愿在overflow: hidden启用 3D 的容器上添加一个绝对元素。如果您在该部分中仍然需要 3D,则为绝对容器提供透明背景)。

通常我也会建议尽量避免.js这种事情(如果可能的话),但我认为你在这里没有很多选择。