Utilizzare shape() per il ritaglio adattabile

Data di pubblicazione: 8 aprile 2025

La proprietà clip-path ti consente di modificare la forma di un elemento ritagliandolo in un cerchio, un poligono o persino un percorso SVG. Tuttavia, prima di Chrome 135 e Safari 18.4, dovevi scegliere tra poligoni reattivi e forme più complesse non reattive che utilizzano i percorsi SVG. Con la nuova funzione shape(), un clip-path può ritagliare l'elemento in una forma non poligonale che sia anche reattiva.

Browser Support

  • Chrome: 135.
  • Edge: 135.
  • Firefox: 148.
  • Safari: 18.4.

Source

Crea una forma a bandiera

Ad esempio, confronta la creazione di una forma a bandiera con clip-path: path() e clip-path: shape().

Una forma a bandiera verde con linee curve nella parte superiore e inferiore.

La forma di una bandiera non è esattamente un poligono, in quanto i bordi superiore e inferiore sono curve di Bézier cubiche anziché linee rette o angoli arrotondati.

Crea il flag con clip-path: path()

Una forma come questa bandiera può essere rappresentata utilizzando un percorso SVG:

.flag {
  clip-path: path(
    "M 0 20 \
     C 25 0 75 40 100 20 \
     V 80 \
     C 75 100 25 60 0 80 \
     z");
}

Per semplificare, un percorso SVG è una serie di comandi di percorso:

  1. Sposta in 0, 20.
  2. Curva a 100, 20, utilizzando i punti di controllo (25,0 e 75, 40).
  3. Linea verticale fino a 80.
  4. Curva a 0, 80, utilizzando i punti di controllo (75,100 e 25,50).
  5. Chiudi il percorso (linea a 0,20).

In questo modo viene disegnata una forma a bandiera, ma tutte le unità sono in pixel. Il formato SVG può scalare questi pixel in una casella di visualizzazione, ma in modo che l'aspetto sia sempre quello di una scala geometrica dell'intera forma.

Ad esempio, se vuoi scalare l'intero rettangolo, ma mantenere l'altezza e la larghezza delle curve a 20 px, SVG non sarebbe all'altezza del compito.

Crea il flag con shape()

Confronta lo stesso risultato utilizzando shape(). La funzione di forma accetta una serie di comandi, simili ai comandi del percorso SVG. Tuttavia, questi comandi accettano lunghezze e percentuali CSS, in qualsiasi unità CSS.

Il seguente CSS converte il flag shape() con unità percentuali:

.flag {
  clip-path: shape(from 0% 20%,
     curve to 100% 20% with 25% 0% / 75% 40%,
     vline to 80%,
     curve to 0% 80% with 75% 100% / 25% 60%,
     close
  );
}

Rendere il sito web responsive

Con l'intera gamma di lunghezze CSS disponibili, puoi scegliere quali utilizzare per ogni coordinata.

Ad esempio, per scalare l'intera dimensione del flag in base alla dimensione dell'elemento, ma mantenere costante l'altezza della curva, puoi procedere nel seguente modo:

.flag {
  clip-path: shape(from 0% 20px,
     curve to 100% 20px with 25% 0% / 75% 40px,
     vline to calc(100% - 20px),
     curve to 0% calc(100% - 20px) 
           with 75% 100% / 25% calc(100% - 40px),
     close
  );
}

Aggiungere proprietà personalizzate e animazioni

Ora che la forma è definita in CSS, puoi anche utilizzare proprietà personalizzate per manipolare facilmente l'altezza:

.flag {
  --wave-height: 40px;
  clip-path: shape(
    from 0px var(--wave-height),
    curve to 100% var(--wave-height) 
          with 25% 0px / 75% calc(var(--wave-height) * 2),
    vline to calc(100% - var(--wave-height)),
    curve to 0 calc(100% - var(--wave-height))
          with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
    close
  )
}

Puoi persino animare la proprietà CSS utilizzando il descrittore @property e bloccarla in modo che non superi i limiti:

@property --animated-wave-height {
  syntax: "<length>";
  inherits: false;
  initial-value: 40px;
}

@keyframes curve {
  from { --animated-wave-height: 0px; }
  to { --animated-wave-height: 180px; }
}

.flag {
  width: 600px;
  height: 400px;
  background: green;
  animation: curve 1s infinite alternate;
  --wave-height: calc(min(var(--animated-wave-height, 40px), 40%));
  clip-path: shape(
    from 0px var(--wave-height),
    curve to 100% var(--wave-height)
          with 25% 0px / 75% calc(var(--wave-height) * 2),
    vline to calc(100% - var(--wave-height)),
    curve to 0 calc(100% - var(--wave-height)) 
          with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
    close
  )
}

Prova la demo

In Chrome 135 o Safari 18.4, puoi vedere la forma della bandiera animata creata utilizzando clip-path: shape() in questa demo di CodePen.

Riepilogo

clip-path: shape() ti consente di ritagliare l'elemento utilizzando forme arbitrarie e reattive, in precedenza possibili solo utilizzando tecniche come gradienti conici o SVG creati con JavaScript.

Controlla la specifica per la sintassi completa.

Al momento funziona solo per clip-path. In futuro, prevediamo di utilizzare questo tipo di forma per impostare la forma del bordo dell'elemento, il che consentirebbe di esprimersi in modi ancora più non rettangolari.