Alla fine di questa lezione saprai creare underline all’hover fluidi e crescenti in Webflow — quelli eleganti che entrano dal basso, dall’alto, da sinistra o da destra, o riempiono tutta l’altezza del testo — solo con box-shadow e un paio di transizioni, e zero codice custom.
Il trucco dietro ogni variazione è lo stesso: non usare un bordo vero. Un bordo si aggiunge al box dell’elemento, quindi animarlo spinge tutto ciò che gli sta intorno. Un box-shadow, invece, è disegnato fuori dal box di layout — può crescere e restringersi senza disturbare un solo vicino. Impara l’unico setup di base e gli altri sei effetti sono solo un offset modificato.
Lo mostro sui link perché sono la scelta naturale, ma la stessa identica logica funziona su un link block, un container, una section — qualsiasi elemento vuoi.
Come funziona
L’effetto base — una linea che cresce dal basso — si costruisce in tre mosse. Primo, dai stile al link: imposta il suo color su inherit (così non resta il blu-link di default) e rimuovi l’underline di default con text-decoration: none. Secondo, aggiungi un box-shadow inset con ogni valore (X, Y, blur, size) a zero e il colore su quello che vuoi per l’underline. Terzo, metti una transizione sul box-shadow — un 600ms abbastanza lungo con ease-out cubic è ciò che lo rende fluido (puoi mettere una transizione anche sul color, allo stesso modo). Poi nello stato hover, sposta l’offset Y dell’ombra a un piccolo valore negativo come -1vw. Ecco tutto l’effetto: l’ombra invisibile a dimensione zero cresce in un underline netto che sale dal basso.
Quando scatta, la direzione è solo un offset. Porta l’Y hover a 1vw positivo e la linea cresce dall’alto. Sposta il valore sull’asse X — 1vw positivo la fa crescere da sinistra, 1vw negativo da destra. L’unico passo extra per le versioni orizzontali è aggiungere un po’ di padding corrispondente (sinistra o destra) così c’è davvero spazio per far apparire la linea accanto al testo.
Il riempimento a tutta altezza sembra più elaborato ma usa lo stesso offset Y — l’unica domanda è quanto farlo alto. Qui non puoi usare una percentuale, quindi il valore viene dal font: moltiplica il font-size per una line-height senza unità. Con font-size: 7vw e line-height: 1.5, fa 7 × 1.5 = 10.5vw, quindi l’offset Y hover è -10.5vw (positivo per un riempimento dall’alto). Se la tua line-height ha già un’unità (px, em…), usa quel valore diretto. Due tocchi finali: aggiungi padding orizzontale così il riempimento ha respiro, e cambia il color del testo con qualcosa a contrasto (tipo bianco) all’hover — altrimenti il testo sparisce nell’ombra.
Infine, il bonus multi-linea è solo l’idea base applicata due volte. Aggiungi due ombre inset nello stato normale, poi all’hover dagli offset opposti — una 1vw, una -1vw — per animare alto e basso insieme. Spostale sull’asse X per sinistra e destra. Stesso meccanismo, più lati. Ognuno di questi effetti è puro box-shadow e transizioni — niente codice custom da nessuna parte.
Come si usa
- Dai stile al link — imposta
color: inheritetext-decoration: nonecosì prende il colore del body e perde l’underline di default. - Aggiungi l’ombra base — un
box-shadowinset con X, Y, blur e size tutti a0e il colore sul tuo accento (es. blu Webflow). - Aggiungi la transizione — transizione sul
box-shadowa ~600ms,ease-out cubic(opzionalmente anche sulcolor, stessi valori). - Imposta l’hover — nello stato hover, cambia l’offset Y del box-shadow a
-1vwper un underline dal basso. Ecco l’effetto classico fatto. - Cambia direzione — porta l’Y a
+1vwper l’alto, o sposta il valore sull’offset X (+1vwsinistra,-1vwdestra); per sinistra/destra, aggiungi padding corrispondente così la linea ha spazio. - Fallo a tutta altezza — imposta l’offset Y hover a
font-size × line-height(es.10.5vwper 7vw × 1.5), aggiungi padding orizzontale e cambia il colore del testo con uno a contrasto all’hover. - Anima più lati — aggiungi due ombre inset nello stato normale e dagli offset opposti all’hover (alto + basso, o sinistra + destra).
Ecco un’intera collezione di underline all’hover da un’unica idea: un’ombra inset che riveli con una transizione. Padroneggia il setup base e ogni variazione è una modifica di due secondi.