Masking is a technique that lets you display selected portions of an element or an image on the screen while hiding the rest. Web developers can use this technique in the browser via the mask property and the SVG mask element. These features allow you to display masking effects on images and other elements in the browser without using any kind of image editing software.
In this article, I’m going to show CSS and SVG masking capabilities in action, also making sure to include some info about current browser support issues.
At the time of writing, most code samples work only in WebKit browsers while SVG-based masks seem to enjoy wider browser support. Therefore, if you’d like to try out the examples, I recommend you use a WebKit browser like Chrome.
You can achieve masking effects on the web using clipping or masking.
Clipping involves laying a closed vector shape, like a circle or a polygon, on top of an image or an element. Any parts of the image behind the shape will be visible, while any parts outside the boundaries of the shape will be hidden. The shape’s boundary is called the clip path, and you create it using the clip-path property.
Masking is done using a PNG image, CSS gradient, or an SVG element to hide some parts of an image or other element on the page. You can accomplish this using the CSS mask property.
In this article, I will focus exclusively on masking with the CSS mask property and the SVG
mask is the CSS shorthand property for a whole bunch of individual properties. Let’s take a closer look at some of them in more detail.
You can use the mask-image property to set the mask layer image of an element.
The value none is not the same as setting no value at all. On the contrary — it still counts as a transparent black image layer.
You can set mask-image to a URL value. This can be the path to a PNG image file, an SVG file, or a reference to an SVG
Here are a few examples:
/* masking with two comma-separated values */ .masked-element { mask-image: url(mask.png), none; } /* using external svg graphic as mask */ .masked-element { mask-image: url(mask.svg); }
This is how you reference an SVG
.masked-element { mask-image: url(#mask1); }
A gradient image is also a suitable value for the mask-image property:
.masked-element { mask-image: linear-gradient(black 0%, transparent 100%); }
With mask-mode you can set the mask layer image to be either an alpha mask or a luminance mask.
An alpha mask is an image with an alpha channel. In more detail, the alpha channel is the transparency information contained in each pixel’s data. Masking operations with the mask-mode property set to alpha will use the image’s alpha values as the mask values.
A handy example of an alpha channel is a PNG image with black and transparent areas. The masked element will show through the black portions of the mask image, which have an alpha value of one. Everything else beneath the transparent portions, which have an alpha value of zero, will be hidden.
I’m going to use this PNG image as my alpha mask:
and perform a masking operation on the JPG image below:
This is where the magic happens:
.masked-element { mask-image: url(alpha-mask.png); mask-mode: alpha; }
and here’s what the result looks like in the browser:
A luminance mask uses an image’s luminance values as mask values. A PNG image like the one above — but in white — is a good example of a luminance mask:
The areas of the element you want to mask, which are covered by the mask’s white pixels, will show through. The portions of the masked element covered by the mask’s transparent pixels will be hidden.
Setting the mask-mode property to luminance and using the image above as my mask, will display the same result as before.
Here’s the code:
.masked-element { mask-image: url(luminance-mask.png); mask-mode: luminance; }
mask-repeat works pretty much like the background-repeat property. It controls the tiling of mask layer images after you’ve set their size and position.
Possible values are:
For instance, this is the image I intend to use as my mask:
The code snippet below sets the mask-repeat property to a value of space:
/* masking with two comma-separated values */ .masked-element { mask-image: url(mask.png), none; } /* using external svg graphic as mask */ .masked-element { mask-image: url(mask.svg); }
resulting in the following masking effect:
You can position a mask layer image using the mask-position property. You can set this property to the same values you would use for the more familiar CSS background-image property. Its initial value is center.
For instance, if you want to place the mask image layer on the top left corner of the viewport, set the mask-position property to a value of 0 0:
.masked-element { mask-image: url(#mask1); }
This is what the code above looks like in the browser:
Changing the value of the mask-position property above to 100% 100%, displays the mask layer image on the bottom right of the viewport:
You can quickly set the size of your mask layer image using the mask-size property, which accepts the same values as the more familiar CSS background-size property.
For example, setting mask-size to 50% displays the mask layer image at 50% of its full width:
Setting mask-size to contain will scale the mask layer image to the largest size so that both its width and height can fit inside the mask positioning area:
You can see these demos live in action on CodePen below:
See the Pen CSS Mask Examples by SitePoint (@SitePoint) on CodePen.
As explained above, you can use more than one mask layer on the same element by separating each value of the mask-image property with a comma. The layers get stacked one on top of the others with the last layer displaying first on the screen.
For instance:
/* masking with two comma-separated values */ .masked-element { mask-image: url(mask.png), none; } /* using external svg graphic as mask */ .masked-element { mask-image: url(mask.svg); }
In the snippet above, mask2.png is layered on top of mask1.png.
The mask-composite property lets you combine different mask layers according to the value of the following keywords:
You can check out the live demos in the CodePen demo below too:
See the Pen CSS Mask Compositing by SitePoint (@SitePoint) on CodePen.
You can set all the properties that control CSS masking operations in one go using mask.
Here’s the full mask shorthand:
.masked-element { mask-image: url(#mask1); }
mask-origin and mask-clip work like the more familiar background-origin and background-clip properties.
Although you can reorder the properties in the mask shorthand, you need to set the mask-size property after the mask-position property, separated by the “/” symbol. Also, setting mask-size without setting mask-position will result in an invalid declaration.
Finally, since any value you fail to specify on the mask property is set back to its initial default value, using mask comes really handy when you need to reset any of the individual properties.
Scalable Vector Graphics, or SVG for short, is an XML-based language to mark up graphics.
You can use a
One more cool thing you can do with SVG is masking other elements on the page using text.
Let’s look closer into each of these possibilities.
At the time of writing, using the
.masked-element { mask-image: linear-gradient(black 0%, transparent 100%); }
With the following CSS:
/* masking with two comma-separated values */ .masked-element { mask-image: url(mask.png), none; } /* using external svg graphic as mask */ .masked-element { mask-image: url(mask.svg); }
In the code above, I’ve included a
Finally, I’ve referenced the SVG
Just by adding a few other style declarations for the page background and the masked image, you can achieve a pretty dramatic effect like the one below:
Notice how the portion of the circle mask filled with the white shade of the gradient lets the masked image show through. Conversely, the portion filled with the black hue of the gradient hides the masked image.
Here’s a live demo of this on CodePen (remember, it will only work on Firefox!).
See the Pen Masking with an Inline SVG mask Element by SitePoint (@SitePoint) on CodePen.
You can use the same SVG
In the snippet below, I’m going to place the image I want to mask inside an SVG element and apply the CSS mask property to it. The CSS mask property references the SVG
.masked-element { mask-image: url(#mask1); }
And this is the snippet that takes care of the masking operation in CSS:
.masked-element { mask-image: linear-gradient(black 0%, transparent 100%); }
The result is pretty much similar to the previous example, only this time you can view it on all major browsers.
Have a look at the CodePen demo:
See the Pen SVG Mask on an SVG Element by SitePoint (@SitePoint) on CodePen.
You can perform masking operations using a text element inside your SVG mask:
.masked-element { mask-image: url(alpha-mask.png); mask-mode: alpha; }
.masked-element { mask-image: url(luminance-mask.png); mask-mode: luminance; }
The snippet above adds a black SVG text element inside the SVG mask and applies it to a light blue SVG ellipse shape using the CSS mask property. Whatever lies behind the ellipse shape (in this case it’s the body‘s background image) will show through the text. The result looks something like this:
The full code is available on CodePen:
See the Pen SVG Text Mask by SitePoint (@SitePoint) on CodePen.
You can animate mask-position and mask-size using CSS transition and keyframe animation.
Below is a basic keyframe animation example of a star-shaped PNG mask image.
Here are the relevant code snippets:
The masked element is a HTML tag:
/* masking with two comma-separated values */ .masked-element { mask-image: url(mask.png), none; } /* using external svg graphic as mask */ .masked-element { mask-image: url(mask.svg); }
The masking operation uses the shorthand mask property:
.masked-element { mask-image: url(#mask1); }
The .animate class on the element adds movement to the star-shaped image using CSS transform and animation:
.masked-element { mask-image: linear-gradient(black 0%, transparent 100%); }
Launch a WebKit browser like Chrome and check out the following live demo on CodePen:
See the Pen Animating with CSS Mask by Maria Antonietta Perna (@antonietta) on CodePen.
You can add masking effects on an tag using the SVG
Here’s a quick CodePen demo: the animation is visible on any browser, however the masking is only rendered in Firefox:
See the Pen Animate SVG Mask on HTML Element by SitePoint (@SitePoint) on CodePen.
The good news is that, if you apply your SVG mask on an inline SVG graphic, browser support immediately sky-rockets. Check out the same animation demo using only SVG:
See the Pen Animating SVG mask on SVG Element by SitePoint (@SitePoint) on CodePen.
I’ve touched on browser support issues throughout this article. A simple breakdown of the situation at the time of writing looks like this:
This great CodePen demo by Yoksel offers a visual illustration of the state of the art as far as browser support goes.
Alan Greenblatt makes available a GitHub repository where he goes into the details of which CSS graphics-related property is supported by which browser.
The browser support compatibility table on the Can I Use website offers further details and links to more resources.
Although current browser support for CSS mask is not great, if you use this feature as an enhancement on a few decorative elements, users of non-supporting browser won’t even notice they’re missing out.
Finally, applying masking effects on an SVG graphic with the SVG
Do you know of a cool masking effect on the web you’d like to share? Hit the comments box and let me know.
CSS and SVG masking both allow you to hide or reveal portions of an element. However, they differ in their approach and capabilities. CSS masking uses an image as a mask layer where the alpha channel of the mask image determines the visibility of the element. On the other hand, SVG masking uses a vector graphic as a mask layer, which provides more flexibility and control over the shape and size of the mask. SVG masking also supports color and gradient masks, which are not possible with CSS masking.
SVG masking allows you to create gradient masks, which can add a unique visual effect to your web elements. To create a gradient mask with SVG, you need to define a linearGradient or radialGradient element inside the mask element. The gradient element should have at least two stop elements that define the color and opacity at different points along the gradient.
Yes, you can use CSS and SVG masking together to create complex masking effects. You can apply a CSS mask to an element and then apply an SVG mask to the same element. The final visibility of the element is determined by the combination of the two masks.
CSS masking is not supported in Internet Explorer. If you need to support Internet Explorer, you should use SVG masking instead. SVG masking is supported in all major browsers, including Internet Explorer.
Both CSS and SVG masking support animation. For CSS masking, you can animate the mask-image property using CSS animations or transitions. For SVG masking, you can animate the mask element using SVG animations.
Yes, you can use a text as a mask with both CSS and SVG. For CSS masking, you can use a text image as the mask image. For SVG masking, you can use a text element as the mask element.
To create a circular mask with CSS, you can use a radial-gradient function as the mask image. To create a circular mask with SVG, you can use a circle element as the mask element.
To create a complex mask with multiple shapes, you can use SVG masking. SVG masking allows you to use multiple shape elements (like rect, circle, polygon, etc.) as the mask element. You can position and size these shapes independently to create a complex mask.
CSS masking supports video masks. You can use a video as the mask image by setting the mask-image property to a video URL. SVG masking does not support video masks.
For CSS masking, the opacity of the mask is determined by the alpha channel of the mask image. You can adjust the opacity by editing the mask image. For SVG masking, the opacity of the mask is determined by the fill-opacity and stroke-opacity properties of the mask element. You can adjust the opacity by changing these properties.
The above is the detailed content of Masking in the Browser with CSS and SVG. For more information, please follow other related articles on the PHP Chinese website!