CSS masking gives you the option of using an image as a mask layer. This means that you can use an image, an SVG, or a gradient as your mask, to create interesting effects without an image editor.
When you clip an element using the clip-path
property the clipped area becomes invisible.
If instead you want to make part of the image opaque or apply some other effect to it, then you need to use masking.
This post explains how to use the mask-image
property in CSS,
which lets you specify an image to use as a mask layer.
This gives you three options. You can use an image file as your mask, an SVG, or a gradient.
Browser compatibility
While CSS masking is Baseline Newly available, most of the features of mask-image
are available in earlier browser versions using the prefixed -webkit-mask-image
.
The following examples show how to use both properties together for the best
browser support.
Mask with an image
The mask-image
property works in a similar way to the background-image
property.
Use a url()
value to pass in an image.
Your mask image needs to have a transparent or semi-transparent area.
A fully transparent area will cause the part of the image under that area to be invisible. Using an area which is semi-transparent however will allow some of the original image to show through. You can see the difference in the following CodePen.
- The first image is the original image of balloons with no mask.
- The second image has a mask applied which has a white star on a fully transparent background.
- The third image has a white star on a background with a gradient transparency.
This example also uses the mask-size
property with a value of cover
.
This property works in the same way as background-size
.
Use the keywords cover
and contain
or give the background a size using any valid length unit, or a percentage.
You can also repeat your mask just as you might repeat a background image, in order to use a small image as a repeating pattern.
Mask with SVG
Rather than using an image file as the mask, you could use SVG.
There are a couple of ways this can be achieved.
The first is to have a <mask>
element inside the SVG and reference the ID of that element in the mask-image
property.
.container img {
-webkit-mask-image: url(#mask);
mask-image: url(#mask);
}
The advantage of this approach is that the mask could be applied to any HTML element, not just an image.
For the most common scenario of masking an image,
you can instead include the image in the SVG.
The first approach is Baseline Newly available, including the image in the SVG
is supported by the older browsers that support the -webkit
prefixed version.
Mask with a gradient
Using a CSS gradient as your mask is an elegant way of achieving a masked area without needing to go to the trouble of creating an image or SVG.
A linear gradient used as a mask can ensure that the bottom part of an image is not too dark underneath a caption, for example.
You can use any of the supported gradient types, and get as creative as you like. This next example uses a radial gradient to create a circular mask to illuminate behind the caption.
Multiple masks
As with background images you can specify multiple mask sources, combining them to get the effect that you want. This is particularly useful if you want to use a pattern generated with CSS gradients as your mask. These typically will use multiple background images and so can be translated easily into a mask.
As an example, there's a checkerboard pattern in this patterns with CSS gradients. The code, using background images, looks like this:
background-image:
linear-gradient(45deg, #ccc 25%, transparent 25%),
linear-gradient(-45deg, #ccc 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #ccc 75%),
linear-gradient(-45deg, transparent 75%, #ccc 75%);
background-size:20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
To turn this, or any other pattern designed for background images, into a mask,
you will need to replace the background-*
properties with the relevant mask
properties,
including the -webkit
prefixed ones.
-webkit-mask-image:
linear-gradient(45deg, #000000 25%, rgba(0,0,0,0.2) 25%),
linear-gradient(-45deg, #000000 25%, rgba(0,0,0,0.2) 25%),
linear-gradient(45deg, rgba(0,0,0,0.2) 75%, #000000 75%),
linear-gradient(-45deg, rgba(0,0,0,0.2) 75%, #000000 75%);
-webkit-mask-size:20px 20px;
-webkit-mask-position: 0 0, 0 10px, 10px -10px, -10px 0px;
There are some really nice effects to be made by applying gradient patterns to images. Test some other variations by forking the following CodePen.
Along with clipping, CSS masks are a way to add interest to images and other HTML elements without needing to use a graphics application.