Effet de zoom au survol de la souris

Coucou,

Aujourd'hui voyons nous allons voir la création d'une liste d'articles de blog responsive avec un effet de zoom au survol.

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;700&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 un main, puis un conteneur pour les articles qui contiendra 3 articles.

<main>
  <div class="container">
    <article>
      <div class="article-image"></div>
      <div class="article-content">
        <p class="article-date">2 hours ago</p>
        <h1>Post one</h1>
        <p class="article-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non est igitur summum malum dolor. Quia nec honesto quic quam honestius nec turpi turpius. </p>
      </div>
      <div class="article-bottom">
        <div class="article-bottom-item">
          <i class="fas fa-heart"></i>
          <div class="article-bottom-item-value">120</div>
          <div class="article-bottom-item-label">Likes</div>
        </div>
        <div class="article-bottom-item">
          <i class="fas fa-eye"></i>
          <div class="article-bottom-item-value">2048</div>
          <div class="article-bottom-item-label">Views</div>
        </div>
        <div class="article-bottom-item">
          <i class="fas fa-comments"></i>
          <div class="article-bottom-item-value">42</div>
          <div class="article-bottom-item-label">Comments</div>
        </div>
      </div>
    </article>
    <article>
      <div class="article-image"></div>
      <div class="article-content">
        <p class="article-date">3 days ago</p>
        <h1>Post two</h1>
        <p class="article-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non est igitur summum malum dolor. Quia nec honesto quic quam honestius nec turpi turpius. </p>
      </div>
      <div class="article-bottom">
        <div class="article-bottom-item">
          <i class="fas fa-heart"></i>
          <div class="article-bottom-item-value">42</div>
          <div class="article-bottom-item-label">Likes</div>
        </div>
        <div class="article-bottom-item">
          <i class="fas fa-eye"></i>
          <div class="article-bottom-item-value">1024</div>
          <div class="article-bottom-item-label">Views</div>
        </div>
        <div class="article-bottom-item">
          <i class="fas fa-comments"></i>
          <div class="article-bottom-item-value">16</div>
          <div class="article-bottom-item-label">Comments</div>
        </div>
      </div>
    </article>
    <article>
      <div class="article-image"></div>
      <div class="article-content">
        <p class="article-date">4 weeks ago</p>
        <h1>Post one</h1>
        <p class="article-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non est igitur summum malum dolor. Quia nec honesto quic quam honestius nec turpi turpius. </p>
      </div>
      <div class="article-bottom">
        <div class="article-bottom-item">
          <i class="fas fa-heart"></i>
          <div class="article-bottom-item-value">12</div>
          <div class="article-bottom-item-label">Likes</div>
        </div>
        <div class="article-bottom-item">
          <i class="fas fa-eye"></i>
          <div class="article-bottom-item-value">2044</div>
          <div class="article-bottom-item-label">Views</div>
        </div>
        <div class="article-bottom-item">
          <i class="fas fa-comments"></i>
          <div class="article-bottom-item-value">159</div>
          <div class="article-bottom-item-label">Comments</div>
        </div>
      </div>
    </article>
  </div>
</main>

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/

body {
  min-height: 100vh;
  font-family: 'Noto Sans JP', sans-serif;
  background-color: #8BC6EC;
  background-image: linear-gradient(135deg, #8BC6EC 0%, #9599E2 100%);
  background-repeat: no-repeat;
  display:flex;
  align-items: center;
  justify-content: center;
}

On crée notre conteneur avec une largeur de 1024 pixels que l'on centre et définit en flex pour que les éléments se mettent côte à côte sans oublier flex-wrap pour qu'ils passent à la ligne une fois qu'il n'y a plus de place pour l'article suivant.

.container {
  width:1024px;
  margin:0 auto;
  max-width: 100%;
  display:flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

Passons maintenant au style de nos articles.

article {
  width:284px;
  background:white;
  margin:24px;
  border-radius:16px;
  box-shadow: 0 4px 8px 0 rgba(0,0,0,0.16);
  overflow: hidden;
}

Puis pour la partie haute on définit le style de notre image et de notre texte :

article .article-image {
  height:220px;
  background-image:url('https://images.unsplash.com/photo-1419242902214-272b3f66ee7a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2587&q=80');
  background-size:cover;
  background-position:center center;
}

article .article-content {
  padding:16px;
}

article .article-date {
  color:#673AB7;
  font-weight: bold;
  font-size: 12px;
}

article .article-description {
  color:#666;
}

C'est toujours sympa de jouer sur les nuances de gris pour le texte et de pas tout avoir en noir absolu tout le temps.

Maintenant occupons nous de la partie basse de notre article.

article .article-bottom {
  display:flex;
  align-items: center;
  background-color:#673AB7;
  color:white;
}

article .article-bottom-item {
  flex:1;
  text-align: center;
  padding:6px 0px;
  border-right:solid 1px rgba(0, 0, 0, 0.16);
}

On les mets dans un conteneur flex et chaque colonne en flex 1 pour qu'ils se répartissent équitablement l'espace.

article .article-bottom-item:last-of-type {
  border-right: none;
}

On utilise la pseudo-class :last-of-type pour que le dernier élément n'ait pas de bordure droite.

article .article-bottom-item i {
  font-size:12px;
  color:rgba(255, 255, 255, 0.6);
}

article .article-bottom-item-value {
  font-weight:bold;
  font-size:24px;
}

article .article-bottom-item-label {
  text-transform: uppercase;
  font-size:10px;
}

Maintenant, nous allons définir des images et couleurs différentes pour les articles. Pour cela on va retourner dans notre HTML et ajouter la classe orange pour le deuxième article.

<article class="orange">

Puis pink pour le dernier.

<article class="pink">

On ajuste notre image et nos couleurs pour ces deux nouveaux types d'articles.

article.orange .article-image {
  background-image:url('https://images.unsplash.com/photo-1442458017215-285b83f65851?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1275&q=80');
}

article.orange .article-date {
  color:#FF9800;
}

article.orange .article-bottom {
  background-color:#FF9800;
}

article.pink .article-image {
  background-image:url('https://images.unsplash.com/photo-1534179523731-b2922018150a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=934&q=80');
}

article.pink .article-date {
  color:#FF4081;
}

article.pink .article-bottom {
  background-color:#FF4081;
}

Puis la touche finale on ajoute l'effet de zoom au survol d'une card :

article:hover {
  cursor:pointer;
  transform:scale(1.08);
}

Puis on retourne sur le style d'un article et on ajoute une transition pour animer le zoom, vous devriez obtenir au final ceci :

article {
  width:284px;
  background:white;
  margin:24px;
  border-radius:16px;
  box-shadow: 0 4px 8px 0 rgba(0,0,0,0.16);
  overflow: hidden;
  transition:transform .4s;
}

Le code source complet est accessible ici :
https://github.com/wass08/tuto-blog-article-list-zoom-on-hover