I'm trying to create multiple flip cards with HTML and CSS, that flip using jQuery. The problem I'm running into is that currently I'm only able to flip the very first card.
Any advice to make the jQuery more global and able to click/flip each card would be greatly appreciated.
Here's the example I've been using: https://codepen.io/marcwilk/pen/JjdwKZR
HTML:
<div class="scene scene--card">
<div class="card">
<div class="card__face card__face--front">front</div>
<div class="card__face card__face--back">back</div>
</div>
</div>
<div class="scene scene--card">
<div class="card">
<div class="card__face card__face--front">front</div>
<div class="card__face card__face--back">back</div>
</div>
</div>
<p>Click card to flip.</p>
CSS:
body { font-family: sans-serif; }
.scene {
width: 200px;
height: 260px;
border: 1px solid #CCC;
margin: 40px 0;
perspective: 600px;
}
.card {
position: relative;
width: 100%;
height: 100%;
cursor: pointer;
transform-style: preserve-3d;
transform-origin: center right;
transition: transform 1s;
}
.card.is-flipped {
transform: translateX(-100%) rotateY(-180deg);
}
.card__face {
position: absolute;
width: 100%;
height: 100%;
line-height: 260px;
color: white;
text-align: center;
font-weight: bold;
font-size: 40px;
backface-visibility: hidden;
}
.card__face--front {
background: red;
}
.card__face--back {
background: blue;
transform: rotateY(180deg);
}
JS:
var card = document.querySelector('.card');
card.addEventListener( 'click', function() {
card.classList.toggle('is-flipped');
});
Thanks!
Firstly, your code is pure JavaScript, and not using jQuery.
Second, the problem is that you use document.querySelector('.card') which selects the first .card element.
Your solution is to use document.querySelectorAll('.card'); and loop through it to add the click event listener:
var cards = document.querySelectorAll('.card');
cards.forEach(card => {
card.addEventListener('click', function() {
card.classList.toggle('is-flipped');
})
})
body {
font-family: sans-serif;
}
.scene {
width: 200px;
height: 260px;
border: 1px solid #CCC;
margin: 40px 0;
perspective: 600px;
}
.card {
position: relative;
width: 100%;
height: 100%;
cursor: pointer;
transform-style: preserve-3d;
transform-origin: center right;
transition: transform 1s;
}
.card.is-flipped {
transform: translateX(-100%) rotateY(-180deg);
}
.card__face {
position: absolute;
width: 100%;
height: 100%;
line-height: 260px;
color: white;
text-align: center;
font-weight: bold;
font-size: 40px;
backface-visibility: hidden;
}
.card__face--front {
background: red;
}
.card__face--back {
background: blue;
transform: rotateY(180deg);
}
<div class="scene scene--card">
<div class="card">
<div class="card__face card__face--front">front</div>
<div class="card__face card__face--back">back</div>
</div>
</div>
<div class="scene scene--card">
<div class="card">
<div class="card__face card__face--front">front</div>
<div class="card__face card__face--back">back</div>
</div>
</div>
<p>Click card to flip.</p>
Related
I am very new to web development, but I have a simple card flip animation with javascript. It works fine until I add links to the back of the cards. Once I do this it will flip the correct card but open the links from the card above. I believe it has to do with event bubbling, but I am unable to find a solution that will work.
I want all cards to work like the first one. What I mean is that the card flips when clicked on and shows the information and the links that the user can click on if they want too.
const card = document.querySelectorAll(".card__inner");
function flipCard() {
this.classList.toggle('is-flipped');
}
card.forEach((card) => card.addEventListener("click", flipCard));
:root {
--primary: #FFCE00;
--secondary: #FE4880;
--dark: #212121;
--light: #F3F3F3;
/* bottom back color*/
}
* {
margin: 0;
padding: 0;
}
body {
font-family: montserrat, sans-serif;
width: 100%;
min-height: 100vh;
}
.card {
margin: 100px auto 0;
width: 400px;
height: 600px;
perspective: 1000px;
}
.card__inner {
width: 100%;
height: 100%;
transition: transform 1s;
transform-style: preserve-3d;
cursor: pointer;
position: relative;
}
.card__inner.is-flipped {
transform: rotateY(180deg);
}
.card__face {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
overflow: hidden;
border-radius: 16px;
box-shadow: 0px 3px 18px 3px rgba(0, 0, 0, 0.2);
}
.card__face--front {
background-image: url("iFoxify.png");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
display: flex;
align-items: center;
justify-content: center;
}
.card__face--front h2 {
color: rgb(0, 0, 0);
font-size: 32px;
}
.card__face--back {
background-color: var(--light);
transform: rotateY(180deg);
}
.card__content {
width: 100%;
height: 100%;
}
.card__header {
position: relative;
padding: 30px 30px 40px;
}
.card__header:after {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: linear-gradient(to bottom left, var(--primary) 10%, var(--secondary) 115%);
z-index: -1;
border-radius: 0px 0px 50% 0px;
}
.pp {
display: block;
width: 128px;
height: 128px;
margin: 0 auto 30px;
border-radius: 50%;
background-color: rgb(0, 0, 0);
border: 5px solid rgb(0, 0, 0);
object-fit: cover;
}
.card__header h2 {
color: rgb(0, 0, 0);
font-size: 32px;
font-weight: 900;
/* text-transform: uppercase; */
text-align: center;
}
.card__body {
padding: 30px;
}
.card__body h3 {
color: var(--dark);
font-size: 24px;
font-weight: 600;
margin-bottom: 15px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Game Card</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2></h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="iFoxify.png" alt="" class="pp" />
<h2>Swift and Java
<h2>
</div>
<div class="card__body">
<h3>iFoxify</h3>
<p>A simple app that shows random pictures of foxes.</p><br><br>
<p><a href="https://play.google.com/store/apps/details?id=com.LucasDahl.ifoxify" target="_blank">Google Play</p>
<p><a href="https://apps.apple.com/us/app/ifoxify/id1576016692" target = "_blank" >iOS</p>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2></h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="babysleep.png" alt="" class="pp" />
<h2>Swift<h2>
</div>
<div class="card__body">
<h3>Baby Sleepytime</h3>
<p>A simple white noise app.</p><br><br>
<p><a href="https://apps.apple.com/us/app/baby-sleepytime/id1480001818" target = "_blank" ><img alt="ApplePlayBadge" src="Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg" width="200" height="70"></p>
</div>
</div>
</div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
You need to close out your <a> tags. You've left them open, so everything under the first tag is a link.
Change:
<p><a href = "https://play.google.com/store/apps/details?id=com.LucasDahl.ifoxify" target="_blank">Google Play</p>
To:
<p>Google Play</p>
Do that for all the card links.
I built a blackjack game. Now I want the cards of the dealer, when they appear, to flip from back to the front. I built the keyframes in CSS but I can't apply it on the JS file.
JAVASCRIPT
function deal() {
if (newgame == true) {
var random = Math.floor((Math.random() * 13));
var UserCards = document.getElementById('user');
var card = document.createElement('img');
card.setAttribute("width", 450);
card.setAttribute("src", images[random]);
UserCards.appendChild(card);
UserCards.className ='myDIV';
checkUserScore += cards[random];
if (checkUserScore > 21)
{
UserCards.appendChild(card);
alert("you hit more than 21");
}
}
EDIT: Did the OP leave out the function closing brace when pasting the code, or is that an actual error?
CSS
<style>
.myDIV {
margin: auto;
border: 1px solid black;
width: 500px;
height: 500px;
background-image:url(media/cards/UpsideDown.jpg);
color: white;
animation: mymove 5s infinite;
}
#keyframes mymove {
50% {
transform: rotate(360deg);
background-image:url(media/cards/QC.jpg);
}
}
</style>
Have you searched the web?
body {
font-family: Arial, Helvetica, sans-serif;
}
.flip-card {
background-color: transparent;
width: 300px;
height: 300px;
perspective: 1000px;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.6s;
transform-style: preserve-3d;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
}
.flip-card:hover .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-front,
.flip-card-back {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.flip-card-front {
background-color: #bbb;
color: black;
}
.flip-card-back {
background-color: #2980b9;
color: white;
transform: rotateY(180deg);
}
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<h1>Card Flip with Text</h1>
<h3>Hover over the image below:</h3>
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<img src="img_avatar.png" alt="Avatar" style="width:300px;height:300px;">
</div>
<div class="flip-card-back">
<h1>John Doe</h1>
<p>Architect & Engineer</p>
<p>We love that guy</p>
</div>
</div>
</div>
Using vanilla js, I am trying to target all elements with the class headingScroll, so when I scroll 100px from the top, it fades away. When I make the function access the DOM as getelementbyid, and then give say, my name the id name, it works, but not with classes.
Anyone have any workarounds or notice that this code is ineffective with what I am trying to do?
window.onload = function() {
const EFFECT = document.querySelectorAll('.headingScroll');
window.addEventListener('scroll', scrollEffect);
function scrollEffect() {
if(window.scrollY>100) {
EFFECT.classList.add('show');
}
else {
EFFECT.classList.remove('show')
}
}
scrollEffect('.headingScroll');
}
/*Header*/
.header-img {
background-image: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 140, 255, 0.5)), url("../images/coding-on-laptop.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: relative;
height: 100vh;
}
.header-text {
text-align: center;
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -40%);
color: white;
}
#headingName {
font-size: 4rem;
text-shadow: 1px 1px 2px rgba(0,0,0,.5);
opacity: 1;
transition: 1s ease-in-out;
}
.headingScroll.remove {
opacity: 1;
transition: 1s ease-in-out;
}
.headingScroll.show {
opacity: 0;
}
.header-social {
position: absolute;
top: 58%;
left: 50%;
transform: translate(-50%, -50%);
}
.fa {
color: white;
font-size: 2rem;
text-align: center;
text-decoration: none;
margin: 5px;
}
.fa:hover {
color:#0779e4;
transition: ease-in-out .3s;
transform: translateY(-2px);
}
.scroll_down {
position: absolute;
bottom: 20%;
left: 50%;
font-size: 2em;
transform: translate(-50%, -20%);
color: white;
padding-bottom: 20px;
text-shadow: 1px 1px 2px rgba(0,0,0,.5)
}
<!--Header-->
<header class="header-img" id="home">
<div class="triangle_1"></div>
<div class="triangle_2"></div>
<div class="header-text">
<h1 id='headingName' class="headingScroll">Alex Schmidt</h1>
</div>
<div class="header-social">
</div>
<div class='scroll_down'>
<p>Scroll</p>
<span></span>
</div>
</header>
<!--End Header-->
<!--About-->
<div class="about-wrapper" id="about">
<div class="triangle_3"></div>
<div class="triangle_4"></div>
<div class="about">
<div class="inner-about">
<h1>About</h1>
<h2>Front-end Engineer</h2>
<h3>Located in Portland, OR</h3>
</div>
</div>
You have to loop through each one to apply.
window.onload = function() {
const effects = document.querySelectorAll('.headingScroll');
window.addEventListener('scroll', scrollEffect);
function scrollEffect() {
effects.forEach(function(el){
if(window.scrollY>100) {
el.classList.add('show');
}
else {
el.classList.remove('show')
}
});
}
scrollEffect();
}
This question already has answers here:
Flip content of a div on clicking a button
(4 answers)
Closed 2 years ago.
I have created a pen here(https://codepen.io/rupamkairi/pen/ExjJRMo?editors=1100) on codepen. The card is made to rotate(specifically to Flip) when hovered on the element. I want it to be flip when I click on the element(.card).
.card {
margin: auto;
width: 5em;
height: 8em;
background-color: transparent;
perspective: 250px;
}
.card-content {
position: relative;
width: 100%;
height: 100%;
border-radius: 5px;
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.5);
transition: transform 0.5s;
transform-style: preserve-3d;
}
.card:hover .card-content {
transform: rotateY(180deg);
}
.card-front,
.card-back {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
}
.card-back {
border-radius: 5px;
background-color: white;
transform: rotateY(180deg);
}
<div class="card">
<div class="card-content">
<div class="card-front">
<h1>🎆</h1>
</div>
<div class="card-back">
<h1>🍕</h1>
</div>
</div>
</div>
I tried using :active pseudo-class but in that case I need to hold the card to keep it fliped.
Is there any way to use css animation with javascript?
I want to make multiple cards on a single page, and make them flip when clicked.
If you want the card to toggle the flip on every click try this:
const card = document.querySelector(".card");
const cardContent = document.querySelector(".card-content");
let flipped = false;
card.addEventListener("click", () => {
if(!flipped) {
cardContent.style.transform = "rotateY(180deg)"
} else {
cardContent.style.transform = "rotateY(0deg)"
}
flipped = !flipped;
});
Or if you want the card to be flipped only once try this:
const card = document.querySelector(".card");
const cardContent = document.querySelector(".card-content");
card.addEventListener("click", () => {
cardContent.style.transform = "rotateY(180deg)";
});
As it's implemented through JavaScript remove .card:hover .card-content { transform: rotateY(180deg);} from stylesheet.
Initially add the id to the div tag where class = "card" like
HTML
<div class="card" id ="card1">
<div class="card-content">
<div class="card-front">
<h1>🎆</h1>
</div>
<div class="card-back">
<h1>🍕</h1>
</div>
</div>
</div>
Here you set the id as card1 and then you must you the following simple JS like
<script>
document.getElementById("card1").onclick = function(){
document.getElementById("card1").style.transform = rotateY(180deg);
}
</script>
This is a simple way by which you can achieve what you want.
just change .card:hover .card-content
to .card.flip .card-content
and add js code:
const card = document.querySelector('.card')
card.onclick=_=>card.classList.add('flip');
card.onmouseout=_=>card.classList.remove('flip');
demo:
const card = document.querySelector('.card')
card.onclick=_=>card.classList.add('flip');
card.onmouseout=_=>card.classList.remove('flip');
html,
body {
margin: 0px;
padding: 0px;
border: 0px;
font-family: "Roboto", sans-serif;
background-color: #96cfe1;
}
.container {
padding: 10%;
}
.card {
margin: auto;
width: 5em;
height: 8em;
background-color: transparent;
perspective: 250px;
}
.card-content {
position: relative;
width: 100%;
height: 100%;
border-radius: 5px;
box-shadow: 0px 5px 15px #00000080;
transition: transform 0.5s;
transform-style: preserve-3d;
}
.card.flip .card-content {
transform: rotateY(180deg);
}
.card-front,
.card-back {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
}
.card-back {
border-radius: 5px;
background-color: white;
transform: rotateY(180deg);
}
<div class="container">
<div class="card">
<div class="card-content">
<div class="card-front">
<h1>🎆</h1>
</div>
<div class="card-back">
<h1>🍕</h1>
</div>
</div>
</div>
</div>
This question already has answers here:
Javascript - arrow functions this in event handler?
(4 answers)
Closed 4 years ago.
I'm not fully understanding 'this', I have checked another answer to the same question, but as the base code was quite different I found I was getting lost. I couldn't figure out what I should be binding meanwhile some of the other answers didn't use 'this' or binding at all.
I am trying to do something very simple, add and remove a class from a single element when clicked, but I want to apply this to multiple elements with only the one clicked triggering each time.
I would like to understand and do this in JS, not jQuery. Which would be an easy short cut but leave me just as baffled.
const flipCard = document.querySelectorAll(".card--holder");
const card = document.getElementById("card");
flipCard.forEach(card => {
card.addEventListener("click", flipCards);
})
const flipCards = () => {
if (card.classList.contains("flipped")) {
this.classList.remove("flipped");
} else {
this.classList.add("flipped");
}
}
.flip {
-webkit-perspective: 800;
width: 400px;
height: 200px;
position: relative;
margin: 50px auto;
}
.flip .card.flipped {
-webkit-transform: rotateY(-180deg);
}
.flip .card {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
}
.flip .card .face {
width: 100%;
height: 100%;
position: absolute;
-webkit-backface-visibility: hidden;
z-index: 2;
text-align: center;
line-height: 200px;
}
.flip .card .front {
position: absolute;
z-index: 1;
background: black;
color: white;
cursor: pointer;
}
.flip .card .back {
-webkit-transform: rotateY(180deg);
background: blue;
color: black;
cursor: pointer;
}
<div class="card--holder flip">
<div class="card" id="card">
<div class="face front">Front</div>
<div class="face back">Back</div>
</div>
</div>
<div class="card--holder flip">
<div class="card" id="card">
<div class="face front">Front</div>
<div class="face back">Back</div>
</div>
</div>
<div class="card--holder flip">
<div class="card" id="card">
<div class="face front">Front</div>
<div class="face back">Back</div>
</div>
</div>
Some points:
You need to define the flipCards constant before you use it.
ids have to be unique in HTML
this is incorrect in arrow functions, you need to use the first function parameter and target property to get the click target element. And as you want to have the parent selected, you need to get this with closest, because the click target is inside of the element, in your example.
const flipCards = event => {
var parent = event.target.closest(".card--holder");
if (parent.classList.contains("flipped")) {
parent.classList.remove("flipped");
} else {
parent.classList.add("flipped");
}
}
const flipCard = document.querySelectorAll(".card--holder");
const card = document.getElementById("card");
flipCard.forEach(card => {
card.addEventListener("click", flipCards);
})
.flip {
-webkit-perspective: 800;
width: 400px;
height: 200px;
position: relative;
margin: 50px auto;
}
.flip .card.flipped {
-webkit-transform: rotateY(-180deg);
}
.flip .card {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
}
.flip .card .face {
width: 100%;
height: 100%;
position: absolute;
-webkit-backface-visibility: hidden;
z-index: 2;
text-align: center;
line-height: 200px;
}
.flip .card .front {
position: absolute;
z-index: 1;
background: black;
color: white;
cursor: pointer;
}
.flip .card .back {
-webkit-transform: rotateY(180deg);
background: blue;
color: black;
cursor: pointer;
}
.flipped .card .front {
background: red !important;
}
<div class="card--holder flip">
<div class="card" id="card1">
<div class="face front">Front</div>
<div class="face back">Back</div>
</div>
</div>
<div class="card--holder flip">
<div class="card" id="card2">
<div class="face front">Front</div>
<div class="face back">Back</div>
</div>
</div>
<div class="card--holder flip">
<div class="card" id="card3">
<div class="face front">Front</div>
<div class="face back">Back</div>
</div>
</div>