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.


![Rachel Andrew](https://web.dev/images/authors/rachelandrew.jpg) Rachel Andrew Technical Writer [GitHub](https://github.com/rachelandrew) [LinkedIn](https://www.linkedin.com/in/rachelandrew) [Mastodon](https://front-end.social/@rachelandrew) [Bluesky](https://bsky.app/profile/rachelandrew.bsky.social) [Homepage](https://rachelandrew.co.uk)

<br />

When you [clip an element](https://web.dev/articles/css-clipping) 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`](https://developer.mozilla.org/docs/Web/CSS/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

<iframe src="https:///frame/articles/css-masking/index_f49c655e398f0a6b4209c0f989d815e620075cc07f1f2642a4e830885f839c24.frame" class="framebox inherit-locale " allow="clipboard-write https://" allowfullscreen is-upgraded></iframe>

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.

<iframe height="459" style="width: 100%;" scrolling="no" title="Untitled" src="https://codepen.io/web-dot-dev/embed/YPKGzWQ?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/pen/YPKGzWQ"&amp;amp;gt; Image masking&amp;amp;lt;/a&amp;amp;gt; by web.dev (&amp;amp;lt;a href="https://codepen.io/web-dot-dev"&amp;amp;gt;@web-dot-dev&amp;amp;lt;/a&amp;amp;gt;) on &amp;amp;lt;a href="https://codepen.io"&amp;amp;gt;CodePen&amp;amp;lt;/a&amp;amp;gt;. </iframe>

This example also uses the `mask-size` property with a value of `cover`.
This property works in the same way as [`background-size`](https://developer.mozilla.org/docs/Web/CSS/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);
    }

<iframe height="387" style="width: 100%;" scrolling="no" title="CSS mask using SVG" src="https://codepen.io/web-dot-dev/embed/YPKGPPj?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/pen/YPKGPPj"&amp;amp;gt; CSS mask using SVG&amp;amp;lt;/a&amp;amp;gt; by web.dev (&amp;amp;lt;a href="https://codepen.io/web-dot-dev"&amp;amp;gt;@web-dot-dev&amp;amp;lt;/a&amp;amp;gt;) on &amp;amp;lt;a href="https://codepen.io"&amp;amp;gt;CodePen&amp;amp;lt;/a&amp;amp;gt;. </iframe>

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.
<iframe height="391" style="width: 100%;" scrolling="no" title="Mask with image included in SVG" src="https://codepen.io/web-dot-dev/embed/raBMaLm?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/pen/raBMaLm"&amp;amp;gt; Mask with image included in SVG&amp;amp;lt;/a&amp;amp;gt; by web.dev (&amp;amp;lt;a href="https://codepen.io/web-dot-dev"&amp;amp;gt;@web-dot-dev&amp;amp;lt;/a&amp;amp;gt;) on &amp;amp;lt;a href="https://codepen.io"&amp;amp;gt;CodePen&amp;amp;lt;/a&amp;amp;gt;. </iframe>

## 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.
<iframe height="414" style="width: 100%;" scrolling="no" title="Gradient mask" src="https://codepen.io/web-dot-dev/embed/RNbGNGE?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/pen/RNbGNGE"&amp;amp;gt; Gradient mask&amp;amp;lt;/a&amp;amp;gt; by web.dev (&amp;amp;lt;a href="https://codepen.io/web-dot-dev"&amp;amp;gt;@web-dot-dev&amp;amp;lt;/a&amp;amp;gt;) on &amp;amp;lt;a href="https://codepen.io"&amp;amp;gt;CodePen&amp;amp;lt;/a&amp;amp;gt;. </iframe>

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.
<iframe height="397" style="width: 100%;" scrolling="no" title="Radial gradient mask" src="https://codepen.io/web-dot-dev/embed/bNbwNod?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/pen/bNbwNod"&amp;amp;gt; Radial gradient mask&amp;amp;lt;/a&amp;amp;gt; by web.dev (&amp;amp;lt;a href="https://codepen.io/web-dot-dev"&amp;amp;gt;@web-dot-dev&amp;amp;lt;/a&amp;amp;gt;) on &amp;amp;lt;a href="https://codepen.io"&amp;amp;gt;CodePen&amp;amp;lt;/a&amp;amp;gt;. </iframe>

## 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](https://cssgradient.io/blog/gradient-patterns/).
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.
<iframe height="400" style="width: 100%;" scrolling="no" title="Checkerboard mask" src="https://codepen.io/web-dot-dev/embed/QwLKwON?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/pen/QwLKwON"&amp;amp;gt; Checkerboard mask&amp;amp;lt;/a&amp;amp;gt; by web.dev (&amp;amp;lt;a href="https://codepen.io/web-dot-dev"&amp;amp;gt;@web-dot-dev&amp;amp;lt;/a&amp;amp;gt;) on &amp;amp;lt;a href="https://codepen.io"&amp;amp;gt;CodePen&amp;amp;lt;/a&amp;amp;gt;. </iframe>

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