back to top

Realizzare un Effetto Hover Avanzato per una Card Prodotto con HTML e CSS

Nike Shoes

Size :

7 8 9 10

Color :

Buy Now

In questo articolo analizzeremo passo dopo passo un effetto hover animato per una card prodotto, realizzato con HTML e CSS puri. Si tratta di un design dal look moderno e accattivante, dove l’elemento principale è un’immagine (in questo caso, di una scarpa Nike) che si muove quando il puntatore del mouse si trova sulla card. Questo tipo di effetto è molto utile in siti e-commerce, landing page o portfolio, perché permette di mettere in risalto in modo dinamico l’oggetto presentato, aggiungendo al contempo dettagli come taglie, colori e un pulsante di acquisto.

Lo scopo dell’articolo è:

  1. Presentare il codice e spiegarne i passaggi salienti.
  2. Mostrare perché queste tecniche sono state scelte.
  3. Fornire use-case reali per l’utilizzo di un effetto simile.
  4. Offrire consigli su come personalizzare e integrare la card in progetti concreti.

Alla fine, troverai il codice completo (HTML e CSS) pronto per essere copiato e incollato nel tuo progetto. Durante l’articolo, riporteremo alcuni frammenti di codice parziali per spiegare meglio i singoli aspetti. Per eventuali riferimenti approfonditi a proprietà CSS o best practice front-end, troverai link utili a fonti autorevoli come MDN, CSS Tricks e web.dev.


1. Struttura HTML di base per questo effetto hover card prodotto

Iniziamo dal markup principale della card. Abbiamo un contenitore .container e, al suo interno, una .card che ospiterà immagine e contenuti testuali. Il codice minimal è il seguente:

<div class="container">
  <div class="card">
    <div class="imgBx">
      <img src="https://assets.codepen.io/4164355/shoes.png" alt="Nike Shoes">
    </div>
    <div class="contentBx">
      <h2>Nike Shoes</h2>
      <div class="size">
        <h3>Size :</h3>
        <span>7</span>
        <span>8</span>
        <span>9</span>
        <span>10</span>
      </div>
      <div class="color">
        <h3>Color :</h3>
        <span></span>
        <span></span>
        <span></span>
      </div>
      <a href="#">Buy Now</a>
    </div>
  </div>
</div>

Perché questa struttura?

  • imgBx funge da contenitore per l’immagine, posizionata tramite CSS con position: absolute e animazioni basate su transform.
  • contentBx contiene il titolo, la selezione della taglia (size), la selezione del colore (color) e un link per l’acquisto.
  • I vari span all’interno di .size e .color sono usati come elementi cliccabili o comunque visualizzano informazioni aggiuntive (p.e. dimensioni, varianti di colore).
  • La card è incapsulata in un div.container che gestisce l’allineamento e lo “spazio” esterno con position: relative.

Questa separazione tra struttura (HTML) e presentazione (CSS) facilita la leggibilità del codice e l’estensibilità futura.


2. Impostazione del layout e sfondo

La parte iniziale del CSS si occupa di resettare lo stile base e di impostare un font globale:

* {
  font-family: 'Poppins', sans-serif;
}

Successivamente, si definisce il layout del body:

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: #131313;
}

Usare display: flex a livello di body è un metodo semplice per centrare orizzontalmente e verticalmente il contenuto, impostando anche min-height: 100vh in modo che la pagina utilizzi tutta l’altezza disponibile. Lo sfondo scuro (#131313) enfatizza l’effetto hover e fa risaltare la card.


3. Le dimensioni e l’animazione della card

.container .card {
  position: relative;
  width: 320px;
  height: 450px;
  background: #232323;
  border-radius: 20px;
  overflow: hidden;
}
  • Dimensioni fisse (320x450px) per una card di medie dimensioni.
  • border-radius: 20px ammorbidisce gli angoli.
  • overflow: hidden fa sì che gli elementi in posizione assoluta (soprattutto lo pseudo-elemento colorato che vedremo tra poco) non escano fuori dal perimetro della card.

L’effetto clip-path

Uno degli elementi più interessanti è l’effetto che il codice crea con lo pseudo-elemento :before. Ecco uno scorcio del CSS corrispondente:

.container .card:before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  background: #9bdc28;
  clip-path: circle(150px at 80% 20%);
  transition: 0.5s ease-in-out;
}

.container .card:hover:before {
  clip-path: circle(300px at 80% -20%);
}
  • :before crea un livello in sovrimpressione colorato di verde lime (#9bdc28).
  • Usando clip-path: circle(), ritagliamo un cerchio di raggio 150px posizionato a 80% da sinistra e 20% dall’alto.
  • Al passaggio del mouse, il cerchio si espande fino a 300px e si sposta verticalmente (-20% dall’alto). In questo modo, il colore lime si diffonde creando un effetto di luce o “aura” attorno all’immagine.

Se vuoi approfondire clip-path, puoi consultare la guida MDN o la sezione dedicata su CSS Tricks.


4. Lo pseudo-elemento :after e il testo in trasparenza

.container .card:after {
  content: 'Nike';
  position: absolute;
  top: 30%; left: -20%;
  font-size: 12em;
  font-weight: 800;
  font-style: italic;
  color: rgba(255,255,25,0.05);
}

Qui vediamo come un secondo pseudo-elemento (:after) venga utilizzato per mostrare un testo gigante e quasi trasparente (“Nike”), donando un aspetto grafico “di sfondo”. Questa è una tecnica di design molto comune per aggiungere elementi decorativi senza appesantire l’HTML.


5. Gestione dell’immagine (la scarpa)

HTML dedicato

<div class="imgBx">
  <img src="./shoes.png" alt="Nike Shoes">
</div>

CSS di .imgBx

.container .card .imgBx {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10000;
  width: 100%;
  height: 220px;
  transition: 0.5s;
}

.container .card:hover .imgBx {
  top: 0%;
  transform: translateY(0%);
}
  • position: absolute; e l’uso di top: 50%; transform: translateY(-50%) servono per centrare verticalmente l’immagine nella card.
  • In hover, la imgBx passa a top: 0%, quindi si sposta in alto, azzerando anche il transform: translateY(0%).

Rotazione e dimensioni dell’immagine

.container .card .imgBx img {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(-25deg);
  width: 270px;
}

Questo “doppio transform” serve per centrare l’immagine al 50% di .imgBx (sia in verticale che in orizzontale) e inclinarla leggermente con rotate(-25deg), dando un effetto dinamico. La larghezza è settata a 270px; regola questo valore in base alla risoluzione dell’immagine.


6. Sezione contentBx: titoli, taglie, colori e pulsante

Mostrare dettagli all’hover

L’idea è che, da default, l’area inferiore (con le taglie, i colori e il pulsante di acquisto) sia più piccola (100px) e con alcuni elementi a opacity: 0; visibility: hidden;. Al passaggio del mouse, la card si espande fino a 210px di altezza e i dettagli appaiono gradualmente. Ecco uno snippet esemplificativo:

.container .card .contentBx {
  position: absolute;
  bottom: 0; 
  width: 100%;
  height: 100px;
  text-align: center;
  transition: 1s;
  z-index: 10;
}

.container .card:hover .contentBx {
  height: 210px;
}

Allo stesso modo:

.container .card .contentBx .size,
.container .card .contentBx .color {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 8px 20px;
  opacity: 0;
  visibility: hidden;
  transition: 0.5s;
}

.container .card:hover .contentBx .size {
  opacity: 1;
  visibility: visible;
  transition-delay: 0.5s;
}

.container .card:hover .contentBx .color {
  opacity: 1;
  visibility: visible;
  transition-delay: 0.6s;
}
  • opacity: 0; visibility: hidden; nasconde completamente l’elemento e evita che possa interferire con altri elementi sulla pagina.
  • In hover, questi valori passano a opacity: 1; visibility: visible;, con un ritardo (transition-delay) per creare un arrivo sfalsato e più “naturale”.

Infine, il link “Buy Now” compare con una transizione simile. Invece di animarne l’opacità e la visibilità, si aggiunge anche un transform: translateY(50px) -> translateY(0px) per un effetto di “slittamento verso l’alto”:

.container .card .contentBx a {
  display: inline-block;
  padding: 10px 20px;
  background: #fff;
  border-radius: 4px;
  margin-top: 10px;
  text-decoration: none;
  font-weight: 600;
  color: #111;
  opacity: 0;
  transform: translateY(50px);
  transition: 0.5s;
}

.container .card:hover .contentBx a {
  opacity: 1;
  transform: translateY(0px);
  transition-delay: 0.75s;
}

7. Use-case reali e adattabilità

  • E-commerce: Perfetto per mostrare prodotti con poche info base, che diventano più visibili al passaggio del mouse (taglie, colore, pulsante d’acquisto).
  • Landing page: Quando desideri un focus immediato su un’offerta o un prodotto hero. L’immagine in primo piano cattura l’attenzione e l’utente può interagire per vedere i dettagli.
  • Portfolio: Potresti mostrare anteprime di progetti e, all’hover, rivelare descrizioni, link e data di realizzazione.
  • Gallerie interattive: Un insieme di card simili su una pagina, ognuna con le proprie transizioni personalizzate (colori, immagini, testi diversi).

Personalizzazioni possibili

  • Cambia la forma di clip-path: non solo circle(), ma anche polygon() o ellipse().
  • Ritocca durata e easing: transition: 1s ease-in-out;, transition-delay: 0.2s; ecc. per un feeling diverso.
  • Mobile-first: Su dispositivi touch, l’hover non esiste. Potresti implementare un tap per espandere la card. Usa media query o JS per adattare il comportamento su schermi più piccoli.
  • Palette colore e tipografia: Se preferisci un brand color diverso, basta sostituire #9bdc28. Seleziona i tuoi font da Google Fonts aggiungendoli nella sezione @import.

Se vuoi approfondire come gestire animazioni e transizioni in maniera efficiente, dai uno sguardo alla guida web.dev su animazioni CSS e ai tutorial su transizioni di CSS Tricks.


8. Codice completo (HTML + CSS) per questo effetto hover card prodotto!

Riassumendo tutti gli snippet visti finora, ecco il codice completo pronto per essere copiato e incollato nei tuoi progetti. Ricorda di includere il link a Google Fonts per Poppins o qualsiasi altro font desideri usare.

<!DOCTYPE html>
<html lang="it">
<head>
  <meta charset="UTF-8">
  <title>Card Hover Effect - Esempio</title>
</head>
<body>

<div class="container">
  <div class="card">
    <div class="imgBx">
      <img src="./shoes.png" alt="Nike Shoes">
    </div>
    <div class="contentBx">
      <h2>Nike Shoes</h2>
      <div class="size">
        <h3>Size :</h3>
        <span>7</span>
        <span>8</span>
        <span>9</span>
        <span>10</span>
      </div>
      <div class="color">
        <h3>Color :</h3>
        <span></span>
        <span></span>
        <span></span>
      </div>
      <a href="#">Buy Now</a>
    </div>
  </div>
</div>

</body>
</html>
  @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap');
  
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Poppins', sans-serif;
  }
  
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: #131313;
  }
  
  .container {
    position: relative;
  }
  
  .container .card {
    position: relative;
    width: 320px;
    height: 450px;
    background: #232323;
    border-radius: 20px;
    overflow: hidden;
  }
  
  .container .card:before {
    content: '';
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: #9bdc28;
    clip-path: circle(150px at 80% 20%);
    transition: 0.5s ease-in-out;
  }
  
  .container .card:hover:before {
    clip-path: circle(300px at 80% -20%);
  }
  
  .container .card:after {
    content: 'Nike';
    position: absolute;
    top: 30%;
    left: -20%;
    font-size: 12em;
    font-weight: 800;
    font-style: italic;
    color: rgba(255,255,25,0.05);
  }
  
  .container .card .imgBx {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 10000;
    width: 100%;
    height: 220px;
    transition: 0.5s;
  }
  
  .container .card:hover .imgBx {
    top: 0%;
    transform: translateY(0%);
  }
  
  .container .card .imgBx img {
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%) rotate(-25deg);
    width: 270px;
  }
  
  .container .card .contentBx {
    position: absolute;
    bottom: 0; 
    width: 100%;
    height: 100px;
    text-align: center;
    transition: 1s;
    z-index: 10;
  }
  
  .container .card:hover .contentBx {
    height: 210px;
  }
  
  .container .card .contentBx h2 {
    font-weight: 600;
    letter-spacing: 1px;
    color: #fff;
    margin: 10px 0;
  }
  
  .container .card .contentBx .size, 
  .container .card .contentBx .color {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 8px 20px;
    opacity: 0;
    visibility: hidden;
    transition: 0.5s;
  }
  
  .container .card:hover .contentBx .size {
    opacity: 1;
    visibility: visible;
    transition-delay: 0.5s;
  }
  
  .container .card:hover .contentBx .color {
    opacity: 1;
    visibility: visible;
    transition-delay: 0.6s;
  }
  
  .container .card .contentBx .size h3, 
  .container .card .contentBx .color h3 {
    color: #fff;
    font-weight: 300;
    font-size: 14px;
    text-transform: uppercase;
    letter-spacing: 2px;
    margin-right: 10px;
  }
  
  .container .card .contentBx .size span {
    width: 26px;
    height: 26px;
    text-align: center;
    line-height: 26px;
    font-size: 14px;
    display: inline-block;
    background: #fff;
    color: #111;
    margin: 0 5px;
    border-radius: 4px;
    cursor: pointer;
    transition: 0.5s;
  }
  
  .container .card .contentBx .size span:hover {
    background: #9bdc28;
  }
  
  .container .card .contentBx .color span {
    width: 20px;
    height: 20px;
    background: #ff0;
    border-radius: 50%;
    margin: 0 5px;
    cursor: pointer;
  }
  
  .container .card .contentBx .color span:nth-child(2) {
    background: #9bdc28;
  }
  
  .container .card .contentBx .color span:nth-child(3) {
    background: #03a9f4;
  }
  
  .container .card .contentBx a {
    display: inline-block;
    padding: 10px 20px;
    background: #fff;
    border-radius: 4px;
    margin-top: 10px;
    text-decoration: none;
    font-weight: 600;
    color: #111;
    opacity: 0;
    transform: translateY(50px);
    transition: 0.5s;
  }
  
  .container .card:hover .contentBx a {
    opacity: 1;
    transform: translateY(0px);
    transition-delay: 0.75s;
  }

Puoi adattare facilmente questo layout a un contesto con più card (e più prodotti), oppure trasformarlo in un componente di React/Vue/Angular, mantenendo la stessa logica di base e integrandolo nei tuoi processi di build.


Conclusione

L’effetto hover che abbiamo analizzato conferma come sia possibile ottenere risultati sorprendenti usando solo HTML e CSS, senza necessità di JavaScript per animazioni di base. L’approccio si presta a:

  1. Migliorare la UX: L’utente “scopre” i dettagli del prodotto in modo graduale, riducendo il disordine visivo.
  2. Ridurre la complessità: Meno dipendenze esterne, meno overhead.
  3. Personalizzare a volontà: Forme, durate, testi, colori e layout possono essere modificati per adattarsi al tuo brand o progetto.

Se vuoi ulteriori spunti, ti consiglio di esplorare l’uso di clip-path con altre forme, leggere la guida di CSS Tricks sulle animazioni e approfondire le best practice di performance su web.dev.

Con questo hai a disposizione un progetto di base da cui partire. Sperimenta con i parametri e integra la card nel tuo e-commerce o portfolio. Vedrai che l’effetto visivo e l’esperienza utente ne trarranno grande beneficio.

Condividi

Articoli Recenti

Categorie popolari