When you look at a picture or design on a website, sometimes you only want part of it to be visible. Think of it like cutting shapes out of paper: if you place a heart-shaped piece of paper over a photo, you’ll only see the parts of the photo inside the heart.
That’s exactly what CSS masks do. They let you hide some parts of an element and reveal others. Instead of showing the full box or image, you can control which parts are visible.
This is different from clip-path, which just cuts out shapes with hard edges. Masks are more powerful because they can use transparency and gradients, which means you can create soft fades, smooth blends, and very creative shapes.
How Do Masks Work in CSS?
In CSS, masking works by applying a mask image or shape to an element. The mask acts as a filter that decides which parts of the element are visible and which are hidden.
The core logic involves the following:
- Visible parts → where the mask is opaque (solid areas).
- Hidden parts → where the mask is transparent.
- Partially visible → where the mask has semi-transparency (useful for fades and gradients).
This visibility is controlled using the alpha channel (transparency in images) or the luminance (brightness) values, depending on the mask-mode.
Key CSS Mask Properties
Masks in CSS are controlled by a group of properties that all work together. If you want to get the most out of masking, it’s important to understand each one clearly. Let’s go step by step.
1. mask-image
The mask-image property is the heart of CSS masking. It tells the browser what to use as the mask. This can be:
- A URL pointing to an image (PNG or SVG are common).
- A CSS gradient.
- A reference to an inline SVG
<mask>usingurl(#id).
.element {
mask-image: url("mask-shape.png"); /* external image */
}
.element {
mask-image: linear-gradient(black, transparent); /* gradient fade */
}
.element {
mask-image: url(#mask1); /* referencing an SVG mask defined inline */
}
If the value is none (the default), no mask is applied. You can also apply more than one mask at the same time. This works just like multiple backgrounds: you separate each mask with a comma, and each one becomes a layer. The browser then combines them in order.
.element {
mask-image:
url("circle.png"),
linear-gradient(black, transparent);
}
In this example, the first mask layer is a circle image (circle.png) and the second mask layer is a gradient fade.
The final visible area is the result of combining both layers. Imagine stacking two stencils: the element only shows through where both masks allow it. This is where mask-composite (explained later) becomes important, because it defines how those layers mix together (add, subtract, intersect, etc.).
2. mask-mode
Once you’ve set a mask-image, the browser needs to know how to interpret it. That’s where mask-mode comes in.
There are two main modes:
alpha → uses transparency (alpha channel). Black or solid = visible, transparent = hidden.
luminance → uses brightness (light vs dark). White = visible, black = hidden.
match-source (default) → automatically chooses based on the source.
.element {
mask-image: url("mask-luminance.png");
mask-mode: luminance;
}
Use alpha for PNGs or gradients with transparent areas, and luminance if you’re working with masks where brightness should control visibility.
3. mask-repeat
By default, masks tile (repeat) if they’re smaller than the element — just like backgrounds do. You can control this with mask-repeat.
.element {
mask-image: url("pattern.png");
mask-repeat: repeat-x; /* repeats horizontally */
}
Values include:
- repeat (default)
- no-repeat
- repeat-x / repeat-y
- space (repeats with spacing in between)
- round (scales the mask so it fits an exact number of times)
In most design cases, you’ll want no-repeat for single masks, unless you’re intentionally creating a repeated pattern.
4. mask-position and mask-size
These two properties define where the mask sits and how big it is.
mask-position: aligns the mask (e.g.,
left, center, 20px 30px).mask-size: scales the mask (
cover, contain, or fixed dimensions).
mask-image: url("circle.png");
mask-position: center;
mask-size: 120px 120px;
mask-repeat: no-repeat;
}
In this example, the mask is centered on the element and fixed to 120px × 120px.
Together, mask-position and mask-size are essential when working with image masks.
5. mask-clip
Sometimes you don’t want the mask to apply to the entire box. mask-clip controls which box area is masked:
- border-box (default) → includes the border.
- padding-box → includes padding but not the border.
- content-box → only the content area.
.element {
mask-image: url("mask.png");
mask-clip: content-box;
}
This is useful when you want the mask effect only inside the content and not spilling into padding or borders.
6. mask-origin
This property works with mask-position and mask-size. It decides the reference box used for positioning the mask. It accepts the same values as mask-clip (border-box, padding-box, content-box).
.element {
mask-image: url("mask.png");
mask-origin: padding-box;
mask-position: center;
}
Think of it as “from where should we start counting when placing the mask?”
7. mask-composite
When you use multiple masks, this property defines how they interact. The values are:
- add → layers combine (union).
- subtract → subtracts one mask from another.
- intersect → only keeps overlapping areas.
- exclude → keeps areas that do not overlap.
.element {
mask-image: url("circle.png"), url("star.png");
mask-composite: add, intersect;
}
This means the first layer (circle) is applied, and then the second layer (star) is combined with it using an intersect (only the overlapping areas show).
Masks vs. Clipping
At first glance, clipping (clip-path) and masking (mask) seem similar: both hide parts of an element and let only certain areas show. But there’s a key difference in how they work:
clip-path creates hard edges. You can cut an element into a circle, polygon, or other geometric shape, but the edges are always sharp and binary (either visible or hidden). There’s no fading or partial transparency.
mask is much more flexible. It can use transparency and gradients, which means you can create smooth fades, soft edges, or even use complex images (like PNGs or SVGs) to decide what shows and what doesn’t.
In practice, if you want something simple and sharp (like a circle avatar image or a hexagon card), clip-path is the quicker, easier choice. If you want fades, blends, or creative effects (like a photo that dissolves at the edges, or a shape with feathered transparency), mask is the way to go.
Real Examples of CSS Masks
Up until now, we’ve gone through the theory: how masks work, the properties that control them, and how they differ from clip-path.
But the real magic of masks comes when you actually see them in action. Let’s go through a few practical, real-world examples. Each one will show you not just the code, but also explain why it works the way it does.
Example 1: Creating a Circular Image Mask
The most basic use of a mask is to turn a regular rectangle image into a neat circle. You might think, “why not just use border-radius: 50%?” — and you’d be right for simple shapes. But masks go further: you can use them for non-geometric shapes, transparency, and more creative controls.
Here’s a simple circular mask with CSS:
<div class="circle-mask"></div>
.circle-mask {
width: 250px;
height: 250px;
background: url("https://picsum.photos/id/1015/400/400") center/cover no-repeat;
mask-image: radial-gradient(circle, black 70%, transparent 72%);
mask-repeat: no-repeat;
mask-position: center;
mask-size: cover;
-webkit-mask-image: radial-gradient(circle, black 70%, transparent 72%);
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: cover;
}
You’d ask, what’s happening here?
The background image fills the box.
The mask-image is a radial gradient: the center is solid black (meaning “show this”), and it fades to transparent outside (meaning “hide this”).
Because black = visible and transparent = hidden in
mask-image, the result is a circular crop of the image.Unlike
border-radius, this same idea could be extended to stars, polygons, or custom patterns without touching the HTML.
Example 2: Fading Out the Bottom of an Image
One of the coolest features of masks is their ability to handle gradients, something clipping can’t do.
This makes it really easy to fade images into the background, a common trick in modern web design.
<div class="fade-mask"></div>
.fade-mask {
width: 400px;
height: 250px;
background: url("https://picsum.photos/id/1018/600/400") center/cover no-repeat;
mask-image: linear-gradient(to bottom, black 70%, transparent 100%);
mask-repeat: no-repeat;
mask-position: center;
mask-size: cover;
-webkit-mask-image: linear-gradient(to bottom, black 70%, transparent 100%);
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: cover;
}
The mask uses a linear gradient where the top 70% of the image stays fully visible and the bottom gradually fades to transparent, making the photo smoothly disappear into the page background — a perfect effect for blog headers, hero sections, or scroll-based designs.
Example 3: Combining Multiple Masks
Here’s where things get interesting. You can apply more than one mask at the same time. Imagine stacking stencils: only the overlapping areas are visible.
<div class="multi-mask"></div>
.multi-mask {
width: 350px;
height: 250px;
background: url("https://picsum.photos/id/1003/600/400") center/cover no-repeat;
mask-image:
radial-gradient(circle at center, black 70%, transparent 72%),
linear-gradient(to bottom, black 70%, transparent 100%);
mask-repeat: no-repeat, no-repeat;
mask-position: center, center;
mask-size: cover, cover;
-webkit-mask-image:
radial-gradient(circle at center, black 70%, transparent 72%),
linear-gradient(to bottom, black 70%, transparent 100%);
-webkit-mask-repeat: no-repeat, no-repeat;
-webkit-mask-position: center, center;
-webkit-mask-size: cover, cover;
}
What happens here is that the first mask layer cuts the image into a circle, the second fades out the bottom, and together they create a photo that not only has a circular shape but also gradually disappears toward the bottom — with mask-composite available if you need finer control over how the layers blend.
Conclusion
CSS masks are one of those features that feel a little advanced at first, but once you understand how they work, they unlock a new level of creativity in web design.
Unlike clipping, which is limited to hard-edged shapes, masks allow you to use gradients, images, and even multiple layers to control exactly what parts of an element should be visible, hidden, or softly faded away.
The best way to get comfortable with masking is to experiment: try different gradients, combine masks, and see how mask-composite changes the results. Over time, you’ll find that masks are more than just a visual trick.
So go ahead: open up a CodePen, copy some of the examples from this guide, and start experimenting. You’ll quickly see how masks can add that extra layer of depth and polish to your projects.
Frequently Asked Questions
What security measures are essential for CSS hosting?
Key security measures for CSS hosting include SSL/TLS encryption, regular software updates, firewalls, and protection against DDoS attacks. These features safeguard your CSS files and the overall integrity of your website.
How do CSS3 transitions and animations enhance web interactivity?
CSS3 transitions allow smooth transitions between different states of an element, while animations enable the creation of dynamic movement and effects. These features enhance user engagement by adding interactivity and visual interest to web interfaces.
How has CSS3 improved styling and animations for web content?
CSS3 enhances styling with gradients, shadows, rounded corners, and introduces animations and transitions for dynamic, visually appealing web content.
Are there any performance considerations when implementing HTML5 and CSS3?
Yes, using excessive animations and complex designs can impact performance. Optimize images, employ CSS minification, and follow best practices to ensure a smooth and fast user experience.
Joel Olawanle is a Software Engineer and Technical Writer with over three years of experience helping companies communicate their products effectively through technical articles.
View all posts by Joel Olawanle