1

I try to have an CSS animated Book in an parallax scroll effect in the header.

Both use CSS 3D transformation. This works fine in Chromium based browsers but not in Firefox.

Removing following transform let the book displayed fine, but also removes the parallax effect.

.container {
    /* … */
    transform: translateZ(-1px) scale(2);
    /* … */
 }

Chromium based:
working screenshot

Firefox:
screenshot of problem

The book is based on: https://3dbookcovergenerator.netlify.app/

I haven't found any note that nested translations are not supported, here is actually a sample that works in FireFox.

Would be nice if someone could give me a hint to answer one (or more) of following questions:

  • Is it just not supported on Firefox?
  • Is just wrong and only works by chance on Chromiums?
  • Is there an alternative implementation, that works across browsers (preferable pure CSS and no JS)?

Thanks in advance


A minimal sample:

.book-container {
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 600px;
}

@keyframes initAnimation {
  0% {
    transform: rotateY(-90deg);
  }

  100% {
    transform: rotateY(-30deg);
  }
}

.book {
  width: 200px;
  height: 300px;
  position: relative;
  transform-style: preserve-3d;
  transform: rotateY(-30deg);
  transition: 1s ease;
  animation: 1s ease 0s 1 initAnimation;
}

.container:hover .book {
  transform: rotateY(-90deg);
}

.book> :first-child {
  z-index: 5;
  position: absolute;
  top: 0;
  left: 0;
  width: 200px;
  height: 300px;
  transform: translateZ(25px);
  border-radius: 0 2px 2px 0;
  box-shadow: 5px 5px 20px #666;
}

.book::after {
  z-index: 4;
  position: absolute;
  content: ' ';
  background-color: blue;
  left: 0;
  top: 3px;
  width: 48px;
  height: 294px;
  transform: translateX(172px) rotateY(90deg);
  background: linear-gradient(90deg,
      #fff 0%,
      #f9f9f9 5%,
      #fff 10%,
      #f9f9f9 15%,
      #fff 20%,
      #f9f9f9 25%,
      #fff 30%,
      #f9f9f9 35%,
      #fff 40%,
      #f9f9f9 45%,
      #fff 50%,
      #f9f9f9 55%,
      #fff 60%,
      #f9f9f9 65%,
      #fff 70%,
      #f9f9f9 75%,
      #fff 80%,
      #f9f9f9 85%,
      #fff 90%,
      #f9f9f9 95%,
      #fff 100%);
}

.book::before {
  z-index: 3;
  position: absolute;
  top: 0;
  left: 0;
  content: ' ';
  width: 200px;
  height: 300px;
  transform: translateZ(-25px);
  background-color: #01060f;
  border-radius: 0 2px 2px 0;
  box-shadow: -10px 0 50px 10px #666;
}

.root {
  perspective: 1px;
  perspective-origin: center top;
  transform-style: preserve-3d;

  height: 150vh;
  max-height: 100%;
  overflow-x: hidden;
}

.container {
  padding-top: 20rem;
  transform: translateZ(-1px) scale(2);
  background-color: #666;
}

.container:hover {
  background-color: green;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

.palceholde {
  transform: translateZ(0px);
  background-color: wheat;
  height: 150vh;
}

.book-cover {
  background-color: aqua;
  height: 100%;
  width: 100%;
  position: absolute;
  padding: 2rem;
  box-sizing: border-box;
  top: 0;
  left: 0;
}
<div class="root">
  <div class="container">
    <a class="book-container" href="" target="_blank" rel="noreferrer noopener">
      <div class="book">
        <div class="book-cover">
          <h1>Foo</h1>
          <strong>BAR</strong>
        </div>
      </div>
    </a>
  </div>
  <div class="palceholde">
  </div>
</div>

1
  • 1
    @AndrewMorton Sorry I could be clearer, I know what CSS is responsible. It is the transform on the container class. Removing that will repair the book, but I will loose the parallax scrolling. I edited the question to actually state that… Commented Apr 22 at 17:36

1 Answer 1

0

Not sure the exact cause of your bug, probably just a Firefox bug. But you've got a pretty complicated setup, and the more complicated your 3d transforms are, the more likely you'll run into a browser bug.

One thing that stood out is that on .root you have a perspective of only 1 pixel, which you're compensating for by using a scale on .container. You could just use a way higher value for perspective and remove the scale, so the browser doesn't have to do all the math on everything inside that scaled div. Making that one change ultimately solves the problem in Firefox.

However, I also noticed you have two different elements with perspective on them, when you could just have one, so in the answer below I made that change and don't have any perspective on .root at all. This then removes the need for a non-default perspective-origin.

Then we can simplify some more by removing unnecessary z-indexes and transforms (e.g., just transform the back of the book backwards 50px instead of moving it back 25px and moving the cover forward 25px). And we can just define the book size in pixels one time and use percentages for the child elements.

End result:

.book-container {
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 600px;
  transform-style: preserve-3d;
}

@keyframes initAnimation {
  0% {
    transform: rotateY(-90deg);
  }
  100% {
    transform: rotateY(-30deg);
  }
}

.book {
  width: 200px;
  height: 300px;
  position: relative;
  transform-style: preserve-3d;
  transform: rotateY(320deg) translateZ(0);
  transition: 1s ease;
  z-index: 0;
}

.container:hover .book {
  transform: rotateY(270deg);
}

.book-cover {
  position: absolute;
  top: 0;
  left: 0;
  background-color: aqua;
  height: 100%;
  width: 100%;
  padding: 2rem;
  box-sizing: border-box;
  border-radius: 0 2px 2px 0;
  box-shadow: 5px 5px 20px #666;
}

.book::before {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  width: 100%;
  height: 100%;
  transform: translateZ(-50px);
  background-color: #01060f;
  border-radius: 0 2px 2px 0;
  box-shadow: -10px 0 50px 10px #666;
}

.book::after {
  content: '';
  display: block;
  position: absolute;
  left: 100%;
  top: 3px;
  width: 48px;
  height: calc(100% - 6px);
  transform: rotateY(90deg) translateZ(-4px);
  background: linear-gradient(
    90deg,
    #fff 0%,
    #f9f9f9 5%,
    #fff 10%,
    #f9f9f9 15%,
    #fff 20%,
    #f9f9f9 25%,
    #fff 30%,
    #f9f9f9 35%,
    #fff 40%,
    #f9f9f9 45%,
    #fff 50%,
    #f9f9f9 55%,
    #fff 60%,
    #f9f9f9 65%,
    #fff 70%,
    #f9f9f9 75%,
    #fff 80%,
    #f9f9f9 85%,
    #fff 90%,
    #f9f9f9 95%,
    #fff 100%
  );
  transform-origin: left center;
}

.root {
  height: 150vh;
  max-height: 100%;
  overflow-x: hidden;
}

.container {
  padding: 10rem 0;
  background-color: #666;
}

.container:hover {
  background-color: green;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

.palceholde {
  transform: translateZ(0px);
  background-color: wheat;
  height: 150vh;
}
<div class="root">
  <div class="container">
    <a class="book-container" href="" target="_blank" rel="noreferrer noopener">
      <div class="book">
        <div class="book-cover"><h1>Foo</h1><strong>BAR</strong></div>
      </div>
    </a>
  </div>
  <div class="palceholde">
  </div>
</div>

2
  • Thank you for your answer, but while the book now works, the parallax effect is gone. I need to set perspective on root class (a value of 0 also works) and transform: translateZ with a negative value on container class to have the parallax effect. the perspective-origin is so it is position at the top. Leaving anything out of the first 2 will prevent the parallax effect. But it still may be more complicated than it should be… :( Commented Apr 23 at 6:23
  • @lokimidgard you're right, I got so focused on the book that I totally missed the parallax part. My apologies. After playing around with it for a while. it's definitely a difficult problem. I was not able to get both the parallax and book looking good in Firefox and don't have more time to get into it right now. Since the nested perspectives seem to be the major problem, I would see if maybe you can pull off the parallax some other way. Maybe a separate container that scrolls besides the body. I was experimenting with that, and it seemed promising, but I didn't quite get there.
    – cjl750
    Commented Apr 23 at 19:19

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.