Skip to main content




When you trim an item with 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 should use masking. This post explains how to use the mask-image in CSS, which allows you to specify an image to use as a mask layer. This gives you three options. You can use an image file as a skin, an SVG, or a gradient.

Browser compatibility

Most browsers only partially support the standard CSS masking property. You will need to use the -webkit- prefix in addition to the standard property for best browser compatibility. Watch Can I use CSS masks? for complete information on browser compatibility.

While browser support for the default property is good, when using masking to make text on top of an image visible, be aware of what will happen if masking is not available. It may be worth using function queries to detect compatibility with mask-image or -webkit-mask-image
and provide a readable backup before adding your masked version.

@supports(-webkit-mask-image: url(#mask)) or (mask-image: url(#mask)) {
}

Masking with an image

the mask-image The property works similar to the background-image property. Use a url () value to pass in an image. Your mask image should have a transparent or semi-transparent area.

A completely transparent area will make the part of the image below that area invisible. However, using a semi-transparent area will allow part of the original image to show through. You can see the difference in the Glitch below. The first image is the original image of balloons without mask. The second image has a mask applied with a white star on a completely transparent background. The third image has a white star on a background with a gradient transparency.

In this example I am also using the mask-size property with a value of cover. This property works in the same way as background-size. You can use the keywords cover and contain or you can size the background using any valid length unit or a percentage.

You can also repeat your mask in the same way that you could repeat a background image, to use a small image as a repeating pattern.

Masking with SVG

Instead of using an image file as a skin, you can use SVG. There are a couple of ways to accomplish this. The first is to have a element within the SVG and reference the ID of that element in the mask-image property.

<svg width="0" height="0" viewBox="0 0 400 300">
<defs>
<mask go="mask">
<rect fill="#000000" x="0" and="0" width="400" height="300"></rect>
<circle fill="#FFFFFF" cx="150" cy="150" r="100" />
<circle fill="#FFFFFF" cx="50" cy="50" r="150" />
</mask>
</defs>
</svg>

<div class="container">
<img src="balloons.jpg" alt="Balloons">
</div>

.container img {
height: 100%;
width: 100%;
object-fit: cover;
-webkit-mask-image: url(#mask);
mask-image: url(#mask);
}

svg-mask-3059015

The advantage of this approach is that the mask can be applied to any HTML element, not just an image. Unfortunately, Firefox is the only browser that supports this approach.

However, all is not lost, as for the most common scenario of masking an image, we can include the image in the SVG.

Masking with a gradient

Using a CSS gradient as a mask is an elegant way to achieve a masked area without having to go to the trouble of creating an image or SVG.

A simple linear gradient used as a mask could ensure that the bottom of an image isn't too dark under a title, for example.

You can use any of the supported gradient types and be as creative as you like. The following example uses a radial gradient to create a circular mask to illuminate behind the title.

Using multiple skins

As with background images, you can specify multiple mask fonts, combining them to get the effect you want. This is particularly useful if you want to use a pattern generated with CSS gradients as a mask. These will typically use multiple background images and can therefore easily be translated into a mask.

As an example, I found a nice checkerboard pattern in This article. 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 -webkit the default 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 applying gradient patterns to images. Try remixing the Glitch and try some other variations.

Along with clipping, CSS masks are a way to add interest to images and other HTML elements without using a graphics application.

Photo by Julio Rionaldo on Unsplash.