iamkeir iamkeir - 3 months ago 31
CSS Question

Backface visibility bug in Firefox/IE (scroll-wipe UI like Life Socks)

I was intrigued by the 'wiping scroll' functionality of http://lifesocks.me/ (which uses JS and Skrollr) and wanted to try and achieve it with CSS only, without hijacking native scrolling.

I managed to get pretty much 90% of the way there:
http://codepen.io/iamkeir/pen/yJKJNG



html, body { height: 100%; }
a { color: white; }
a:hover { text-decoration: none; }

.slide {
height: 100vh;
position: relative;
z-index: 1;
font-size: 10vw;
color: white;
text-align: center;
overflow: hidden;
backface-visibility: hidden;
}

.slide__inner {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 100%;
overflow: hidden;
backface-visibility: hidden;
}

.slide--1 { background: red; }
.slide--2 { background: blue; }
.slide--3 { background: green; }
.slide--4 { background: grey; }

<div class="slide slide--1">
<div class="slide__inner"><a href="#test-1">Slide 1</a></div>
</div>

<div class="slide slide--2">
<div class="slide__inner"><a href="#test-2">Slide 2</a></div>
</div>

<div class="slide slide--3">
<div class="slide__inner"><a href="#test-3">Slide 3</a></div>
</div>

<div class="slide slide--4">
<div class="slide__inner"><a href="#test-4">Slide 4</a></div>
</div>





Two issues remain:

1) The backface visibility trick does not seem to work in Firefox or IE11/Edge but I am not sure why.

2) Because of the z-index stack, you cannot interact with text/links on previous slides as the last slide is essentially 'on top'.

Regarding 2, I tried using JS to bring the 'current' slide to the top of the z-index stack but this is clunky - when is a slide 'current', when it is halfway up?

Would be great to get other's input on both the bug in 1 and any ideas for 2.

EDIT

Here is a Codepen of the JS 'focus' functionality - as I said, clunky!
http://codepen.io/iamkeir/pen/akxRwj

Answer

The backface visibility "trick" sounds like a Chrome / Webkit bug to me. overflow: hidden is not supposed to apply to elements whose containing block is outside the overflow: hidden element.

The effect you're looking for can be achieved using the clip property. The clip property applies to all descendants, not just to containing block descendants. See this BBC page for an example.

Unfortunately, since the clip property only applies on position: absolute elements, you need three elements per slide. Here's how you do it:

body { margin: 0; }
a { color: white; }
a:hover { text-decoration: none; }

.slide {
  height: 100vh;
  position: relative;
  font-size: 10vw;
  color: white;
  text-align: center;
}

.slide__wrapper {
  position: absolute;
  clip: rect(auto auto auto auto);
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.slide__inner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.slide--1 { background: red; }
.slide--2 { background: blue; }
.slide--3 { background: green; }
.slide--4 { background: grey; }
<div class="slide slide--1">
  <div class="slide__wrapper"><div class="slide__inner"><a href="#test-1">Slide 1</a></div></div>
</div>

<div class="slide slide--2">
  <div class="slide__wrapper"><div class="slide__inner"><a href="#test-2">Slide 2</a></div></div>
</div>

<div class="slide slide--3">
  <div class="slide__wrapper"><div class="slide__inner"><a href="#test-3">Slide 3</a></div></div>
</div>

<div class="slide slide--4">
  <div class="slide__wrapper"><div class="slide__inner"><a href="#test-4">Slide 4</a></div></div>
</div>

Comments