mask-image
Baseline 2023Newly available
Since December 2023, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
The mask-image
CSS property sets the image that is used as the mask layer for an element, hiding sections of the element on which the masking image is set based on the alpha channel of the mask image and, depending on the mask-mode
property value, the luminance of the mask image's colors.
Syntax
/* Keyword value */
mask-image: none;
/* <mask-source> value */
mask-image: url(masks.svg#mask1);
/* <image> values */
mask-image: linear-gradient(rgb(0 0 0 / 100%), transparent);
mask-image: image(url(mask.png), skyblue);
/* Multiple values */
mask-image: url(mask.png), linear-gradient(black 25%, transparent 35%);
/* Global values */
mask-image: inherit;
mask-image: initial;
mask-image: revert;
mask-image: revert-layer;
mask-image: unset;
Values
none
-
This keyword is interpreted as a transparent black image layer.
<mask-source>
<image>
-
An image value used as a mask image layer.
Description
The mask-image
property provides a mask that hides part of the element to which it is applied. The value is a comma-separated list of mask references. Each mask reference is an <image>
, a <mask-source>
, or the keyword none
.
An <image>
can be any type of image, including generated images such as CSS gradients.
If only one value is specified in the mask-image
property value, and that value is none
, no masking effect will be apparent. If multiple values are specified, a none
value included in the list may have no direct effect, however, other mask-*
values in the same list position will apply to a transparent black mask layer and have no visual effect.
Only image sources served over HTTP and HTTPS protocols are accepted as <image>
values due to the CORS policy. Images served locally, including relative or absolute file://
protocols, are not accepted, and will render as transparent black. To test URL image sources locally, set up a local server.
A mask will be counted as a transparent black image layer, not revealing anything, in the following cases:
- The mask image is empty (zero width or zero height).
- The mask image fails to download.
- The browser does not support the mask image format.
- The mask image doesn't exist.
- The mask value doesn't point to a mask image.
The default value of the mask-mode
property is match-source
, which means the mode is defined by the mode of the mask image itself. The mask image's mode is generally alpha
except when the mask source is an SVG <mask>
element, in which case the mode is luminance
unless the mode is changed to alpha
via the CSS mask-type
property or SVG mask-type
attribute.
The mask-mode
value is significant, because it determines whether the masking effect depends on the image source's alpha channel values alone or a combination of those and the mask's luminance (the lightness/darkness of the colors that make up the mask-image
):
- In all cases, the alpha transparency of the mask matters; element areas masked by opaque sections of the
mask-image
will be rendered, while areas masked by transparent image sections are hidden. - When the
mask-mode
value is set or resolves toalpha
, only the alpha-channel of the colors matter; the hue, lightness, etc., don't matter. - If the
mask-mode
property is set or defaults toluminance
, the masking value is the luminance value of each color multiplied by its alpha value. Themask-mode
will resolve toluminance
if explicitly set to that value, or if the property is set tomatch-source
and themask-image
source is an SVG<mask>
that does not have itsmask-type
property ormask-type
attribute explicitly set toalpha
.
Formal definition
Initial value | none |
---|---|
Applies to | all elements; In SVG, it applies to container elements excluding the <defs> element and all graphics elements |
Inherited | no |
Computed value | as specified, but with <url> values made absolute |
Animation type | discrete |
Formal syntax
mask-image =
<mask-reference>#
<mask-reference> =
none |
<image> |
<mask-source>
<image> =
<url> |
<gradient>
<mask-source> =
<url>
<url> =
<url()> |
<src()>
<url()> =
url( <string> <url-modifier>* ) |
<url-token>
<src()> =
src( <string> <url-modifier>* )
Examples
Gradient as a mask image
In this example, we use an <image>
value as a mask, defining a CSS radial gradient as our mask image to create a round image with a soft edge.
HTML
We include an HTML <img>
element, which will also be used in all other examples.
<img
src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
alt="Pride flag" />
CSS
We use the CSS radial-gradient()
function to create a mask that has a black circle with a radius that is half the width of the mask, before transitioning to being transparent over 10%.
img {
mask-image: radial-gradient(black 50%, transparent 60%);
}
Results
The part of the original element that is masked by the black circle is fully opaque, fading to transparent as the mask fades to transparent.
Image resource as a mask image
In this example, the <mask-source>
used as our mask image is an external SVG.
HTML
We include the same image as the previous example. We've also included the image we will be using as the mask; a star whose fill-opacity
is 0.5
, or 50% opaque.
<img
src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
alt="Pride flag" />
<img
src="https://mdn.github.io/shared-assets/images/examples/mask-star.svg"
alt="A star" />
CSS
We use mask-star.svg
as a mask image on our first image:
img:first-of-type {
mask-image: url(https://mdn.github.io/shared-assets/images/examples/mask-star.svg);
}
Results
The mask is semi-opaque, which is why the colors are not as vibrant as the previous example. The part of the image that is visible is 50% opaque; the opacity of the mask applied.
The mask is smaller than the image, so repeats by default. We could have used mask-repeat
to control the repeating or mask-size
to change the size of the mask, which we do in the next example.
Multiple masks
This example demonstrates applying multiple masks.
CSS
We apply two masks — the same semi-transparent SVG as in the previous example, and a repeating-radial-gradient()
. We control the size of the masks using the mask-size
property. Because our first mask is not sized at 100%, we make sure our masks are centered and don't repeat with the mask-position
and mask-repeat
properties, respectively.
img {
mask-size: 95%, 100%;
mask-position: center;
mask-repeat: no-repeat;
mask-image:
url(https://mdn.github.io/shared-assets/images/examples/mask-star.svg),
repeating-radial-gradient(transparent 0 5px, black 5px 10px);
}
Results
Masking with SVG <mask>
This example demonstrates using SVG <mask>
elements as masks. In this case, the color of the mask matters as the mask-type
value for SVG masks defaults to luminance
, which means white opaque areas (100% luminance) will be masked and visible, transparent and black areas (0% luminance) will be clipped, and anything in between will be partially masked.
HTML
We've included an id
for each of our four images, and an SVG that contains an equal number of <mask>
elements.
<img
id="green"
src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
alt="Pride flag" />
<img
id="stroke"
src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
alt="Pride flag" />
<img
id="both"
src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
alt="Pride flag" />
<img
id="alphaMode"
src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
alt="Pride flag" />
<svg height="0" width="0">
<mask id="greenMask">
<path
d="M20,70 A40,40,0,0,1,100,70 A40,40,0,0,1,180,70 Q180,130,100,190 Q20,130,20,70 Z"
fill="green" />
</mask>
<mask id="strokeMask">
<path
d="M20,70 A40,40,0,0,1,100,70 A40,40,0,0,1,180,70 Q180,130,100,190 Q20,130,20,70 Z"
fill="none"
stroke="white"
stroke-width="20" />
</mask>
<mask id="bothMask">
<path
d="M20,70 A40,40,0,0,1,100,70 A40,40,0,0,1,180,70 Q180,130,100,190 Q20,130,20,70 Z"
fill="green"
stroke="white"
stroke-width="20" />
</mask>
<mask id="black">
<path
d="M20,70 A40,40,0,0,1,100,70 A40,40,0,0,1,180,70 Q180,130,100,190 Q20,130,20,70 Z"
fill="black" />
</mask>
</svg>
CSS
We apply a different <mask>
to each <img>
. No part of the last image, with the black
fill, will be visible by default. In this case, while all colors used in this example are fully opaque, the mask-mode
defaults to match-type
, which resolves to luminance
in this case.
#green {
mask-image: url(#greenMask);
}
#stroke {
mask-image: url(#strokeMask);
}
#both {
mask-image: url(#bothMask);
}
#alphaMode {
mask-image: url(#black);
}
body:has(:checked) img {
mask-mode: alpha;
}
The luminance values of black
, white
, and green
are 0
, 100
, and 46.228
, respectively. This means the areas where the mask is white will be visible, whereas areas where the mask is black or fully transparent will be clipped (not visible). Areas where the mask is green will be visible but lighter, equivalent to having a white mask that is 46.228% opaque.
Results
Toggle the checkbox to toggle the value of the mask-mode
between alpha
(checked) and the initial value, which resolves to luminance
(unchecked). When alpha
is used, the color of the mask doesn't matter; all that matters is the alpha-transparency. When the value resolves to luminance
, white
areas are visible, black
areas are not, and green
areas are visible but at an opacity that matches the luminance of the color green
. When mask-mode
is set to alpha
, the colors are equivalent as they are all fully opaque.
Specifications
Specification |
---|
CSS Masking Module Level 1 # the-mask-image |
Browser compatibility
See also
mask
shorthandmask-origin
mask-position
mask-repeat
mask-size
mask-border
clip-path
- CSS masking module