Animation d'une flip card en HTML | CSS

Coucou,

Aujourd'hui voyons comment créer facilement une card qui se retourne au survol de la souris laissant apparaître une image et des liens dans son dos.

Démo du résultat final

Mise en place de la structure HTML

On commence par créer un fichier index.html. Dans le head on importe une police depuis Google Fonts, la librairie Font Awesome et un fichier style.css que l'on va créer plus tard.

<!DOCTYPE html>
<html>
  <head>
    <title>Flip</title>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;900&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"/>
    <link href="style.css" rel="stylesheet" />
  </head>
  <body>
</body>
</html>

Ensuite dans le body on va créer notre flip card. La classe card-inner va servir de conteneur pour le devant de la card card-front et le derrière card-back.

<div class="card">
  <div class="card-inner">
    <div class="card-front">
      <div class="card-content">
        <h2>WawaSensei</h2>
        <p>Tutos dev</p>
        <p>HTML, CSS, JS</p>
      </div>
    </div>
    <div class="card-back">
      <div class="card-top">
        <div class="card-image"></div>
      </div>
      <p>Follow me on</p>
      <div class="card-icons">
        <a href="https://www.wawasensei.dev" target="_blank">
          <i class="fas fa-link"></i>
        </a>
        <a href="https://www.youtube.com/channel/UCBH-5ctALmmOrm4kczL3urQ" target="_blank">
          <i class="fab fa-youtube"></i>
        </a>
        <a href="https://instagram.com/wass08" target="_blank">
          <i class="fab fa-instagram"></i>
        </a>
      </div>
    </div>
  </div>

CSS

J'aime commencer chaque base CSS d'un projet par une définition des styles de base sur le sélecteur * (tous les éléments). box-sizing:border-box pour que les bordures et les padding soient inclus quand on définit des dimensions ce qui facilite la gestion des tailles des éléments. Je définis tous les margin et padding à 0 pour éviter que les titres et paragraphes aient déjà des valeurs qui peuvent varier en fonction du navigateur.

* {
  box-sizing: border-box;
  margin:0;
  padding:0;
}

On utilise notre police d'écriture, rajoute du flex pour centrer et un arrière plan dégradé trouvé sur https://cssgradient.io/gradient-backgrounds/

html, body {
  font-family: 'Noto Sans JP', sans-serif;
  min-height: 100vh;
  display:flex;
  align-items: center;
  justify-content: center;
  background-color: #D9AFD9;
  background-image: linear-gradient(0deg, #D9AFD9 0%, #97D9E1 100%);
}

Passons maintenant au style de notre carte.

.card {
  margin:0 auto;
  width:240px;
  height:320px;
  perspective: 1000px;
  text-align: center;
}

.card-inner {
  position:relative;
  width: 100%;
  height:100%;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}

La propriété perspective permet de définir la distance entre l'utilisateur et l'axe de rotation de notre carte. On ajoute transform-style preserve-3d à notre card-inner qui est la partie qui va tourner pour que l'élément soit positionné en 3 dimensions.

.card:hover .card-inner {
  transform: rotateY(180deg);
}

Enfin on fait tourner la carte de 180 degré sur l'axe des Y pour retourner la carte au survol.

Attaquons le contenu de notre carte, la face et l'arrière :

.card-front, .card-back {
  position:absolute;
  height:100%;
  width: 100%;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  padding:16px;
  border-radius:8px;
  box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
}

On la met en position absolute pour pouvoir avoir les deux éléments au même endroit mais un devant et l'autre derrière. On utilise backface-visibility hidden pour que le contenu soit invisible une fois retourné.

Ensuite on définit le style de notre choix sur le devant

.card-front {
  background-image:url('images/front.jpg');
  background-size:cover;
  background-position:center center;
  display:flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  overflow: hidden;
}

.card-front:before {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0px;
  background: linear-gradient(0deg, black, transparent);
}

.card-front .card-content {
  z-index: 1;
  color:white;
}

.card-front .card-content p {
  color:#ececec;
}

Puis de même sur le derrière en rajoutant un transform rotateY de 180 degrés pour bien définir que c'est le derrière (qui sera du coup invisible de base)

.card-back {
  transform: rotateY(180deg);
  background:white;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.card-back .card-image {
  width:120px;
  height:120px;
  margin:0 auto;
  border:solid 1px #cecece;
  border-radius:100%;
  background-image:url('images/back.jpg');
  background-size:cover;
  background-position:center center;
}

.card-back p {
  margin-top:12px;
}

.card-back .card-icons {
  display:flex;
  justify-content: center;
  align-items: center;
}

.card-back .card-icons a {
  font-size:18px;
  color:white;
  background:black;
  width:42px;
  height:42px;
  border-radius:100%;
  margin:8px;
  display:flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  transition:opacity .2s;
}

.card-back .card-icons a:hover {
  cursor:pointer;
  opacity:0.7;
}

J'ai remarqué que les liens sont difficilement cliquables car malgré que le contenu du devant est invisible au survol, il intérargit toujours avec le clic de souris. Pour éviter ça on peut mettre l'opacity à 0 au survol de la souris ce qui résout le problème.

.card-front {
  transition: opacity .6s;
}

.card:hover .card-front {
  opacity:0;
}

Le code source complet est accessible ici :
https://github.com/wass08/tuto-html-css-creation-flip-card-animee