30 luglio 2026

Animare elementi lungo il bordo con CSS: offset-path: border-box

Un trucco moderno per far “scorrere” icone, badge o particelle lungo il perimetro di un box, senza SVG e senza calcoli manuali.

Con motion path in CSS puoi posizionare un elemento lungo il bordo di un contenitore e animarlo semplicemente variando offset-distance. Usando offset-path: border-box e qualche custom property ottieni effetti “whimsical” (stelline, particelle, indicatori) con pochissimo codice e con un controllo fine su ritardi, distanze e micro-spostamenti.

L’idea: un motion path senza SVG

Per anni, quando si voleva far “seguire un percorso” a un elemento UI, la risposta tipica era: SVG path. Funziona, ma introduce complessità (markup, coordinate, scaling, manutenzione).

Oggi puoi ottenere un effetto simile con i CSS Motion Path, e la cosa sorprendente è che per far orbitare un elemento lungo il bordo di un contenitore non serve definire alcun path personalizzato: basta usare il box stesso come percorso.

Il cuore del trucco è qui:

  • posizioni l’elemento in absolute
  • gli assegni un offset-path legato al box (es. border-box)
  • lo fai “viaggiare” variando offset-distance

Posizionare un elemento sul bordo con offset-path: border-box

Immagina un contenitore (card, button, banner) e un piccolo elemento decorativo (stellina, puntino, badge).

.card {
  position: relative;
}

.card .sparkle {
  position: absolute;
  offset-path: border-box;
}

Senza offset-path, un assoluto resta dove lo metti (top/left, ecc.). Con offset-path: border-box, invece, l’elemento viene ancorato al perimetro del box: hai un percorso pronto, già coerente con dimensioni e responsive.

Nota mentale utile: qui non stai “disegnando” una traiettoria; stai dicendo al browser “il percorso è il bordo di questo box”.

Animare il movimento: offset-distance

A questo punto l’animazione è quasi banale: ti basta cambiare la distanza percorsa lungo il path.

.card .sparkle {
  position: absolute;
  offset-path: border-box;
  offset-distance: 0%;
  transition: offset-distance 600ms ease;
}

.card:hover .sparkle {
  offset-distance: 70%;
}
  • offset-distance: 0% = punto di partenza sul percorso
  • 70% = percorre circa i 2/3 del bordo

Questo approccio è perfetto per hover “leggeri”: un dettaglio animato che aggiunge personalità senza dover orchestrare keyframe complessi.

Sfasare più elementi (e ottenere un effetto più ricco)

Il salto di qualità arriva quando metti più particelle e le fai muovere con timing diversi, così non sembrano “incollate” tra loro.

Un pattern comodo è usare custom properties per ritardi e distanze:

.card .sparkle {
  position: absolute;
  offset-path: border-box;
  offset-distance: var(--start, 0%);
  transform: translate(var(--tx, 0px), var(--ty, 0px));
  transition:
    offset-distance 700ms cubic-bezier(.2,.8,.2,1);
}

.card:hover .sparkle {
  offset-distance: var(--travel, 70%);
}

.card .sparkle:nth-child(1) {
  --travel: 70%;
  --tx: 2px;
  --ty: -1px;
}

.card .sparkle:nth-child(2) {
  --travel: 55%;
  --tx: -3px;
  --ty: 2px;
}

.card .sparkle:nth-child(3) {
  --travel: 85%;
  --tx: 1px;
  --ty: 3px;
}

Cose interessanti qui:

  • Distanze diverse (--travel) → ogni elemento percorre un tratto unico.
  • Micro-spostamenti con translate() → rompi la perfezione geometrica e l’effetto risulta più “vivo”.
  • Invece di sincronizzare tutto, puoi aggiungere anche delay o durate differenti per creare “scie” e sfasamenti.

Quando usarlo (e quando evitarlo)

Ottimo per

  • micro-interazioni su card e CTA
  • decorazioni “orbitanti” (stelline, punti luce, badge)
  • indicatori che seguono il bordo (in modo sottile)

Attenzione a

  • accessibilità: rispetta prefers-reduced-motion se l’animazione è evidente
  • performance: tante particelle + hover frequenti possono appesantire, specialmente su mobile
  • supporto: i motion path sono moderni; verifica compatibilità se hai target browser conservativi

Esempio rapido di rispetto per chi riduce le animazioni:

@media (prefers-reduced-motion: reduce) {
  .card .sparkle {
    transition: none;
  }
}

Sintesi: un perimetro come “traccia” pronta all’uso

Con offset-path: border-box ottieni un percorso responsivo gratis: il bordo del tuo componente. Con offset-distance controlli il movimento lungo quel percorso in modo estremamente semplice. Aggiungendo custom properties per distanze, tempi e piccoli translate, puoi costruire micro-animazioni eleganti e variate con pochissimo CSS.

L’implicazione pratica è chiara: se ti serve un effetto “segue il bordo” per rendere più curata una UI, oggi puoi farlo direttamente in CSS, senza introdurre SVG o coordinate difficili da mantenere.