Making a cutout-like div with a z-translated background

105 Views Asked by At

I want to make divs which got backgrounds that have this 3d-effect while scrolling, that one can achieve with translateZ. In the end it should look like cutouts or windows and through them you can see the (background-)images.
edit: So, if you scroll through the page you can see those boxes/cutouts but the images inside them are moving slower while scrolling to create the effect that they are further away. end of edit

What I have in mind is to have one div for the cutout and then another div inside it for the background. So, i set it up and it didn't work. It turns out that the overflow: hidden; of the outer div somehow blocks the transform: translateZ(-5px) scale(1.05); of its child.

Here is what I have got so far:

body {
  perspective: 100px;
  transform-style: preserve-3d;
  
  overflow-x: hidden;
  overflow-y: scroll;
}

#artwork, #photos {
  width: 800px;
  padding: 0 50px;
  box-sizing: border-box;
 
  display: flex;
  justify-content: space-between;
}

.pic {
  /*position: relative;*/
  width: 200px;
  height: 100px;

  display: inline-block;

  background: #aaa;
  border-radius: 10px;

  box-shadow: inset 0 10px 30px rgba(0,0,0,.3);
}

#artwork > * {
  overflow: hidden;
}

.pic div {
  position: absolute;
  width: 200px;
  height: 110px;

  background: #660; /*couldn't put an image here*/
  background-size: cover;

  transform: translateZ(-5px) scale(1.05);
}
<section id="artwork">
  <div class="pic"><div></div></div>
  <div class="pic"><div></div></div>
  <div class="pic"><div></div></div>
</section>

P.S.: I don't want to achieve the effect via JavaScript because it's not working smoothly on most computers.

edit n°2: my approaches so far:
- making extra tick borders to cover overlapping parts of the image divs; instead of using overflow: hidden >> parts are sometimes still overlapping on some screen sizes & it takes a lot of space
- creating a clip-path to use as overflow: hidden >> clip-paths also break the translateZ
- playing around with display and position on both outer and inner div >> only solutions without cutout
- Ztranslating the parent of the outer div further away and then bringing the outer div close again >> still blocked by the overflow: hidden;

1

There are 1 best solutions below

0
On

I found a workaround, although it's a compromise because the border radius isn't working. I added thick borders in the background color to the outer divs and set the z-index of the inner divs to something negative.

body {
  height: 200px;
  
  perspective: 100px;
  transform-style: preserve-3d;
  
  overflow-x: hidden;
  overflow-y: scroll;
}

#artwork {
  width: 800px
  padding: 0 50px;
  box-sizing: border-box;
  
  display: flex;
  justify-content: space-between;
}

.pic {
  width: 200px;
  height: 100px;
  margin: -40px;
  
  display: inline-block;
  
  background: transparent;
  border: 40px solid hsl(30, 50%, 90%);
  box-shadow: inset 0 10px 30px rgba(0,0,0,.3);
}

.pic div {
  position: absolute;
  width: 200px;
  height: 110px;
  
  background: linear-gradient(135deg, rgba(240,183,161,1) 0%,rgba(140,51,16,1) 50%,rgba(117,34,1,1) 51%,rgba(191,110,78,1) 100%);
  
  transform: translateZ(-5px) scale(1.05) translateY(-1vw);
  z-index: -20;
}

#artwork div:nth-child(2) div, #photos div:nth-child(2) div {transform: translateZ(-5px) scale(1.05) translateX(-1.5vw) translateY(-1vw);}
#artwork div:nth-child(4) div, #photos div:nth-child(4) div {transform: translateZ(-5px) scale(1.05) translateX(1.5vw) translateY(-1vw);}
<br><br><br><br><br><br><br>
<section id="artwork">
  <div class="pic"><div></div></div>
  <div class="pic"><div></div></div>
  <div class="pic"><div></div></div>
</section>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

that code snippet doesn't work here for some reason. For me however it works in the browser. It would be nice if someone could suggest another possible solution as this one works with only some screen sizes.