Ritagli sagomati

Funzionalità web: Maschere

Panoramica

Le maschere CSS ti consentono di ritagliare un elemento in una forma personalizzata, ad esempio aggiungendo un notch a una scheda o creando un bordo sagomato. Quando combini le forme per layout complessi, scegli la strategia di mascheramento in base al tipo di contenuti dell'elemento:

Strategia di mascheramento I migliori per Impatto del testo
Mascheramento SVG diretto degli elementi Immagini, icone, forme decorative, forme complesse Non consigliato (può ritagliare il testo)
Mascheramento SVG di elementi adiacenti Schede con testo, contenuti cruciali Il testo rimane completamente leggibile
Pure CSS Gradients Forme geometriche semplici Non consigliato (può ritagliare il testo)

Implementazione

Per implementare i ritagli sagomati:

Utilizzo di una maschera SVG

Le maschere SVG ti consentono di definire forme che sottraggono o aggiungono all'area visibile utilizzando riempimenti bianchi (mostra) e neri (nascondi).

Mascheramento di luminanza e alfa: le maschere SVG sono impostate per impostazione predefinita sulla modalità luminanza (luminosità), motivo per cui utilizziamo fill="white" per mostrare le aree e fill="black" per ritagliarle. Se preferisci utilizzare la trasparenza dell'SVG (canale alfa) anziché i colori, puoi impostare mask-type: alpha; nel CSS o mask-type="alpha" nell'elemento SVG <mask>.

Mascheramento SVG diretto degli elementi

Quando non devi preoccuparti del testo all'interno dell'elemento (ad esempio avatar del profilo, immagini dei prodotti o illustrazioni), puoi applicare la maschera SVG direttamente all'elemento.

L'utilizzo di maskContentUnits="objectBoundingBox" all'interno della maschera SVG garantisce che la maschera venga ridimensionata automaticamente in base alla larghezza e all'altezza di qualsiasi elemento a cui viene applicata.

<!-- 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>

Mascheramento SVG di elementi adiacenti

Applica la maschera a un elemento adiacente anziché all'elemento principale contenente il testo. In questo modo, il testo non viene tagliato e rimane leggibile.

Per risolvere il problema, struttura il componente in un layout in due parti:

  1. Un contenitore di testo sicuro e non mascherato (.card-body) per tutti i contenuti leggibili.
  2. Un div decorativo vuoto (.card-accent) posizionato accanto, che riceve la maschera SVG personalizzata.

Assegnando a entrambe le parti lo stesso colore di sfondo, queste si fondono visivamente in un unico componente dalla forma personalizzata.

<!-- 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>

Utilizzo di un singolo gradiente CSS per ritagli semplici

Quando hai bisogno solo di semplici ritagli geometrici (come un notch superiore semicircolare, rientranze laterali o tagli diagonali dritti), non è necessario scrivere o fare riferimento a un SVG esterno. Puoi invece definire una sfumatura radiale o lineare CSS direttamente all'interno della proprietà 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>

Strategie di riserva

Se un browser non supporta mask-image o la versione con prefisso:

  • Per le immagini sagomate: l'elemento verrà ridotto in modo controllato e verrà visualizzato come un normale elemento rettangolare con gli stili di riserva predefiniti.
  • Per le Shaped Card: l'elemento decorativo .card-accent adiacente rimarrà un rettangolo solido e non mascherato. Poiché condivide lo stesso colore di sfondo del contenitore di testo, l'intera scheda verrà visualizzata semplicemente come un contenitore rettangolare standard e pulito.
  • Potenziamento progressivo: mantenendo i livelli di testo completamente al di fuori della maschera, i tuoi contenuti rimarranno completamente leggibili, strutturati e accessibili sui browser meno recenti.