Utiliser shape() pour le recadrage responsif

Publié le : 8 avril 2025

La propriété clip-path vous permet de modifier la forme d'un élément en le découpant en cercle, en polygone ou même en chemin SVG. Toutefois, avant Chrome 135 et Safari 18.4, vous deviez choisir entre des polygones responsifs et des formes plus complexes non responsives utilisant des chemins SVG. Avec la nouvelle fonction shape(), un clip-path peut découper l'élément selon une forme non polygonale qui est également responsive.

Browser Support

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

Source

Créer une forme de drapeau

Par exemple, comparez la création d'une forme de drapeau avec clip-path: path() et clip-path: shape().

Forme de drapeau vert avec des lignes courbes en haut et en bas.

La forme d'un drapeau n'est pas exactement un polygone, car ses bordures supérieure et inférieure sont des courbes de Bézier cubiques plutôt que des lignes droites ou des angles arrondis.

Créez l'indicateur avec clip-path: path().

Une forme telle que ce drapeau peut être représentée à l'aide d'un tracé 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");
}

Pour être plus précis, un chemin SVG est une série de commandes de chemin :

  1. Déplacez-vous à la position 0, 20.
  2. Courbe vers 100, 20, en utilisant les points de contrôle (25,0 et 75, 40).
  3. Ligne verticale à 80.
  4. Courbe à 0, 80, à l'aide des points de contrôle (75,100 et 25,50).
  5. Fermez le chemin d'accès (ligne à 0,20).

Cela dessine une forme de drapeau, mais toutes les unités sont en pixels. SVG peut mettre à l'échelle ces pixels dans une boîte de vue, mais de manière à ce que l'ensemble de la forme ressemble toujours à une échelle géométrique.

Par exemple, si vous souhaitez que l'ensemble du rectangle soit mis à l'échelle, mais que la hauteur et la largeur des courbes restent de 20 px, SVG ne sera pas à la hauteur.

Créez l'indicateur avec shape().

Comparez le même résultat à l'aide de shape(). La fonction de forme accepte une série de commandes, semblables aux commandes de tracé SVG. Toutefois, ces commandes acceptent les longueurs et les pourcentages CSS, dans n'importe quelle unité CSS.

Le code CSS suivant convertit le flag A shape() avec des unités de pourcentage :

.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
  );
}

Rendez-le responsive

Vous pouvez choisir les longueurs CSS à utiliser pour chaque coordonnée.

Par exemple, pour que la taille de l'ensemble du drapeau soit mise à l'échelle en fonction de la taille de l'élément, mais que la hauteur de la courbe reste constante, vous pouvez procéder comme suit :

.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
  );
}

Ajouter des propriétés et des animations personnalisées

Maintenant que la forme est définie en CSS, vous pouvez également utiliser des propriétés personnalisées pour manipuler facilement la hauteur :

.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
  )
}

Vous pouvez même animer la propriété CSS à l'aide du descripteur @property et la limiter pour qu'elle ne dépasse pas les limites :

@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
  )
}

Essayer la démo

Dans Chrome 135 ou Safari 18.4, vous pouvez voir la forme du drapeau animé créée à l'aide de clip-path: shape() dans cette démo CodePen.

Résumé

clip-path: shape() vous permet de découper votre élément à l'aide de formes arbitraires et responsives, ce qui n'était auparavant possible qu'à l'aide de techniques telles que les dégradés coniques ou les SVG construits en JavaScript.

Consultez les spécifications pour connaître la syntaxe complète.

Pour le moment, cela ne fonctionne que pour clip-path. À l'avenir, nous prévoyons d'utiliser ce type de forme pour définir la forme de la bordure de l'élément, ce qui permettrait d'exprimer encore plus de formes non rectangulaires.