John
John

Reputation: 33

z-index lost until end of transition

I've been playing around with "folding" elements using rotate3d(), and I ran into a problem with half of my fold - during the transition, the z-index isn't respected, but at the end, it pops to the top. I suspect it has something to do with the z part of rotate3d() (similar to here), but it's only happening on one of two elements, and I can't figure out what the difference is.

var button = $('.button');
var open = true;

button.click(() => {
  var right = $('.triangle.topright');
  var left = $('.triangle.topleft');

  if (open) {
    right.addClass('r-close');
    left.addClass('l-close');
  } else {
    right.removeClass('r-close');
    left.removeClass('l-close');
  }

  open = !open;
});
.container {
  box-sizing: border-box;
  display: flex;
  padding: 50px 75px;
  position: relative;
  height: 300px;
  width: 100%;
}

.fold.r-close {
  transform-origin: left;
  transform: rotate3d(0, 1, 0, 90deg);
}

.fold {
  box-sizing: border-box;
  display: inline-block;
  height: 100px;
  width: 100px;
  position: relative;
  transition: all 1.5s;
  transform-style: preserve-3d;
}

.fold.outer {
  width: 150px;
}

.fold.left {
  margin-left: 50px;
}

.triangle {
  height: 0;
  position: absolute;
  transition: all 1.5s;
  width: 0;
}

/* middle */
.triangle.middle {
  top: 0;
  z-index: -1 !important;
}

.triangle.middle.left {
  border-bottom: 100px solid pink;
  border-left: 100px solid transparent;
  right: 0;
}

.triangle.middle.right {
  border-bottom: 100px solid pink;
  border-right: 100px solid transparent;
  left: 0;
}

/* right fold */
.triangle.topright.front {
	border-bottom: 100px solid red;
	border-right: 100px solid transparent;
  backface-visibility: hidden;
  transform: rotate3d(1, 1, 0, 180deg);
}

.triangle.topright.back {
  backface-visibility: hidden;
  border-left: 100px solid transparent;
  border-top: 100px solid pink;
  left: -0.6px;
}

/* left fold */
.triangle.topleft.front {
	border-bottom: 100px solid red;
	border-left: 100px solid transparent;
  backface-visibility: hidden;
  transform: rotate3d(-1, 1, 0, 180deg);
}

.triangle.topleft.back {
  backface-visibility: hidden;
  border-top: 100px solid pink;
  border-right: 100px solid transparent;
  right: -0.6px;
}

/* folds */
.r-close.back {
  transform: rotate3d(1, 1, 0, 180deg);
}

.triangle.r-close.front {
  transform: rotate3d(1, 1, 0, 0deg);
}

.l-close.back {
  transform: rotate3d(-1, 1, 0, 180deg);
}

.triangle.l-close.front {
  transform: rotate3d(-1, 1, 0, 0deg);
}

.button {
  bottom: 0;
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="fold outer">
    <div class="triangle middle left"></div>
    <div class="fold left">
      <div class="triangle topleft front"></div>
      <div class="triangle topleft back"></div>
    </div>
  </div>
  <div class="fold outer">
    <div class="triangle middle right"></div>
    <div class="fold right">
      <div class="triangle topright front"></div>
      <div class="triangle topright back"></div>
    </div>
  </div>
  <button class="button">Click</button>
</div>

https://jsfiddle.net/jonkani/p5858nso/

Upvotes: 3

Views: 154

Answers (1)

Temani Afif
Temani Afif

Reputation: 273807

This behavior is logical, it's a bit difficult to explain but it's due to the direction of the rotation. If you look closely you will see that the right part turn by going to the top (considering the Z axis) but the the left part turn by going to the bottom that why it's hidden while rotating.

In order to correct this, you need to inverse the rotation of the left part to make it behave like the right one. Instead of 0deg you need to use 360deg.

var button = $('.button');
var open = true;

button.click(() => {
  var right = $('.triangle.topright');
  var left = $('.triangle.topleft');

  if (open) {
    right.addClass('r-close');
    left.addClass('l-close');
  } else {
    right.removeClass('r-close');
    left.removeClass('l-close');
  }

  open = !open;
});
.container {
  box-sizing: border-box;
  display: flex;
  padding: 50px;
  position: relative;
  width: 100%;
}

.fold.r-close {
  transform-origin: left;
  transform: rotate3d(0, 1, 0, 90deg);
}

.fold {
  box-sizing: border-box;
  display: inline-block;
  height: 100px;
  width: 100px;
  position: relative;
  transition: all 1.5s;
  transform-style: preserve-3d;
}

.fold.outer {
  width: 150px;
}

.fold.left {
  margin-left: 50px;
}

.triangle {
  height: 0;
  position: absolute;
  transition: all 1.5s;
  width: 0;
}

/* middle */
.triangle.middle {
  top: 0;
  z-index: -1 !important;
}

.triangle.middle.left {
  border-bottom: 100px solid pink;
  border-left: 100px solid transparent;
  right: 0;
}

.triangle.middle.right {
  border-bottom: 100px solid pink;
  border-right: 100px solid transparent;
  left: 0;
}

/* right fold */
.triangle.topright.front {
	border-bottom: 100px solid red;
	border-right: 100px solid transparent;
  backface-visibility: hidden;
  transform: rotate3d(1, 1, 0, 180deg);
}

.triangle.topright.back {
  backface-visibility: hidden;
  border-left: 100px solid transparent;
  border-top: 100px solid pink;
  left: -0.6px;
}

/* left fold */
.triangle.topleft.front {
	border-bottom: 100px solid red;
	border-left: 100px solid transparent;
  backface-visibility: hidden;
  transform: rotate3d(-1, 1, 0, 180deg);
}

.triangle.topleft.back {
  backface-visibility: hidden;
  border-top: 100px solid pink;
  border-right: 100px solid transparent;
  right: -0.6px;
}

/* folds */
.r-close.back {
  transform: rotate3d(1, 1, 0, 180deg);
}

.triangle.r-close.front {
  transform: rotate3d(1, 1, 0, 0deg);
}

.l-close.back {
  transform: rotate3d(-1, 1, 0, 180deg);
}

.triangle.l-close.front {
  transform: rotate3d(-1, 1, 0, 360deg); /*Updated this*/
}

.button {
  bottom: 0;
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="fold outer">
    <div class="triangle middle left"></div>
    <div class="fold left">
      <div class="triangle topleft front"></div>
      <div class="triangle topleft back"></div>
    </div>
  </div>
  <div class="fold outer">
    <div class="triangle middle right"></div>
    <div class="fold right">
      <div class="triangle topright front"></div>
      <div class="triangle topright back"></div>
    </div>
  </div>
  <button class="button">Click</button>
</div>

Upvotes: 1

Related Questions