Flipping and expanding cards with CSS3

I am attempting to create a layout with a collection of cards/divs within a container. When a card/div is clicked, it should flip horizontally and expand to occupy the entire space within the container (essentially resizing to 100% x 100% when clicked). I am not certain if this is achievable, as most examples I have come across show the card/div maintaining its original size.

Here is the fiddle that I tried working on, but I am struggling to implement the basic flipping functionality: https://jsfiddle.net/4dazznb5/

$('.card').click(function(){
  $(this).addClass('flipped').mouseleave(function(){
    $(this).removeClass('flipped');
  });
  return false;
});
.cards {
  width: 100%;
  height: 100%;
  background: gray;
  padding: 10px;
  box-sizing: border-box;
  
  position: relative;
  -webkit-perspective: 800;
  perspective: 800;
}

.cards .card {
  -webkit-transform-style: preserve-3d;
  -webkit-transition: 0.5s;
}

.flip .card .face {
  width: 100%;
  position: absolute;
  -webkit-backface-visibility: hidden ;
  z-index: 2;
}

.flip .card .front {
  position: absolute;
  z-index: 1;
  background: black;
}

.flip .card .back {
  -webkit-transform: rotatex(-180deg);
  background: white;
}

.cards .card.flipped {
  -webkit-transform: rotatex(-180deg);
}

.card {
  width: 100%;
  background: lightgray;
  padding: 6px;
  margin: 10px 0;
  box-sizing: border-box;
  
  cursor: pointer;
  
  position: relative;
  position: absolute;
  transform-style: preserve-3d;
  transition: transform 1s;
}

.card:nth-of-type(1) {
  margin-top: 0;
}

.card figure {
  margin: 0;
  display: block;
  position: absolute;
  width: 100%;
  backface-visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width: 400px; height: 600px;">
  <div class="cards">
    <div class="card">
      <div class="face front">Card 1 Front</div>
      <div class="face back">Card 2 Back</div>
    </div>
    <div class="card">
      <div class="face front">Card 2 Front</div>
      <div class="face back">Card 2 Back</div>
    </div>
    <div class="card">
      <div class="face front">Card 3 Front</div>
      <div class="face back">Card 3 Back</div>
    </div>
  </div>
</div>

Answer №1

Upon discovering that Tambo's backfaces were more efficient in allowing HTML content, I decided to merge our answers and create a solution that works flawlessly on both Mozilla and Chrome:

$('.card').click(function(){  
 
  if (!$(this).hasClass("flipped")) {
  $( ".face" ).addClass( 'off' );
  $( this ).children( ".face" ).removeClass( 'off' );
  $( this ).parent( ".cards" ).addClass( 'big' );
  $( this ).addClass('flipped');

  } else {
 
  $( ".face" ).removeClass( 'off' );
  $( ".cards" ).removeClass( 'big' );
  $( this ).removeClass('flipped'); 
}
  

});
body {
height:100vh;
width:100vw;
margin:0px;
}

#container {
position: relative;
background: skyblue;
height:100%;
width:60%;
overflow: hidden;
margin:auto;
}

.off {
  color: rgba(0, 0, 0, 0.0) !important;
  background: rgba(230, 230, 250, 0.0) !important;
  -webkit-transition: all 2s; /* Safari */
  transition: all 2s;
}

.cards {
  -webkit-perspective: 900px;
  -moz-perspective: 900px;
  perspective: 900px;
  width: 80%;
  height: 20%;
  position: absolute;
  -webkit-transition: all 1s; /* Safari */
  transition: all 1s;
  margin-left: 10%;
  margin-right: 10%;
 }
 
.cards .card.flipped {
  -webkit-transform: rotatex(-180deg);
  -moz-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  height: 100%;
  z-index: 100;
}

.cards .card {
  width: 100%;
  height: 100%;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transition: all 1s; /* Safari */
  transition: all 1s;
}

.cards .card .face {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-backface-visibility: hidden ;
  -moz-backface-visibility: hidden ;
  backface-visibility: hidden ;
  z-index: 2;
  font-size: 2em;
  font-family: arial, sans-serif;
  text-align: center;
  -webkit-transition: all 0.5s; /* Safari */
  transition: all 0.5s;
}

.cards .card .front {
  position: absolute;
  background: tomato;
  z-index: 1;
}

.cards .card .back {
  -webkit-transform: rotatex(-180deg);
  -moz-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  background: gold;
}

.cards .card .front,
.cards .card .back{
  cursor: pointer;
}

.big {
height:100%;
width:100%;
top: 0% !important;
margin-left: 0%;
margin-right: 0%;
z-index:100;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=container>

<div class=cards style="top:0px"> 
<div class=card> 
   <div class="face front"> 
      Card 1 Front
    </div> 
    <div class="face back"> 
      Card 1 Back
    </div> 
  </div> 
</div> 

<div class=cards style="top:25%"> 
    <div class=card> 
    <div class="face front"> 
      Card 2 Front
    </div> 
    <div class="face back"> 
      Card 2 Back
    </div> 
  </div> 
</div>

 <div class=cards style="top:50%"> 
   <div class=card> 
    <div class="face front"> 
      Card 3 Front
    </div> 
    <div class="face back"> 
      Card 3 Back
    </div> 
  </div> 
</div>

<div class=cards style="top:75%">
   <div class=card> 
    <div class="face front"> 
      Card 4 Front
    </div> 
    <div class="face back"> 
      Card 4 Back
    </div> 
  </div> 
</div> 

</div>

Answer №2

When you include !important in the new 'flipped' class attributes, it will overwrite the old ones. Using the javascript line

$( ".item" ).not( this ).addClass( 'off' )
, you can remove the other cards when one is selected. The use of absolute position ensures everything stays in place. The active card is given a higher z-index to prevent other cards from activating the 'mouseleave' trigger. UPDATE: The code now works perfectly on Mozilla and Chrome browsers. Note: Clicking opens a card, clicking again closes it.

$('.item').click(function(){  
 
  if (!$(this).hasClass("flipped")) {
  $( ".item" ).not( this ).addClass( 'off' );
  $( this ).addClass('flipped');

  } else {
 
  $( ".item" ).removeClass( 'off' );
  $( this ).removeClass('flipped'); 
}
  

});
.off {
  color: rgba(0, 0, 0, 0.0) !important;
  background: rgba(230, 230, 250, 0.0) !important;
}

.cards {
  width: 100%;
  height: 100%;
  background: lavender;
  position: relative;
  -webkit-perspective: 900px;
  perspective: 900px;
}

.flipped {
  top: 0% !important;
  height: 100% !important;
  width: 100% !important;
  -webkit-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  -webkit-transition: all 1s; /* Safari */
  transition: all 1s;
  color: rgba(0, 0, 0, 0.0);
  z-index:100;
  -webkit-transform-style: preserve-3d;
  background: tomato;
}

.flipped:after {
  content: 'More text on here.';
    right: 0px;
    bottom: 0px;
    position: absolute;
    top: 0px;
    left: 0px;
  color: rgba(0, 0, 0, 1.0);
  -webkit-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  -webkit-backface-visibility: hidden;
  -webkit-transform-style: preserve-3d;
  background: gold;
}

.card {
  height: 22%;
  width: 100%;
  box-sizing: border-box;  
  cursor: pointer;  
  -webkit-transition: all 1s; /* Safari */
  transition: all 1s;
  display: block;
  position: absolute;
  background: tomato;
}

.aaa {
top:0%;  
}

.bbb {
top:26%;  
}

.ccc {
top:52%;  
}

.ddd {
top:78%;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width: 400px; height: 600px;">
  <div class="cards">
    <div class="card item aaa">
      <div class="face front">Some text on here.</div>
    </div>
    <div class="card item bbb">
      <div class="face front">Some text on here.</div>
    </div>
      <div class="card item ccc">
      <div class="face front">Some text on here.</div>
    </div>
      <div class="card item ddd">
      <div class="face front">Some text on here.</div>
    </div>
  </div>
</div>

Answer №3

Simply experiment with Element.classList and CSS transitions

// Try out this function to flip the card and expand the content 
function flipMe() {
  console.log(this.innerHTML);
  var card = this.querySelector('.card');
  card.classList.add('flipped');
  // This event listener will trigger when the cursor moves off the card
  card.addEventListener("mouseout", function( event ) {   
    this.classList.remove('flipped');
  }, false);
}
// Set up our variables
var cardWrapper = document.querySelector('.cardWrapper');
 

cardWrapper.addEventListener("click", flipMe, false);
:root {
 background: #CAC8CC;
}
.cardWrapper {
  -webkit-perspective: 800;
  -moz-perspective: 800;
  perspective: 800;
  width: 400px;
  height: 300px;
  position: relative;
  margin: 100px auto;
}
.cardWrapper .card.flipped {
  -webkit-transform: rotatex(-180deg);
  -moz-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  height: 100%;
}
.cardWrapper .card {
  width: 100%;
  height: 100px;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transition: .5s;
  -moz-transition: .5s;
  transition: .5s;
}
.cardWrapper .card .face {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-backface-visibility: hidden ;
  -moz-backface-visibility: hidden ;
  backface-visibility: hidden ;
  z-index: 2;
  font-size: 4em;
  text-align: center;
}
.cardWrapper .card .front {
  position: absolute;
  background: black;
  color: white;
  z-index: 1;
}
.cardWrapper .card .back {
  -webkit-transform: rotatex(-180deg);
  -moz-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  background-color: #0095ff;
}
.cardWrapper .card .front,
.cardWrapper .card .back{
  cursor: pointer;
}
<div class=cardWrapper> 
  <div class=card> 
    <div class="face front"> 
      Card 1 Front
    </div> 
    <div class="face back"> 
      Card 1 Back
    </div> 
  </div> 
</div> 

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Python's Selenium Throws No Such Element Exception

Looking to automate tasks involving hyperlinks on my university's SAP Portal, I decided to use Selenium. However, encountering difficulties as many web elements are dynamically generated using JavaScript, making them invisible to the webdriver. The e ...

Trouble with bootstrap 5 nested accordions: panels won't collapse as expected

I've structured my page content using nested bootstrap accordions within Bootstrap 5. The primary accordion is organized by continents, with each panel containing a secondary accordion for individual countries. While the main accordion functions cor ...

Issue with Chart.JS bar chart displaying error related to missing parenthesis

I am struggling to create a bar chart and can't seem to figure out the correct syntax. Every time I try, I encounter this error: Uncaught SyntaxError: missing ) after argument list The error seems to be on this line label: 'Dollar Values&apos ...

Generating HTML Document using asp.net with Internet Explorer

During my work on a tool, I encountered an issue where saving a template as an HTML file from Internet Explorer resulted in improper formatting compared to other browsers like Firefox and Chrome. This mishap led to crashes within the application. Below is ...

In the IE7 standards mode, table cells with no content will have a height of 1px

When utilizing IE7 standards mode within IE9, empty table cells are automatically assigned a height of 1px. As a result, elements positioned beneath the table appear lower on the page than intended. To view an example of this issue, refer to the code provi ...

Performance issues with the iOs CSS keyboard appearance are causing delays in

Recently updated my application to be mobile-friendly. I've noticed that at times, the keyboard seems to have a slight delay in appearing when I tap on an input field. I have around 20 inputs on a single page. I conducted a test with the same number ...

Pop-up form for file uploading with MVC and AJAX consistently returns 'NULL' value in a system

I've been utilizing the code provided in this tutorial to upload rows to a SQL Server table. A new requirement has emerged which involves storing files on the server for "Evidence" purposes. In the form, I have implemented the following code: @using ...

A sleek and modern fixed navigation bar in Bootstrap 4 featuring two elegantly stacked rows, with a striking brand image perfectly centered

I need help creating a Bootstrap 4 fixed navigation bar with 2 rows. The first row should have a centered brand image like the one on (with the image size changing after scrolling down), and the second row should contain the navigation menu. Thank you i ...

Filter a Vue list based on a checkbox that can be either checked or unchecked

I am currently working on my Vue app and aiming to filter a list to display only entries that have been moderated. However, I am encountering an issue where when the checkbox is checked, I receive all the results that are true, and when the checkbox is un ...

What is the best way to obtain the id of a selected row using JavaScript?

I'm attempting to utilize the JavaScript function below to extract a specific cell value from a jqgrid upon clicking. Within the following function, #datagrid refers to the table where the jqgrid is located. $("#datagrid").click(function ...

Tips for getting the jQuery accordion to return smoothly to its original position (instead of stacking on top of each other)

I'm a complete beginner at this and could really use some assistance. Here's my JS Fiddle: http://jsfiddle.net/hAZR7/ The problem I'm facing seems to be more related to logic or math, as the animation works fine when starting and moving to ...

What is the best way to adjust a 5-row bootstrap grid to fill the entire window space?

Trying to achieve a layout in my bootstrap project with 5 rows that span the full width has been challenging. I'm struggling to grasp how to accomplish this... Here is the initial code snippet: <div class="row car-list btn-group" style="border: 1 ...

Tips on resolving the 'jQuery reference error' in an ASP.NET environment

I've included all the necessary jQuery files, but I keep getting an error that says jQuery is not defined. Here's how I'm loading jQuery: <script src="/Scripts/jquery.js" type="text/javascript"></script> <script src="/Scripts ...

Designing a rounded border radius for various child elements within a layout

I am currently working on creating a circular container that houses an image and a description overlaid at 50% opacity. Here is what I have achieved so far: https://i.stack.imgur.com/pIkO1.png My goal is to apply a uniform border-radius to the entire div ...

Tips for syncing HTML Canvas to track the mouse's X and Y position accurately across various screen resolutions

I'm facing an issue with my canvas game where the onclick buttons are redirecting to another menu. However, when I open the Canvas on a monitor with a different resolution, all the X & Y coordinates change and nothing works as expected. Is there a wa ...

"Exploring SQL Databases: Data Entry and Retrieval

Hey there, experts! I would greatly appreciate your assistance. The main objective of the code is to allow users to register. It aims to store the values from the form with id="signup" in a MySQL database. <!DOCTYPE html> <html lang="en" ...

The background image shifts dynamically with a parallax effect as the page is scrolled

I need help solving a parallax issue that I'm currently facing. On my webpage, I have a background image positioned at the top with a parallax effect achieved through background-position: fixed. However, I now require the image to scroll along with t ...

Automatically disconnect from the application upon logging out of Google account

I've successfully set up an express server that uses Google OAuth for user authentication. One interesting challenge I'm facing is how to handle the scenario where a user logs out of Google services (like Gmail) and automatically log them out fro ...

Guide to building a robust tab system using JQuery and Ajax

I am currently working on a mockup page where the accordion feature is functioning well. However, I am looking to implement a tab-like system that will allow users to navigate between different pages. Specifically, I want users to be able to click on page ...

Is the behavior of a function with synchronous AJAX (XMLHttpRequest) call in JavaScript (Vanilla, without jQuery) the same as asynchronous?

I'm facing an issue with a file named tst.html and its content: part two (purely for demonstration, no extra markup) The challenge arises when I try to load this file using synchronous AJAX (XMLHttpRequest): function someFunc() { var str = &ap ...