Issue
The below codes defines boxes that flips when any area of the box is touched or clicked but I would rather this function was specific to a button instead so that instead of clicking on any area of the box to achieve a flip, a button is used instead. How can I tweak this code to achieve this.
I want the button within these divs to be responsible for the flip function rather than having to click on any area of the box and I would equally like to achieve this possibility in all cases.
cards.forEach(card => {
card.addEventListener('click', function() {
card.classList.toggle('is-flipped');
});
})
.flip-box {
background-color: transparent;
width: 300px;
height: 200px;
border: 1px solid #f1f1f1;
}
.card {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 1s;
transform-style: preserve-3d;
}
.flip-box-front,
.flip-box-back {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.flip-box-front {
background-color: #bbb;
color: black;
}
.flip-box-back {
background-color: #333;
color: white;
transform: rotateY(180deg);
}
.card.is-flipped {
transform: rotateY(180deg);
}
<div class="flip-box">
<div class="card">
<div class="flip-box-front">
<h2>Front Side</h2>
<p> some text </p>
<p> some text </p>
<button> click to flip </button>
</div>
<div class="flip-box-back">
<h2>Back Side</h2>
<p> some text </p>
<p> some text </p>
<button> click to flip </button>
</div>
</div>
<br/>
<div class="card">
<div class="flip-box-front">
<h2>Front Side</h2>
<p> some text </p>
<p> some text </p>
<button> click to flip </button>
</div>
<div class="flip-box-back">
<h2>Back Side</h2>
<p> some text </p>
<p> some text </p>
<button> click to flip </button>
</div>
</div>
</div>
Solution
Assuming that all the button
tags are "click to flip" and:
cards = someRoot.querySelectorAll(".card");
you can modify the code to:
cards.forEach(card => {
// For each card
card.querySelectorAll("div > button").forEach(btn => {
// For each button on the card sides
btn.addEventListener("click", ev => {
// Toggle the "is-flipped" class
ev.target.parentElement.parentElement.classList.toggle("is-flipped");
});
});
});
Full demo:
// Get all cards
var cards = document.querySelectorAll(".card");
cards.forEach(card => {
// For each card
card.querySelectorAll("div > button").forEach(btn => {
// For each button on the card sides
btn.addEventListener("click", ev => {
// Toggle the "is-flipped" class of the button parent's parent
ev.target.parentElement.parentElement.classList.toggle("is-flipped");
});
});
});
.flip-box {
background-color: transparent;
width: 300px;
height: 200px;
border: 1px solid #f1f1f1;
}
.card {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 1s;
transform-style: preserve-3d;
}
.flip-box-front,
.flip-box-back {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.flip-box-front {
background-color: #bbb;
color: black;
}
.flip-box-back {
background-color: #333;
color: white;
transform: rotateY(180deg);
}
.card.is-flipped {
transform: rotateY(180deg);
}
<div class="flip-box">
<div class="card">
<div class="flip-box-front">
<h2>Front Side</h2>
<p> some text </p>
<p> some text </p>
<button> click to flip </button>
</div>
<div class="flip-box-back">
<h2>Back Side</h2>
<p> some text </p>
<p> some text </p>
<button> click to flip </button>
</div>
</div>
<br/>
<div class="card">
<div class="flip-box-front">
<h2>Front Side</h2>
<p> some text </p>
<p> some text </p>
<button> click to flip </button>
</div>
<div class="flip-box-back">
<h2>Back Side</h2>
<p> some text </p>
<p> some text </p>
<button> click to flip </button>
</div>
</div>
</div>
Answered By - Plantt