When using the transform: rotateY(180deg)
property, text is selectable on both sides of the flipper.
When using the rotate: y 180deg
property, the text on the back side is not available for selection, because front div
higher than back div
.
Is it possible to somehow solve this problem?
const btn = document.querySelector("button");
const flipperInner1 = document.querySelector(".option1 .flipper__inner");
const flipperInner2 = document.querySelector(".option2 .flipper__inner");
btn.addEventListener("click", () => {
flipperInner1.classList.toggle("flipper__inner--flipped")
flipperInner2.classList.toggle("flipper__inner--flipped")
})
/* COMMON STYLES */
.flipper {
inline-size: 300px;
block-size: 100px;
perspective: 1000px;
}
.flipper__inner {
position: relative;
inline-size: 100%;
block-size: 100%;
border: 1px solid #000;
transform-style: preserve-3d;
transition: transform 0.3s, rotate 0.3s;
}
.flipper__side {
position: absolute;
inset: 0;
backface-visibility: hidden;
}
.flipper__side--front {
z-index: 2;
}
/* Option 1: transform: rotate(180deg) */
.option1 .flipper__inner--flipped,
.option1 .flipper__side--back {
transform: rotateY(180deg);
}
/* Option 2: rotate: y 180deg */
.option2 .flipper__inner--flipped,
.option2 .flipper__side--back {
rotate: y 180deg;
}
<h2>Option 1: transform: rotate(180deg)</h2>
<div >
<div >
<div >Front (text is selectable)</div>
<div >Back (text is selectable)</div>
</div>
</div>
<h2>Option 2: rotate: y 180deg</h2>
<div >
<div >
<div >Front (text is selectable)</div>
<div >Back (text is NOT selectable, because `front div` higher than `back div`)</div>
</div>
</div>
<br/>
<button>CLICK TO FLIP BOTH FLIPPERS</button>
CodePudding user response:
use pointer-events
so the front text cannot be selected
const btn = document.querySelector("button");
const flipperInner1 = document.querySelector(".option1 .flipper__inner");
const flipperInner2 = document.querySelector(".option2 .flipper__inner");
btn.addEventListener("click", () => {
flipperInner1.classList.toggle("flipper__inner--flipped")
flipperInner2.classList.toggle("flipper__inner--flipped")
})
/* COMMON STYLES */
.flipper {
inline-size: 300px;
block-size: 100px;
perspective: 1000px;
}
.flipper__inner {
position: relative;
inline-size: 100%;
block-size: 100%;
border: 1px solid #000;
transform-style: preserve-3d;
transition: transform 0.3s, rotate 0.3s;
}
.flipper__side {
position: absolute;
inset: 0;
backface-visibility: hidden;
}
.flipper__side--front {
z-index: 2;
}
/* Option 1: transform: rotate(180deg) */
.option1 .flipper__inner--flipped,
.option1 .flipper__side--back {
transform: rotateY(180deg);
}
/* Option 2: rotate: y 180deg */
.option2 .flipper__inner--flipped,
.option2 .flipper__side--back {
rotate: y 180deg;
}
.flipper__inner--flipped .flipper__side--front {
pointer-events:none;
}
<h2>Option 1: transform: rotate(180deg)</h2>
<div >
<div >
<div >Front (text is selectable)</div>
<div >Back (text is selectable)</div>
</div>
</div>
<h2>Option 2: rotate: y 180deg</h2>
<div >
<div >
<div >Front (text is selectable)</div>
<div >Back (text is NOT selectable, because `front div` higher than `back div`)</div>
</div>
</div>
<br/>
<button>CLICK TO FLIP BOTH FLIPPERS</button>
CodePudding user response:
You could add the following css which puts the back over the front when flipped.
.flipper__inner--flipped .flipper__side--front {
z-index:-1;
}