Vai al contenuto
animorio
EN
Tutti i componenti

Il menu che si scrive con le sue lettere

Menu, Testo, Transizioni, HoverGSAP, Solo CSSMediaPeso compresso: Demo 7,1 KBGSAP 28 KBGratisScarica lo zip

Nello stile minimal: il menu di una piccola casa editrice indipendente. Il pulsante dice MENU, e premendolo le sue quattro lettere escono una dopo l'altra, cadono ognuna sulla sua riga su una molla misurata e diventano l'iniziale di una voce: M di Manifesto, E di Editions, N di Notes, U di Us. Atterrando la lettera si schiaccia un attimo e la riga sotto si disegna; poi il resto della parola si apre dall'iniziale, stretto e poi largo sull'asse della larghezza. Chiudendo le parole si richiudono nelle iniziali e le lettere tornano nel pulsante a riscrivere MENU.

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 menu spelled by its own letters</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the menu of a small independent press. At rest only the button, with the word MENU. Pressed, its four letters
         leave the button one after the other, drop each onto its own row and become the initial of a link:
         Manifesto, Editions, Notes, Us. Every word then opens out of its initial, narrow and light first, then wide.
         Closing, the words fold back into their initials and the letters fly home to spell MENU again -->
    <div class="frame" data-frame>
      <button class="toggle" type="button" aria-expanded="false" aria-controls="press-menu" data-toggle data-autoclic>
        <span class="toggle__word" aria-hidden="true">
          <span class="toggle__l" data-letter>M</span><span class="toggle__l" data-letter>E</span><span class="toggle__l" data-letter>N</span><span class="toggle__l" data-letter>U</span>
        </span>
        <span class="toggle__close" aria-hidden="true" data-close-word>Close</span>
        <span class="toggle__icon" aria-hidden="true">
          <svg viewBox="0 0 20 20" width="20" height="20">
            <line class="toggle__bar" data-bar x1="3" y1="7" x2="17" y2="7"></line>
            <line class="toggle__bar" data-bar x1="3" y1="13" x2="17" y2="13"></line>
          </svg>
        </span>
        <span class="sr" data-toggle-name>Open the menu</span>
      </button>

      <nav class="menu" id="press-menu" aria-label="Main" data-menu inert>
        <ul class="rows">
          <li class="row" data-row><a class="row__link" href="#manifesto" data-link>
            <span class="row__initial" data-initial><span class="row__glyph" data-glyph>M</span></span><span class="row__rest" data-rest>anifesto</span>
            <span class="row__note" data-note>What we print and why</span>
            <svg class="row__arrow" viewBox="0 0 22 12" width="22" height="12" aria-hidden="true"><path data-arrow d="M1 6h19M15 1.5 20 6l-5 4.5"></path></svg>
            <span class="row__rule" aria-hidden="true" data-rule></span>
          </a></li>
          <li class="row" data-row><a class="row__link" href="#editions" aria-current="page" data-link>
            <span class="row__initial" data-initial><span class="row__glyph" data-glyph>E</span></span><span class="row__rest" data-rest>ditions</span>
            <span class="row__note" data-note>Books and prints</span>
            <svg class="row__arrow" viewBox="0 0 22 12" width="22" height="12" aria-hidden="true"><path data-arrow d="M1 6h19M15 1.5 20 6l-5 4.5"></path></svg>
            <span class="row__rule" aria-hidden="true" data-rule></span>
          </a></li>
          <li class="row" data-row><a class="row__link" href="#notes" data-link>
            <span class="row__initial" data-initial><span class="row__glyph" data-glyph>N</span></span><span class="row__rest" data-rest>otes</span>
            <span class="row__note" data-note>The journal</span>
            <svg class="row__arrow" viewBox="0 0 22 12" width="22" height="12" aria-hidden="true"><path data-arrow d="M1 6h19M15 1.5 20 6l-5 4.5"></path></svg>
            <span class="row__rule" aria-hidden="true" data-rule></span>
          </a></li>
          <li class="row" data-row><a class="row__link" href="#us" data-link>
            <span class="row__initial" data-initial><span class="row__glyph" data-glyph>U</span></span><span class="row__rest" data-rest>s</span>
            <span class="row__note" data-note>Who we are, how to write</span>
            <svg class="row__arrow" viewBox="0 0 22 12" width="22" height="12" aria-hidden="true"><path data-arrow d="M1 6h19M15 1.5 20 6l-5 4.5"></path></svg>
            <span class="row__rule" aria-hidden="true" data-rule></span>
          </a></li>
        </ul>
      </nav>
    </div>
  </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 menu che si scrive con le sue lettere» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco c'è solo il pulsante: una pillola col bordo sottile, la parola MENU in maiuscole spaziate e due righe a destra. Col mouse sopra le lettere prendono peso e si allargano. Premuto, la M esce dal pulsante e cade giù, crescendo, fino alla prima riga, dove passa di un pelo il suo posto e torna; un istante dopo la segue la E, poi la N, poi la U, ognuna con una piccola inclinazione che si raddrizza. Toccando la riga la lettera si schiaccia e si rialza, e sotto di lei una riga grigia sottile si disegna da sinistra. Subito dopo il resto della parola esce dall'iniziale come da una fessura, prima stretto e leggero e poi largo: Manifesto, Editions, Notes, Us. A destra compare una nota piccola che dice cosa c'è dietro. Intanto nel pulsante, rimasto vuoto, compare Close e le due righe diventano una croce. La voce della pagina in cui sei ha l'iniziale vermiglia. Passando col mouse su una voce la parola diventa più pesante, la sua iniziale si inclina e sale di due pixel, a destra si disegna una freccia sottile e le altre voci si schiariscono. Cliccando, l'iniziale si schiaccia, diventa vermiglia, e il menu si richiude: le note spariscono, le parole si stringono e rientrano nelle iniziali dall'ultima alla prima, le righe si ritirano e le lettere volano su nel pulsante, ognuna al suo posto, finché c'è di nuovo scritto MENU.

Come funziona

Una lettera, due elementi

Nel pulsante ogni lettera di MENU è uno span; nella riga c'è la stessa lettera come iniziale della voce. Aprendo, getBoundingClientRect dice dove sta la lettera nel pulsante e dove sta l'iniziale nella sua riga: l'iniziale parte spostata di quella differenza, con la scala del rapporto fra le due altezze (transform-origin in alto a sinistra), e la lettera del pulsante sparisce nello stesso istante. Si vede una lettera sola che si stacca e vola.

La caduta su una molla

Una timeline porta ogni iniziale a x 0, y 0 e scala 1 con elastic.out(1, SETTLE) in FLIGHT secondi, STAGGER secondi dopo la precedente; una rotazione di più o meno 7 gradi si raddrizza con back.out. Quando la lettera tocca, il glifo dentro (un figlio, per non litigare col transform del volo) fa scaleY 0,86 e torna su un elastico, e la riga sotto passa da scaleX 0 a 1 da sinistra.

La parola che si apre dall'iniziale

Il resto della parola è uno span accanto all'iniziale, con clip-path inset(-20% 100% -20% 0) che lo nasconde da destra a sinistra: GSAP lo porta a inset(-20% 0% -20% 0) in OPEN_WORD secondi, e intanto anima la variabile CSS --wdth da NARROW a 100, che font-variation-settings legge sull'asse della larghezza di Mona Sans. La parola esce stretta e si allarga mentre si scopre.

La voce sotto il puntatore

paintHot() anima la variabile --wght della voce calda a WEIGHT[1] e delle altre a WEIGHT[0] (quella della pagina corrente a metà), schiarisce le altre righe di DIM, inclina e solleva il glifo caldo con back.out e disegna la freccia con stroke-dashoffset. La tastiera fa lo stesso col fuoco: frecce, Home e Fine.

Il ritorno nel pulsante

Chiudendo, le parole tornano strette e si richiudono col clip-path dall'ultima alla prima, le righe si ritirano, e ogni iniziale vola al punto misurato di nuovo sulla sua lettera nel pulsante con power3.inOut; arrivata, sparisce e la lettera del pulsante ricompare con un piccolo rimbalzo. I voli di ritorno si fermano se il menu si riapre a metà.

Valori da cambiare

NomeFileDi partenzaCosa cambia
FLIGHTscript.js0.95I secondi che una lettera impiega a volare dal pulsante alla sua riga.
STAGGERscript.js0.08I secondi fra una lettera e l'altra, all'apertura e alla chiusura.
SETTLEscript.js0.72Quanto calma atterra una lettera: basso oscilla oltre la riga, alto si ferma subito (da 0,3 a 1).
OPEN_WORDscript.js0.6I secondi che una parola impiega ad aprirsi dalla sua iniziale.
NARROWscript.js75Quanto è stretta una parola quando comincia ad aprirsi, sull'asse della larghezza (da 75 a 100).
WEIGHTscript.js[380, 640]Il peso di una parola a riposo e sotto il puntatore (da 200 a 900).
DIMscript.js0.42Quanto si schiariscono le altre voci mentre una è sotto il puntatore (da 0 a 1).

Provali nel Playground

Quando usarla

Per il menu di chi lavora con le parole: una casa editrice, una stampa indipendente, una rivista, uno studio di grafica, un blog personale. Funziona quando le iniziali delle voci scrivono la parola del pulsante: qui MENU, ma può essere INDEX, WORK o il nome del marchio, scegliendo voci che cominciano con quelle lettere.

Sul telefono

Il menu è largo quanto lo schermo meno 32 pixel (al massimo 400) e l'altezza delle righe si prende dall'altezza della finestra, fra 42 e 66 pixel, così pulsante e quattro voci stanno sempre dentro; sotto i 360 pixel le note a destra non ci sono. Le stesse animazioni: le lettere cadono e le parole si aprono. Il tocco su una voce la sceglie e richiude il menu.

Con il movimento ridotto

Niente voli né cadute: aprendo, le lettere del pulsante sfumano e le voci compaiono in dissolvenza già intere al loro posto, una appena dopo l'altra; sotto il puntatore cambiano solo il peso, la freccia e la luce delle altre voci. Chiudendo le voci sfumano e MENU ricompare.

Trappole

  • Il transform di GSAP sull'iniziale (il volo, con la scala) cancellerebbe lo schiacciamento dell'atterraggio: lo schiacciamento sta sul glifo, un figlio dell'iniziale.
  • La posizione di partenza si misura con l'iniziale rimessa a x 0, y 0 e scala 1, altrimenti getBoundingClientRect legge il transform del volo precedente e la lettera parte dal punto sbagliato.
  • Chiudendo e riaprendo in fretta, i voli di ritorno ancora in corso finivano dopo l'apertura e spegnevano le iniziali appena atterrate: ora si fermano quando il menu si riapre.
  • Il clic dell'anteprima e Invio sul pulsante fanno tutti e due un clic senza dettagli (detail 0): un tasto appena premuto apre il menu col fuoco sulla pagina corrente, senza il giro.

Librerie

GSAP 3.15.0, Mona Sans (font variabile, con gli assi del peso e della larghezza) 5.3.0.

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

Collaudo

Provata il 23 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