Vai al contenuto
animorio
EN
Tutti i componenti

Il piè di pagina col nome che respira

Piè di pagina, Hover, Testo, FisicaGSAP, Solo CSSImpegnativaPeso compresso: Demo 12 KBGSAP 28 KBGratisScarica lo zip

Nello stile minimal: il piè di pagina nero di uno studio, col nome scritto in fondo così grande da riempire tutta la larghezza. Le lettere sentono il puntatore e respirano sugli assi del peso e della larghezza, ognuna su una sua molla, ma la parola resta giustificata: quando una lettera si allarga le altre le restituiscono lo spazio e i bordi non si spostano di un pixel. Sotto, una riga sottile segna le giunture e una linea vermiglia sta sotto la lettera che respira di più.

Il codice

Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN. Nelle schede React e Vue la stessa demo è già un componente, che spegne le sue animazioni quando esce dalla pagina.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>The breathing name footer</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/anybody@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the footer of a small studio: the address, two columns of links, the year, and along the bottom the studio's
         name, so big it fills the width. Its letters feel the pointer and breathe on the weight and width axes, while
         the word stays justified: when one letter takes more room the others give it back, and the edges never move -->
    <footer class="ft" data-footer>
      <i class="ft__rule" aria-hidden="true" data-rule></i>

      <div class="ft__top">
        <div class="ft__reach" data-rise>
          <p class="ft__label">Start a project</p>
          <div class="ft__mailrow">
            <a class="ft__mail" href="mailto:hello@somna.studio" data-breathe data-mail>hello@somna.studio</a>
            <button class="ft__copy" type="button" aria-label="Copy the email address" data-copy>
              <svg viewBox="0 0 20 20" aria-hidden="true">
                <rect class="c-back" x="3.5" y="3.5" width="9" height="9" rx="2" data-copy-back/>
                <rect class="c-front" x="7.5" y="7.5" width="9" height="9" rx="2" data-copy-front/>
                <path class="c-tick" d="M5.2 10.4l3.2 3.2 6.6-7.2" data-copy-tick/>
              </svg>
            </button>
            <span class="ft__copied" aria-live="polite" data-copied></span>
          </div>
        </div>

        <nav class="ft__cols" aria-label="Footer">
          <div class="ft__col" data-rise>
            <h2 class="ft__head">Studio</h2>
            <ul class="ft__list">
              <li><a class="ft__link" href="#" data-breathe>Work</a></li>
              <li><a class="ft__link" href="#" data-breathe>Approach</a></li>
              <li><a class="ft__link" href="#" data-breathe>Journal</a></li>
            </ul>
          </div>
          <div class="ft__col" data-rise>
            <h2 class="ft__head">Elsewhere</h2>
            <ul class="ft__list">
              <li><a class="ft__link" href="#" data-breathe>Instagram</a></li>
              <li><a class="ft__link" href="#" data-breathe>Are.na</a></li>
              <li><a class="ft__link" href="#" data-breathe>Vimeo</a></li>
            </ul>
          </div>
        </nav>
      </div>

      <!-- the name: the script builds one letter per span and solves their widths every frame -->
      <div class="ft__name" data-name></div>

      <!-- the scale under the name: a hairline, a tick at every joint between letters, and the span of the letter
           that breathes the most -->
      <div class="ft__scale" aria-hidden="true" data-scale>
        <i class="ft__base-line" data-base-line></i>
        <i class="ft__span" data-span></i>
      </div>

      <div class="ft__base" data-rise>
        <p class="ft__year"><svg viewBox="0 0 12 12" aria-hidden="true"><circle cx="6" cy="6" r="5.1"/><path d="M7.9 4.5a2.3 2.3 0 1 0 0 3"/></svg><span class="sr">Copyright</span> 2026 Somna Studio</p>
        <nav class="ft__legal" aria-label="Legal">
          <a class="ft__link ft__link--small" href="#" data-breathe>Privacy</a>
          <a class="ft__link ft__link--small" href="#" data-breathe>Imprint</a>
        </nav>
      </div>
    </footer>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Cambia valori, colori e testi con le manopole e guarda l’animazione rispondere dal vivo. Oppure scrivi tu nel codice. Poi scarica la cartella con le tue modifiche.

31 valori da cambiare

Oppure chiedila a Claude Code

Col connettore di Animorio, Claude Code la prende da qui con tutta la sua guida e la adatta al tuo progetto. Incolla questa richiesta:

Prendi «Il piè di pagina col nome che respira» da Animorio e adattala al mio sito

Cosa fa

Su un fondo nero il piè di pagina di Somna Studio, uno studio inventato, largo 1040 pixel e alto circa 410, senza riquadro: una riga sottile in cima, poi a sinistra l'invito a scrivere (Start a project, l'indirizzo hello@somna.studio e accanto un piccolo tasto per copiarlo), a destra due colonne di link (Studio: Work, Approach, Journal; Elsewhere: Instagram, Are.na, Vimeo). In fondo il nome, SOMNA, in Anybody, un carattere variabile con la larghezza da 50 a 150 e il peso da 100 a 900, scritto così grande che la prima e l'ultima lettera toccano con l'inchiostro i due bordi del piè di pagina. Sotto il nome una riga sottile con una tacca a ogni giuntura fra le lettere e due tacche più lunghe ai bordi, e l'anno con i link legali. Quando il piè di pagina entra in vista la riga in cima si disegna da sinistra, l'indirizzo e le colonne salgono uno dopo l'altro, le lettere del nome salgono dalla linea di base sottilissime e prendono il loro peso dal centro verso i lati; poi un'onda attraversa il nome da sinistra a destra, così il trucco si vede prima che qualcuno punti. Col puntatore sopra, le lettere vicine diventano più nere e più larghe, tanto più quanto più è vicino, e ognuna ci arriva su una sua molla, con un poco di slancio e l'assestamento; le lontane si stringono e si alleggeriscono quanto serve perché la parola resti larga esattamente come prima: i bordi stanno fermi, si muovono solo le giunture, e le tacche sotto le seguono e si allungano dove la lettera accanto respira. Una linea vermiglia scivola sotto la lettera che respira di più, con le due estremità su due molle, quella davanti un po' più svelta. Quando nessuno punta, dopo un attimo un respiro lento passa da solo avanti e indietro per il nome. I link respirano anche loro: puntati, o raggiunti col tasto Tab, le loro lettere prendono peso e larghezza in una piccola onda che parte dal lato da cui è arrivato il puntatore, e si schiariscono. Il tasto accanto all'indirizzo lo copia: i due quadratini se ne vanno, si disegna una spunta vermiglia, compare Copied e dopo due secondi e mezzo tutto torna com'era.

Come funziona

Una tabella di larghezze, misurata una volta

All'avvio ogni lettera del nome si misura a 100 pixel su una griglia di larghezze (ogni 10, da 50 a 150) e di pesi (ogni 100, da 100 a 900): 99 posizioni, ognuna una sola lettura per tutte le lettere insieme. Fra un punto e l'altro la larghezza si legge in modo bilineare, e siccome la larghezza cresce in proporzione alla grandezza del carattere, a un cambio di misura della finestra non si rimisura niente.

Il risolutore che tiene la riga giustificata

Ogni lettera ha la sua intensità e (0 a riposo, 1 sotto il puntatore): il peso è il peso a riposo più e per la differenza, la larghezza è lam più SPREAD per e, dentro l'asse. lam è uno solo per tutta la parola, e la somma delle larghezze cresce con lam: a ogni fotogramma una bisezione di 22 passi sulla tabella trova il lam che rende la parola larga esattamente come il piè di pagina, meno gli spazi fra le lettere. Se nemmeno il lam più stretto basta, si riduce lo SPREAD invece. Il resto di mezzo pixel lo assorbe un flex con justify-content: space-between, così i bordi sono fermi per costruzione.

L'inchiostro sui bordi, non la scatola

Ogni lettera lascia un po' di vuoto ai lati (le spalle del disegno): con la scatola sui bordi, la S e la A stavano qualche pixel dentro. Un canvas legge l'inchiostro della prima e dell'ultima lettera a tre pesi, come parte della loro larghezza; il nome si allarga oltre i bordi di quanto vale quel vuoto, nel fotogramma stesso, e il risolutore tiene conto dei pixel in più.

Molle per lettera, e un respiro da solo

Ogni intensità insegue il suo obiettivo su una molla smorzata (SPRING), in passi di 1/120 di secondo e col passo del fotogramma limitato a 1/30. L'obiettivo è il più grande fra tre campane: quella del puntatore (con una forza che sale in fretta e scende piano, e svanisce a 180 pixel dal piè di pagina), quella dell'onda d'entrata, e quella del respiro lento che va avanti e indietro quando nessuno punta. La linea vermiglia ha due molle sue, una per estremità.

I link che respirano, in CSS

Le lettere di ogni link hanno font-variation-settings scritto con calc() su una variabile --b; GSAP fa andare --b da 0 a 1 con uno stagger che parte dal lato da cui arriva il puntatore e una molla come curva. Il link tiene il suo nome intero in aria-label per chi usa un lettore di schermo.

Valori da cambiare

NomeFileDi partenzaCosa cambia
NAMEscript.js'SOMNA'Il nome dello studio, la parola grande in fondo: una parola sola (più è lunga, più si fa piccola per starci).
WEIGHTscript.js[270, 860]Il peso di una lettera a riposo e di una proprio sotto il puntatore (da 100 a 900).
SPREADscript.js62Quanto si allarga la lettera sotto il puntatore, sull'asse della larghezza: le altre si stringono per farle posto.
REACHscript.js0.8Fin dove si sente il puntatore, in lettere.
SPRINGscript.js[150, 15]La molla di ogni lettera: quanto è rigida e quanto è frenata (meno freno, più oscilla).
BREATHEscript.jstrueQuando nessuno punta, un respiro lento passa da solo per il nome.
BREATHscript.js9Quanti secondi dura un respiro lento, andata e ritorno.
DEPTHscript.js0.62Quanto è profondo il respiro da solo, da 0 a 1.

Provali nel Playground

Quando usarla

Per il piè di pagina di uno studio di design, di un'agenzia, di un fotografo, di un marchio di moda o di un portfolio: ovunque il nome sia la cosa più bella da lasciare in fondo alla pagina, e le parole siano poche.

Sul telefono

Il piè di pagina prende la larghezza dello schermo: l'indirizzo va sopra e le due colonne di link restano affiancate, con righe alte 44 pixel da toccare. Il nome riempie la larghezza con le lettere più strette a riposo, così è più alto. Le lettere respirano sotto il dito che tocca e scorre di lato sul nome (su e giù scorre la pagina), e fra un tocco e l'altro il respiro lento passa da solo. Un tocco su un link fa respirare le sue lettere.

Con il movimento ridotto

Il nome resta fermo, giustificato, al peso di riposo: niente molle e niente respiro da solo. Tutto entra in dissolvenza. Sotto la lettera puntata la linea vermiglia compare in dissolvenza, e passando a un'altra lettera si spegne e si riaccende al posto nuovo senza scivolare. I link si schiariscono soltanto, e il tasto per copiare scambia i quadratini con la spunta in dissolvenza.

Trappole

  • Con la scatola delle lettere sui bordi la S e la A stavano qualche pixel dentro le tacche: le spalle del disegno. Ora il nome si allarga oltre i bordi di quanto vale il vuoto della prima e dell'ultima lettera, letto con un canvas.
  • Il canvas non sa mettere l'asse della larghezza (ctx.fontStretch con questo carattere non cambia niente): le spalle si leggono alla larghezza normale come parte della larghezza della lettera, e quella parte vale per ogni larghezza.
  • Lo stagger di un link che respira, interrotto da un'uscita veloce col tasto Tab, finiva dopo: le lettere che non avevano ancora cominciato si gonfiavano lo stesso. Ora ogni tween nuovo toglie tutti quelli delle stesse lettere (overwrite: true), anche le parti non ancora partite.
  • Il tondo della S e della O scende un poco sotto la linea di base e la maschera dell'entrata lo tagliava piatto: la maschera ora lascia sotto la base qualche pixel.
  • Sul telefono la griglia della pagina si allargava quanto il nome voleva e il piè di pagina usciva dallo schermo: la colonna della pagina è minmax(0, 1fr).
  • Leggere la posizione delle lettere da getBoundingClientRect avrebbe seguito anche la salita dell'entrata: offsetLeft ignora le trasformazioni, così le tacche e la linea vermiglia stanno sempre sulle giunture vere.

Librerie

GSAP 3.15.0, Anybody (font variabile) 5.3.0.

Compressi con gzip, i tre file della demo pesano 12 KB; le librerie: GSAP 28 KB.

Collaudo

Provata il 16 ottobre 2026

  • Computer: Fatto
  • Telefono: Fatto
  • Movimento ridotto: Fatto
  • Safari su iPhone: Da fare

Licenza d’uso

Puoi usarla nei tuoi progetti e in quelli dei tuoi clienti. Non puoi rivenderla né ridistribuirla così com’è. GSAP resta sotto la sua licenza Standard. Licenza completa.

Tutti i componenti