Il CSS Masking Module 1 introduce le proprietà mask e clip-path, che indicano come di applicare agli elementi di una pagina HTML gli stessi effetti grafici ottenibili in SVG grazie agli elementi <mask>
e <clipPath>
.
La specifica prevede che le due proprietà accettino come valore un riferimento ad un elemento SVG, individuato dal suo ID, come nella seguente dichiarazione:
.img1 { clip-path: url(#svgPath); }
Della proprietà clip-path
abbiamo parlato diffusamente in un precedente articolo. In questo capitolo, quindi, focalizzeremo l'attenzione sulle maschere.
Le maschere SVG
Se la proprietà clip-path
rende visibile un elemento HTML attraverso un'area di ritaglio, mask
(e tutte le proprietà collegate) vi sovrappone un'immagine attraverso la quale traspare l'elemento sottostante. Le maschere si applicano grazie alle proprietà:
- mask-image
- mask-border-source
La prima, mask-image, accetta come valore un riferimento ad un elemento <mask>
, il cui contenuto genera l'immagine sovrapposta. mask-image
può anche puntare direttamente ad un'immagine, che in questo caso potrà essere posizionata e dimensionata grazie alle proprietà mask-position
e mask-size
.
Per la gestione dei bordi della maschera sono previste le proprietà mask-border e mask-border-source.
mask-mode
Va ancora sottolineato che esistono due tipi di maschere, di "luminosità" e di "trasparenza". Le modalità si attivano grazie alla proprietà mask-mode, la quale, quindi, potrà assumere i valori:
Valore | Descrizione |
---|---|
alpha | la visibilità dell'elemento sottostante dipende dal livello alpha di ogni punto dell'immagine che compone la maschera |
luminance | il browser converte la maschera in scala di grigio. Quanto più è chiaro il colore dei singoli punti maschera, tanto più sarà visibile l'elemento sottostante; |
auto | cambia il comportamento in base al tipo di file indicato nella proprietà mask-image (se di tipo mask-source applica una maschera di luminosità a partire dall'immagine, se invece è di tipo mask-reference applica una maschera di trasparenza. |
Infine, il draft fornisce con la proprietà mask
lo short-hand per tutte le proprietà connesse alle maschere.
Vediamo quindi cosa si può creare con le maschere.
Effetti di trasparenza
Sovrapponendo una maschera ad un qualsiasi elemento SVG, si possono creare effetti di trasparenza anche complessi utilizzando grafiche vettoriali come layer sovrapposti.
Analizziamo il seguente codice:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="600" height="300" viewBox="0 0 600 300"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="Gradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="600" y2="0">
<stop offset="0" stop-color="white" stop-opacity="0" />
<stop offset="1" stop-color="white" stop-opacity="1" />
</linearGradient>
<mask id="Mask" width="600" height="300" x="0" y="0" maskUnits="userSpaceOnUse">
<rect x="0" y="0" width="600" height="300" fill="url(#Gradient)" />
</mask>
<text id="Text" x="300" y="160" text-anchor="middle" font-size="96" font-weight="bold">CSS & SVG</text>
</defs>
<rect x="0" y="0" width="600" height="300" fill="#F80" />
<use xlink:href="#Text" fill="blue" />
<use xlink:href="#Text" fill="white" mask="url(#Mask)" />
<use xlink:href="#Text" fill="none" stroke="black" stroke-width="2" />
</svg>
La maschera viene generata dall'elemento SVG <mask>, e può contenere uno o più elementi grafici. In questo esempio, l'elemento grafico è un rettangolo, il cui riempimento viene generato da un linearGradient, cui ci si riferisce grazie all'attributo fill
.
Le diverse colorazioni del testo vengono generate da tre elementi use
, che puntano allo stesso elemento text#Text
. Il primo elemento genera un testo di colore blu, che viene utilizzato come colorazione di sfondo; il secondo testo, bianco, viene sfumato da trasparente a opaco con un riferimento all'elemento mask#Mask
. Infine l'ultimo elemento use genera un testo di sfondo trasparente e con bordo nero.
Nell'esempio appena visto abbiamo applicato la maschera ad un elemento SVG. Grazie alle proprietà rese disponibili dal CSS Masking Module 1 http://dev.w3.org/fxtf/css-masking-1/ gli stessi effetti possono essere applicati ad elementi HTML.
Maschere SVG su elementi HTML
Basandoci sull'esempio del già citato articolo sulla proprietà clip-path
, vediamo come applicare su un elemento HTML sia un'area di ritaglio che una maschera. Definiamo, quindi, un percorso con clipPath
, una sfumatura da trasparente a opaco con linearGradient
ed una maschera rettangolare, con mask
e rect
:
<svg width="0" height="0">
<defs>
<clipPath id="svgPath">
<path
d="M 328.57143,423.79076 214.92963,412.17017 140.9316,499.19769 116.86618,387.52695 11.231446,344.04362 110,286.6479 118.71218,172.7462 203.81992,248.94443 314.83908,222.03264 268.67,326.52146 z"
transform="translate(400,-170)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
</clipPath>
<linearGradient id="Gradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="800" y2="0">
<stop offset="0.40" stop-color="white" stop-opacity="0" />
<stop offset="0.90" stop-color="white" stop-opacity="1" />
</linearGradient>
<mask id="Mask" width="800" height="400" x="0" y="0" maskUnits="userSpaceOnUse">
<rect x="0" y="0" width="800" height="400" fill="url(#Gradient)" />
</mask>
</defs>
</svg>
Gli effetti saranno applicati ad un elemento img
:
<img class="img1" src="images/nisyros.jpg" />
Infine, le proprietà CSS3:
<style type="text/css">
.img1 {
-webkit-clip-path: url(#svgPath);
clip-path: url(#svgPath);
mask: url(#Mask);
}
</style>
Dai nostri test, solo Firefox interpreta correttamente il codice appena visto. Tuttavia, lo stesso Firefox non sembra supportare la proprietà mask-image
, per cui si è fatto ricorso allo shorthand mask
.
Webkit, invece, non permette di applicare maschere SVG ad elementi HTML, ma solo ad altri elementi SVG. Per ottenere su Webkit l'effetto maschera dell'esempio precedente, bisognerà, quindi, adottare la soluzione in puro SVG:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="800" height="400" viewBox="0 0 800 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="svgPath">
<path
d="M 328.57143,423.79076 214.92963,412.17017 140.9316,499.19769 116.86618,387.52695 11.231446,344.04362 110,286.6479 118.71218,172.7462 203.81992,248.94443 314.83908,222.03264 268.67,326.52146 z"
transform="translate(400,-170)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
</clipPath>
<linearGradient id="Gradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="800" y2="0">
<stop offset="0.40" stop-color="white" stop-opacity="0" />
<stop offset="0.90" stop-color="white" stop-opacity="1" />
</linearGradient>
<mask id="Mask" width="800" height="400" x="0" y="0" maskUnits="userSpaceOnUse">
<rect x="0" y="0" width="800" height="400" fill="url(#Gradient)" />
</mask>
</defs>
<image xlink:href="images/nisyros.jpg" width="800" height="400" mask="url(#Mask)" clip-path="url(#svgPath)"></image>
</svg>
Come si vede, l'elemento img
è stato sostituito dall'elemento SVG <image>
ed a questo sono stati assegnati gli attributi mask
e clip-path
, con i rispettivi riferimenti agli elementi <mask>
e <clipPath>
.
Conclusioni e riferimenti
Il supporto offerto dai browser è, quindi, parziale e disomogeneo. Mentre Firefox supporta solo i riferimenti inline (mask: url(#id)
), i browser Webkit supportano (parzialmente) solo le proprietà mask-image
e mask-box-image
. Nessun supporto da parte di Internet Explorer 11.
Per ogni approfondimento, si fa rinvio alle seguenti risorse: