Tips for creating animated card designs with HTML, CSS, and JavaScript

As I delve into the realm of CSS animation, my primary focus is on replicating the captivating card shuffling animation showcased at

Here's a glimpse of the progress I've made so far: https://youtu.be/GDIJ2K22cnY

While I've successfully implemented the basic movement, I'm facing challenges when it comes to refining the translation and relative movement of each card. My ultimate goal is to enhance the animation to achieve a smoother and more realistic card shuffling effect. Although the cards are in motion, the animation lacks the cyclic shuffle effect that I aspire to create. I suspect there might be an error in my approach. Can you pinpoint what I might be doing wrong here?

Below is the code snippet I've written:

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="card-container">
        <div class="card">
          <img src="./assets/Cart  Geometric  2.png" alt="Card 1">
        </div>
        <div class="card">
          <img src="./assets/Cart  Geometric  5.png" alt="Card 2">
        </div>
        <div class="card">
          <img src="./assets/Cart  Geometric  8.png" alt="Card 3">
        </div>
      </div>
</body>
</html>

CSS:


body {
    font-family: 'HelveticaNeue', sans-serif;
    margin: 0;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    height: 100vh;
    background: url('./assets/Vector\ 1.png') center/cover no-repeat , linear-gradient(180deg, #DBE4ED 100%, #BABABA 100%)  ;
}

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.card-container {
    position: relative;
    perspective: 1000px;
    width: 300px;
    height: 200px;
}

.card {
    position: absolute;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    animation: rotateCard 6s linear infinite;
}

@keyframes rotateCard {
    20% {
        transform: rotate(4deg) translateY(-10px);
        z-index: 3;
    }
    40%, 100% {
        transform: rotate(-4deg) translateY(10px);
        z-index: 2;
    }
    0%, 60%, 80% {
        transform: scale(1) translateY(0);
        z-index: 1;
    }
}

.card:nth-child(2) { animation-delay: 2s; }
.card:nth-child(3) { animation-delay: 4s; }

.card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 10px;
    margin-right: 170px; 
}

Answer №1

I have replicated the animation from the provided link using only CSS. Here is the code:

.container-cards {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  transform-style: preserve-3d;
}

.card {
  position: absolute;
  width: 300px;
  height: 200px;
  border-radius: 10px;
  animation: rotateCard 10.5s ease-in-out infinite;
}

@keyframes rotateCard {
  /* Hold front */
  0% {
    transform: translateZ(1px);
  }
  /* Hold front */
  28.57% {
    transform: translateZ(1px);
  }
  /* Move left */
  33.33% {
    transform: rotate(-4deg) scale(0.9) translate(-15%, -5%);
  }
  /* Hold left */
  61.90% {
    transform: rotate(-4deg) scale(0.9) translate(-15%, -5%);
  }
  /* Move right */
  66.67% {
    transform: rotate(4deg) scale(0.9) translate(15%, -5%);
  }
  /* Hold right */
  95.23% {
    transform: rotate(4deg) scale(0.9) translate(15%, -5%);
  }
  /* Move front */
  100% {
    transform: translateZ(1px);
  }
}

.card:nth-child(1) {
  animation-delay: -7s;
}
.card:nth-child(2) {
  animation-delay: -3.5s;
}
/* This card is initially at the front */
.card:nth-child(3) {
  animation-delay: 0;
}
<div class="container-cards">
  <div class="card" style="background-color: red"></div>
  <div class="card" style="background-color: blue"></div>
  <div class="card" style="background-color: green"></div>
</div>

The timing percentages are calculated as follows:

at front: 0s - start point 1
hold front: 3s (3 / 10.5 = 28.57%)
move left: 0.5s (3.5 / 10.5 = 33.33%)  - start point 2
hold left: 3s (6.5 / 10.5 = 61.90%)
move right: 0.5s (7 / 10.5 = 66.67%) - start point 3
hold right: 3s (10 / 10.5 = 95.23%)
move front: 0.5s (10.5 / 10.5 = 100%)

If you wish to make any adjustments to the timing, you will need to recalculate using the same method.

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

When the filter feGaussianBlur is applied to an SVG circle, it disappears on Safari but not on Chrome

While implementing the filter with feGaussianBlur to an SVG circle, I encountered a peculiar issue. It works perfectly on Chrome, but unfortunately, the circle disappears when viewed on Safari. https://i.sstatic.net/k916B.png https://i.sstatic.net/5Bfp9. ...

"Accessing your account only requires a simple two-click login process

Why do I need to click the log in button twice for data validation on my forum website? While designing a forum website, I noticed that users have to click the log-in button twice before the system validates and processes the input data. Below is the code ...

Stripping out only the position attribute using jQuery

I have implemented a code with the following characteristics: The navigation items' texts are hidden behind certain Divs, which I refer to as Navigation Divs. When the mouse hovers over these pixels (navigation Divs), the text that is behind the ...

Ways to modify the background color of the entire body excluding a sidebar div

How do I implement an overlay and dim the screen after clicking on a menu button? <ul id="gn-menu" class="gn-menu-main"> <li class="gn-trigger"> <a class="gn-icon gn-icon-menu"><span>Menu</spa ...

Using jQuery to create a nested table

I have a table that I would like to customize so that when a user clicks on a row, only the child table under that specific row is visible while the child tables under other rows are hidden. How can I achieve this using jQuery? <table class="mainTabl ...

Infinite loop using jQuery function endlessly

I'm trying to create a jQuery Animation that loops indefinitely, but my current code doesn't seem to be working. Here's what I have: $(document).ready(function() { var i = 0; document.write(i); function runAnimatio ...

Mastering Cookies in Javascript

I have been exploring the world of cookies in Javascript and decided to create an experimental log-in page. The page is fully functional, but I am interested in displaying the user's username and password using cookies. Is this possible with Javascrip ...

The type 'MutableRefObject<undefined>' cannot be assigned to the type 'LegacyRef<HTMLDivElement> | undefined'

I have created a customized hook that takes a ref object and observes its behavior: import { useState, useEffect, MutableRefObject } from "react"; const UseOnScreen = (ref: MutableRefObject<undefined>) => { const [isIntersecting, setI ...

Sending a group of checkboxes via Ajax using AngularJS

I am facing a challenge with making an ajax GET request where I need to submit an array of checkboxes, all with the same name. The checkboxes are defined as follows: type[] = new type[] = used type[] = refurbished The purpose of this is to fulfill the r ...

Is there a more efficient method to achieve the desired effect without making multiple calls to jQuery ajaxSuccess?

Currently, I am working on creating an effect that involves a quick fade-out followed by a fade-in of the element once the request is successful. Since jQuery processes elements in a routine manner (top to bottom), I have managed to achieve my desired eff ...

Axios - Show the error message returned from validation as [object Object]

Within my API, I include the following validation logic: $request->validate([ 'firstname' => 'required', 'lastname' => 'required', 'username' => 'required|unique:us ...

An error was encountered when attempting to use the 'await' syntax in a useEffect() function that called axios.get()

To avoid using .then(..), I have switched to utilizing await. I am making a call to a function that includes an Axios request and returns the data as response.data after awaiting for it. My functional component has a useEffect that is meant to initialize a ...

Adding an existing element to the DOM using Javascript/jQuery

I am facing an issue in my DOM where I have an element with two children, a div block and a button. My goal is to add a new copy of the same div block to the parentNode whenever the button is clicked. Currently, I am using the following code in the button ...

Border becomes dashed when dragging and dropping

I am working on enabling drag and drop functionality for users. When an item is lifted from its original position, a gray dashed box should appear in its place. As the item is moved closer to another spot, the containers adjust to create a target area (gra ...

Utilize Twitter Bootstrap 4 to organize menu items in neat rows

I would like my menu to be structured in rows rather than wrapping and breaking to the next line when there is no more space. For instance: https://i.sstatic.net/dInTx.png Currently, it looks like this: https://i.sstatic.net/QkVS6.png Even changing to ...

How can we ensure that the Material-UI <Select> component is as wide as the widest <MenuItem>?

I am attempting to adjust a Mui Select field so that it is the same width as its largest MenuItem. Despite trying to utilize the autoWidth prop on the Select component, I have not been able to achieve the desired result. To better illustrate the issue, I h ...

Utilizing the variable $this outside of an object context within an Ajax function

Encountering the following error: Fatal error: Uncaught Error: Using $this when not in object context in E:\xampp\htdocs\StudentGuideBook\Version1.0\models\AjaxChecking.php:4 Stack trace: #0 {main} thrown in E:\xampp&b ...

Leveraging nodemailer and handlebars for personalized email templates

I'm encountering an issue and struggling to pinpoint what exactly is causing it. Whenever I execute my code, the following error message pops up: [Error: ENOENT: no such file or directory, open 'C:\Users\Alex\Desktop\emailtes ...

Display the device model using Google Cloud Monitoring API

I've been utilizing a Node.js library to fetch metrics from my Google Cloud Compute Engine instances. You can find the library here. When creating a time series, the resulting data looks like this: { "points": [...], "metric": { "lab ...

AngularJS url update event

In order to gather statistical data, I am interested in tracking how many times the URL has been changed. To achieve this, I have set up a counter that will increment each time the URL is modified. Does anyone have a solution for this? ...