Bordo che cresce in hover in Webflow (CSS + GSAP)

Intermedio 16:32 webflowgsapcsshoverconic-gradient

Costruisci un bordo circolare che cresce in hover in Webflow con un conic-gradient e una @property animabile; GSAP fa solo il toggle di una classe mentre il CSS anima.

Punti chiave

  • Qui GSAP non anima il bordo — fa solo il toggle di una classe, e il CSS gestisce tutta l'animazione. Più pulito e leggero che guidarlo da JavaScript.
  • Il "bordo" è finto: un wrapper leggermente più grande il cui conic-gradient di sfondo spunta attorno al cerchio interno, così far crescere il gradiente sembra un bordo che si disegna da solo.
  • Le variabili CSS normali non si animano, ma una @property registrata (syntax percentage, initial 0%) sì — è questo che fa transizionare fluidamente il riempimento del conic-gradient.
  • Imposta il fill dell'SVG a currentColor e metti il colore sul link genitore (non sull'icona) così una sola transizione di font color ricolora l'icona in hover.
  • Il targeting per attributo più un filtro "direct parent of trigger" fa sì che una sola interazione hover animi solo il bordo del link su cui passi — e tutto il setup è subito riutilizzabile.

Capitoli del video

  1. 00:00 Intro
  2. 01:00 Preparare la struttura
  3. 03:54 Creare l'effetto hover sul colore dell'icona
  4. 05:39 Setup HTML del bordo che cresce
  5. 07:18 Setup CSS del bordo che cresce
  6. 11:31 Setup GSAP del bordo che cresce
  7. 15:26 Outro

Questo è uno di quegli effetti hover che sembrano sofisticati ma girano su quasi zero codice: un bordo circolare fluido che cresce attorno a un link social, in sincrono con l’icona che cambia colore. La sorpresa è che GSAP non anima mai il bordo — fa solo il toggle di una classe, e il CSS gestisce tutta l’animazione dietro le quinte.

È una bella vetrina di due feature CSS poco usate — i conic gradient e la regola @property — più il tema ricorrente di questo corso: usa GSAP solo dove serve davvero.

Come funziona

Il colore dell’icona è puro CSS. Il link è un cerchio (display: flex, centrato, border-radius: 100%, sfondo scuro) con un’icona SVG il cui path usa fill: currentColor. Il trucco: se imposti il colore sull’embed dell’icona, sovrascrive quello ereditato, quindi un hover sul genitore non lo raggiunge. Metti invece il colore sul link genitore, aggiungi una transizione di font-color e imposta il colore nello stato hover — ora l’icona eredita e anima grigio → verde in hover, senza JavaScript.

Il bordo è un’illusione. Non c’è nessuna proprietà border. Avvolgi il link in un cerchio leggermente più grande (section_link-wrapper, border-radius: 100%); il link interno ne copre gran parte, lasciando visibile solo un anello sottile. Dai a quell’anello uno sfondo conic-gradient (conic perché il colore si diffonde radialmente attorno a un cerchio), e anima quanto il gradiente si riempie — da niente fino a tutto il giro — e si legge come un bordo che si disegna da solo.

@property rende animabile il gradiente. Non puoi transizionare fluidamente una variabile CSS normale — il browser la tratta come testo. Quindi registra la quantità di riempimento con la regola @property (syntax: '<percentage>', inherits: true, initial-value: 0%), che dice al browser che è un valore reale e tipizzato. Metti una transition su quella proprietà (0.8s, expo) e una regola che la porta a 100% quando è presente una classe on-hover. Ecco il CSS esatto dal cloneable:

<!-- Embed sul body, trascinato sopra la sezione così carica per primo -->
<style>
  @property --fill {
    syntax: '<percentage>';
    inherits: true;
    initial-value: 0%;
  }

  [data-animate-link-border] {
    transition: --fill 0.8s cubic-bezier(.19, 1, .22, 1);
    background: conic-gradient(greenyellow var(--fill), transparent var(--fill));

    &.on-hover {
      --fill: 100%;
    }
  }
</style>

L’unico compito di GSAP è la classe. Un’interazione hover (mouse-enter + mouse-leave) usa una action set per fare il toggle della classe on-hover sul wrapper — colpito via data-animate-link-border con un filtro direct parent of trigger così solo il wrapper del link su cui passi è interessato. La transizione CSS fa il resto: fill a 100% all’enter, di nuovo a 0% al leave. Dato che è guidato da attributi, duplicare il link “funziona e basta” — ognuno anima in modo indipendente.

Come si usa

  1. Link + icona. Link block (section_link): flex centrato, 7rem quadrato, sfondo scuro, border-radius: 100%. Dentro, un embed con il tuo SVG (path fill: currentColor), display: flex. Metti il colore sul link (non sull’embed), aggiungi una transizione di font-color (0.8s expo) e imposta il colore nello stato hover.

  2. Wrapper del finto bordo. Avvolgi il link in section_link-wrapper: quadrato leggermente più grande, flex centrato, border-radius: 100%. Aggiungi l’attributo data-animate-link-border.

  3. Il CSS. Aggiungi un embed sul body con il CSS @property + conic-gradient qui sopra (mettilo display: none e trascinalo sopra la sezione così carica per primo).

  4. Registra la classe. Aggiungi un div nascosto con la classe on-hover (idealmente in uno style guide) così Webflow la mantiene e GSAP può farne il toggle.

  5. L’interazione. Aggiungi data-animate-link al link. Crea un’interazione hover con mouse-enter + mouse-leave; una action set che fa il toggle della classe on-hover, target data-animate-link-border filtrato per direct parent of trigger. Abilita il codice custom (o pubblica) per testare — il CSS non standard non gira nella preview semplice.

Il CSS qui sopra è il blocco esatto del cloneable — si riempie con la keyword greenyellow e un ease expo; cambia il colore a piacere.

Risorse

Nella knowledge base

Pagine di riferimento derivate da questa lezione — lo stesso materiale riorganizzato per concetto, così cerchi una cosa sola senza riguardare il video. In inglese.

  • Target filters — resolving a target relative to the trigger

    An action's target is not one setting but three composed into a sentence — what to target, a filter, and the element the filter is measured against — so "the sidebar that is the previous sibling of the trigger" is Previous sibling of + Trigger element, not a single menu option; this is what lets one interaction serve every card in a CMS collection.

  • Draw a border on hover with a conic gradient

    There is no border — a slightly larger wrapper behind the element leaves a visible ring, filled by a conic gradient whose fill percentage is registered with @property so it can actually transition; GSAP's only job is toggling one class on the hovered instance's wrapper.

  • A style cleanup deletes the classes your interactions toggle

    A class that exists only to be added by a GSAP set action is applied to no element, so Webflow flags it as unused and any style cleanup deletes it — publishing itself does not strip it, which means this breaks work that was already correct, later, when someone tidies the project; keep an element wearing the class so it is genuinely used and never appears in a cleanup list.

  • It works in the Designer but not live — or the reverse

    Custom code, non-standard CSS properties, first-paint flicker, scroll lock and keyboard focus all behave differently in the Designer and in plain preview than on the published site, and the Designer additionally shows you your animations' initial states, so half-hidden content while building is expected rather than broken.

  • Verified identifiers

    Every exact attribute name, class name, variable name, SVG id and selector used across the GSAP-in-Webflow corpus, each traced to the cloneable it was copied from; copy these verbatim and never reconstruct one from memory, because a wrong identifier fails silently.

Domande frequenti

Come animo un bordo che cresce attorno a un elemento circolare in Webflow?
Non animare una proprietà border. Avvolgi l'elemento in un cerchio leggermente più grande il cui sfondo è un conic-gradient, e anima quanto quel gradiente si riempie. Man mano che il riempimento cresce da 0% a 100%, il colore gira attorno al cerchio e sembra un bordo che si disegna da solo.
Perché usare @property invece di una normale variabile CSS?
I browser trattano le variabili CSS normali come semplice testo, quindi non sempre transizionano fluidamente. Registrare il valore con @property (syntax: '<percentage>', initial-value: 0%) dice al browser che è un valore reale, tipizzato e animabile — ed è questo che fa animare il riempimento del conic-gradient.
GSAP dovrebbe animare il bordo direttamente?
No — ed è il punto. GSAP fa solo il toggle di una classe on-hover con una set action; la transizione CSS sulla proprietà registrata fa l'animazione vera. È più leggero e semplice che animare il valore da JavaScript, e tiene il movimento nel CSS dove sta bene.
Come ricoloro un'icona SVG in hover in Webflow?
Dai al path dell'SVG fill: currentColor, poi imposta il colore sul link genitore invece che sull'embed dell'icona (un colore messo direttamente sull'embed sovrascrive quello ereditato). Aggiungi una transizione di font-color sul link e imposta il colore nello stato hover — l'icona ora anima il suo colore in hover senza JavaScript.