Flipping all cards, but want to flip one by one

Viewed 533

I am trying to flip these cards one by one, but they are flipping all together.

I believe I am missing something on my javaScript.

On the original code I am using images in front and an unordered list in back, I tried to resume it here writing only "Front" and "Back".

$(".flip").click(function() {
  $(".card").toggleClass("flipped");
});
.card-container {
  display: flex;
}
.card {
  width: 300px;
  height: 6rem;
  margin: 30px;
  transform-style: preserve-3d;
  transition: transform 1s;
}

.card figure {
  margin: 0;
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
}

.card figure figcaption {
  padding: 0 1rem;
  backface-visibility: hidden;
  border: 1px solid gray;
}

.card button.flip {
  position: absolute;
  right: 1rem;
  margin: 0;
}

.card button.flip {
  top: 1rem;
}

.card .back {
  transform: rotateY( 180deg);
}

.card.flipped {
  transform: rotateY( 180deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card-container">
  <div class="card">
    <figure class="front">
      <figcaption>
        <h2>FRONT 1</h2>
        <button class="flip">+</button>
      </figcaption>
    </figure>
    <figure class="back">
      <figcaption>
        <h2>BACK 1</h2>
        <button class="flip">-</button>
      </figcaption>
    </figure>
  </div>

  <div class="card">
    <figure class="front">
      <figcaption>
        <h2>FRONT 2</h2>
        <button class="flip">+</button>
      </figcaption>
    </figure>
    <figure class="back">
      <figcaption>
        <h2>BACK 2</h2>
        <button class="flip">-</button>
      </figcaption>
    </figure>
  </div>
</div>

Do you guys know what am I doing wrong?

5 Answers

Instead of flipping all elements of class .card, you can flip only the one that the button is in, using the .closest() method (which traverses UP the DOM tree until it finds an element with the specified class).

$(this).closest(".card").toggleClass("flipped");

$(".flip").click(function() {
  $(this).closest(".card").toggleClass("flipped");
});
.card-container {
  display: flex;
}
.card {
  width: 300px;
  height: 6rem;
  margin: 30px;
  transform-style: preserve-3d;
  transition: transform 1s;
}

.card figure {
  margin: 0;
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
}

.card figure figcaption {
  padding: 0 1rem;
  backface-visibility: hidden;
  border: 1px solid gray;
}

.card button.flip {
  position: absolute;
  right: 1rem;
  margin: 0;
}

.card button.flip {
  top: 1rem;
}

.card .back {
  transform: rotateY( 180deg);
}

.card.flipped {
  transform: rotateY( 180deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card-container">
  <div class="card">
    <figure class="front">
      <figcaption>
        <h2>FRONT 1</h2>
        <button class="flip">+</button>
      </figcaption>
    </figure>
    <figure class="back">
      <figcaption>
        <h2>BACK 1</h2>
        <button class="flip">-</button>
      </figcaption>
    </figure>
  </div>

  <div class="card">
    <figure class="front">
      <figcaption>
        <h2>FRONT 2</h2>
        <button class="flip">+</button>
      </figcaption>
    </figure>
    <figure class="back">
      <figcaption>
        <h2>BACK 2</h2>
        <button class="flip">-</button>
      </figcaption>
    </figure>
  </div>
</div>

$(".flip").click(function() {
  $(this).closest(".card").toggleClass("flipped");
});
.card-container {
  display: flex;
}
.card {
  width: 300px;
  height: 6rem;
  margin: 30px;
  transform-style: preserve-3d;
  transition: transform 1s;
}

.card figure {
  margin: 0;
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
}

.card figure figcaption {
  padding: 0 1rem;
  backface-visibility: hidden;
  border: 1px solid gray;
}

.card button.flip {
  position: absolute;
  right: 1rem;
  margin: 0;
}

.card button.flip {
  top: 1rem;
}

.card .back {
  transform: rotateY( 180deg);
}

.card.flipped {
  transform: rotateY( 180deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card-container">
  <div class="card">
    <figure class="front">
      <figcaption>
        <h2>FRONT 1</h2>
        <button class="flip">+</button>
      </figcaption>
    </figure>
    <figure class="back">
      <figcaption>
        <h2>BACK 1</h2>
        <button class="flip">-</button>
      </figcaption>
    </figure>
  </div>

  <div class="card">
    <figure class="front">
      <figcaption>
        <h2>FRONT 2</h2>
        <button class="flip">+</button>
      </figcaption>
    </figure>
    <figure class="back">
      <figcaption>
        <h2>BACK 2</h2>
        <button class="flip">-</button>
      </figcaption>
    </figure>
  </div>
</div>

You have used the .card class, rather than identify cards one by one by their ids. Thus when you attempt to flip, you end up flipping all the cards. You need to uniquely identify your cards by id so that you can identify which specific cards you want to flip.

const cardElement = document.querySelectorAll('.card');
for(let i = 0; i < cardElement.length; i++) {
  cardElement[i].addEventListener('click',function(){
    this.classList.add('flipped')
  })
}
.card-container {
  display: flex;
}
.card {
  width: 300px;
  height: 6rem;
  margin: 30px;
  transform-style: preserve-3d;
  transition: transform 1s;
}

.card figure {
  margin: 0;
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
}

.card figure figcaption {
  padding: 0 1rem;
  backface-visibility: hidden;
  border: 1px solid gray;
}

.card button.flip {
  position: absolute;
  right: 1rem;
  margin: 0;
}

.card button.flip {
  top: 1rem;
}

.card .back {
  transform: rotateY( 180deg);
}

.card.flipped {
  transform: rotateY( 180deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card-container">
  <div class="card">
    <figure class="front">
      <figcaption>
        <h2>FRONT 1</h2>
        <button class="flip">+</button>
      </figcaption>
    </figure>
    <figure class="back">
      <figcaption>
        <h2>BACK 1</h2>
        <button class="flip">-</button>
      </figcaption>
    </figure>
  </div>

  <div class="card">
    <figure class="front">
      <figcaption>
        <h2>FRONT 2</h2>
        <button class="flip">+</button>
      </figcaption>
    </figure>
    <figure class="back">
      <figcaption>
        <h2>BACK 2</h2>
        <button class="flip">-</button>
      </figcaption>
    </figure>
  </div>
</div>

Maybe you should get first all the element that has card class and then loop it, something like this. Btw, I am using javascript and not jQuery.

const cardElement = document.querySelectorAll('.card');

Then use loop all variable that holds the elements.

for(let i = 0; i < cardElement.length; i++) {
  cardElement[i].addEventListener('click',function(){
    this.classList.add('flipped')
  })
}

You may try on how to toggle the flipped class.

Further to your other question in the comments (that of learning jQuery and/or React)... I started answering you in a comment and quickly ran out of room, so I decided to turn a very long comment into another answer.

There were two reasons to use jQuery, both now outdated.

The first was browser compatibility, mostly concerning IE. Generally, we had to write code for two browsers: IE and all the rest of them (as a group). IE was that different - it had to be dealt with separately. But since Microsoft finally killed the disaster known as IE, that first reason is no longer necessary.

Aside: why was IE so different? It wasn't because the Microsoft programmers were lousy... it was because Microsoft (a commercial, for-profit company) was entering into an environment (the Internet) where software products were given away for free. Not only the browsers (Firefox, Netscape Navigator) but more importantly: the servers. How could Microsoft compete with free servers like Linux and backend languages like PHP, Perl, etc? Their solution? Create a new browser that was included on every computer (Windows had like 95% of the personal computer market) and only worked well with the Microsoft webserver (Internet Information Server, or IIS). With all other webservers, websites just didn't display quite right on IE... programmers had to figure out hacks and do backflips - but with MS IIS as the webserver, everything worked correctly. SO if you are a bank, or a major multinational, looking to create a presence on the new WorldWideWeb, are you going to take risks that your site might look like crap on the most-used browser on Earth? No, you are going to purchase MS IIS and put it on a Windows server, serviced by Microsoft certified technicians. Ka-Ching, Ka-Ching and Ka-Ching.

The second was simplifying javascript. jQuery has routines like $.each() and $.ajax() and .on() that were much easier and less convoluted than pure javascript. However, so-called "modern javascript" (es6, etc) has gradually added new functions and methods that fixed this deficiency and left jQuery behind. Today, learn javascript! jQuery is still good to know, but with all your learning, learn javascript.

jQuery is still good to know because it is still used on ~ 70% of websites and was a core component in many other libraries, like Bootstrap 3 and 4. But first and foremost, one should know how to do stuff in native javascript. Here are a few posts that show how to do jQuery things in new javascript patterns.

Faster way to select an element in pure JS

jQuery remove() equivalent in pure JS


Finally, regarding learning React.

It depends on what your end goal is. If your goal is to be employable, then yes, React / Angular / Vue.js are good to know. However, if you are chiefly interested in making webpages do amazing things, then: javascript is critical, graphing libraries (D3.js, Dash-Plotly, etc) are important, the Python language is very heavily used in scientific and math/graphing environments, and PHP is a very robust back end with a ton of pre-written code. (Never forget that Facebook only recently began moving away from PHP and MySQL to their own in-house system (React) ).

Here is another answer that adds some important information regarding learning React:

Site coded in React, displaying blank page on GitHub Pages

Related