Présentation
Le masquage CSS vous permet de découper un élément selon une forme personnalisée, par exemple en ajoutant une encoche à une carte ou en créant une bordure profilée. Lorsque vous combinez des formes pour des mises en page complexes, choisissez votre stratégie de masquage en fonction du type de contenu de l'élément :
| Stratégie de masquage | Application idéale | Impact du texte |
|---|---|---|
| Masquage SVG d'élément direct | Images, icônes, formes décoratives, formes complexes | Non recommandé (peut recadrer le texte) |
| Masquage SVG d'éléments adjacents | Fiches avec du texte, contenu crucial | Le texte reste entièrement lisible |
| Dégradés CSS purs | Formes géométriques simples | Non recommandé (peut recadrer le texte) |
Implémentation
Pour implémenter des découpes de forme :
Utiliser un masque SVG
Les masques SVG vous permettent de définir des formes qui se soustraient ou s'ajoutent à la zone visible à l'aide de remplissages blancs (afficher) et noirs (masquer).
Masquage par luminance ou par canal alpha : les masques SVG utilisent par défaut le mode luminance (luminosité). C'est pourquoi nous utilisons
fill="white"pour révéler des zones etfill="black"pour les découper. Si vous préférez utiliser la transparence du SVG (canal alpha) au lieu des couleurs, vous pouvez définirmask-type: alpha;en CSS oumask-type="alpha"sur l'élément SVG<mask>.
Masquage SVG d'élément direct
Lorsqu'il n'y a pas de texte à l'intérieur de l'élément (comme les avatars de profil, les images de produits ou les illustrations), vous pouvez appliquer le masque SVG directement à l'élément.
L'utilisation de maskContentUnits="objectBoundingBox" dans le masque SVG garantit que le masque s'adapte automatiquement à la largeur et à la hauteur de tout élément auquel il est appliqué.
<!-- 1. Define the mask in SVG (hidden from view) -->
<svg width="0" height="0" style="position: absolute;" aria-hidden="true">
<defs>
<!-- objectBoundingBox makes the mask scale from 0 to 1 along the element's borders -->
<mask id="splat-mask" maskContentUnits="objectBoundingBox">
<!-- Organic Bezier path defining an artistic paint splat shape -->
<path d="M 0.5 0.05 C 0.58 0.05, 0.58 0.21, 0.67 0.18 C 0.76 0.15, 0.79 0.08, 0.85 0.15 C 0.91 0.22, 0.83 0.32, 0.89 0.38 C 0.95 0.44, 1.03 0.45, 0.99 0.55 C 0.95 0.65, 0.82 0.62, 0.8 0.72 C 0.78 0.82, 0.89 0.92, 0.8 0.97 C 0.71 1.02, 0.64 0.88, 0.55 0.93 C 0.46 0.98, 0.44 1.06, 0.35 1.01 C 0.26 0.96, 0.31 0.81, 0.22 0.79 C 0.13 0.77, 0.01 0.88, 0.01 0.77 C 0.01 0.66, 0.16 0.62, 0.14 0.52 C 0.12 0.42, -0.02 0.39, 0.03 0.29 C 0.08 0.19, 0.23 0.27, 0.29 0.19 C 0.35 0.11, 0.3 0.01, 0.4 0.01 C 0.5 0.01, 0.42 0.05, 0.5 0.05 Z" fill="white" />
</mask>
</defs>
</svg>
<!-- 2. Apply the mask to the image element -->
<img src="avatar.jpg" alt="User Profile" class="shaped-avatar">
<style>
.shaped-avatar {
width: 200px;
height: 200px;
object-fit: cover;
/* Apply the SVG mask ID with standard and webkit-prefixed properties */
-webkit-mask-image: url(#splat-mask);
mask-image: url(#splat-mask);
}
</style>
Masquage SVG d'éléments adjacents
Appliquez le masque à un élément adjacent plutôt qu'à l'élément parent contenant du texte. Cela permet d'éviter que le texte ne soit tronqué et de garantir sa lisibilité.
Pour résoudre ce problème, structurez votre composant en deux parties :
- Un conteneur de texte sécurisé et non masqué (
.card-body) pour tout le contenu lisible. - Un
divdécoratif vide (.card-accent) placé à côté, qui reçoit le masque SVG personnalisé.
En attribuant la même couleur d'arrière-plan aux deux parties, elles fusionnent visuellement en un seul composant de forme personnalisée.
<!-- 1. Define the SVG mask (hidden from view) -->
<svg width="0" height="0" style="position: absolute;" aria-hidden="true">
<defs>
<!-- Use objectBoundingBox to make the mask scale with the element -->
<mask id="accent-stencil" maskContentUnits="objectBoundingBox">
<!-- Fill the entire area with white (fully visible) -->
<rect width="1" height="1" fill="white" />
<!-- Draw a black shape to cut out a concave curve. Extending the path to x=1.1 guarantees it fully clears the right edge, preventing subpixel lines -->
<path d="M 1.1,0 C 0.4,0.1 0.4,0.9 1.1,1 L 1.1,0 Z" fill="black" />
</mask>
</defs>
</svg>
<!-- 2. Create the unified card layout -->
<div class="unified-card">
<!-- The text-bearing element remains unmasked and perfectly rectangular -->
<div class="card-body">
<h3>Premium Membership</h3>
<p>Get exclusive weekly updates on modern web standards and premium UI designs.</p>
</div>
<!-- The empty accent element next to it is masked to form the custom shape -->
<div class="card-accent"></div>
</div>
<style>
.unified-card {
display: flex;
width: 400px;
}
.card-body {
flex: 1;
background-color: #1e293b; /* Elegant slate color */
color: #f8fafc;
padding: 24px;
border-top-left-radius: 16px;
border-bottom-left-radius: 16px;
}
.card-accent {
width: 60px;
background-color: #1e293b; /* Same background color so they merge visually without seams */
border-top-right-radius: 16px;
border-bottom-right-radius: 16px;
/* Reference the SVG mask */
-webkit-mask-image: url(#card-accent-mask);
mask-image: url(#card-accent-mask);
}
</style>
Utiliser un seul dégradé CSS pour les découpes simples
Lorsque vous n'avez besoin que de découpes géométriques simples (comme une encoche supérieure semi-circulaire, des encoches latérales ou des découpes diagonales droites), vous n'avez pas besoin d'écrire ni de référencer un SVG externe. À la place, vous pouvez définir un dégradé radial ou linéaire CSS directement dans la propriété mask-image.
<div class="gradient-masked-card">
<h3>Notched Coupon Card</h3>
<p>This card uses a pure CSS radial gradient to cut out a semi-circular notch along its top edge.</p>
</div>
<style>
.gradient-masked-card {
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
color: white;
padding: 40px 24px 24px 24px; /* Extra top padding ensures content clears the notch */
border-radius: 16px;
text-align: center;
/* radial-gradient places a circle at 50% (horizontal center) and 0% (top edge), cutting out a 20px transparent notch */
-webkit-mask-image: radial-gradient(circle at 50% 0%, transparent 20px, black 21px);
mask-image: radial-gradient(circle at 50% 0%, transparent 20px, black 21px);
}
</style>
Stratégies de remplacement
Si un navigateur n'est pas compatible avec mask-image ou la version préfixée :
- Pour les images mises en forme : l'élément se dégradera de manière fluide et s'affichera sous la forme d'un élément rectangulaire normal avec ses styles de remplacement par défaut.
- Pour les cartes mises en forme : l'élément décoratif
.card-accentadjacent restera un rectangle plein et non masqué. Comme elle partage la même couleur d'arrière-plan que le conteneur de texte, l'ensemble de la carte s'affiche simplement sous la forme d'un conteneur rectangulaire standard et épuré. - Amélioration progressive : en conservant les calques de texte entièrement en dehors du masque, vous garantissez que votre contenu reste lisible, structuré et accessible sur les anciens navigateurs.