In short
CSS blend modes, clip-path and masks let you mix colors like in Photoshop, cut elements into shapes like circles and arrows, and fade edges with gradients. What are CSS blend modes? A blend mode decides how the colors of an element mix with the colors under it.
CSS blend modes, clip-path and masks let you mix colors like in Photoshop, cut elements into shapes like circles and arrows, and fade edges with gradients.
What are CSS blend modes?
A blend mode decides how the colors of an element mix with the colors under it. If you have used layers in a photo editor, it is the same idea. CSS has two blend properties:
mix-blend-modeblends an element with whatever is behind it on the page.background-blend-modeblends an element's own background layers (for example an image and a color) with each other.
The most useful modes are multiply (darkens, like ink on paper), screen (lightens, like light from two projectors), overlay (more contrast), difference (inverts where things overlap) and luminosity.
Tinting an image with background-blend-mode
A common design trick is a photo tinted in your brand color. With background-blend-mode you don't need to edit the image.
<section class="banner">
<h2>Summer coding camp</h2>
</section>
.banner {
min-height: 250px;
display: grid;
place-items: center;
color: white;
background-color: #1d4ed8;
background-image: url("https://picsum.photos/id/1015/1200/500");
background-size: cover;
background-blend-mode: multiply;
}
The photo now looks dark blue, as if printed in blue ink, and the white heading is easy to read on top. Try luminosity or screen to see other moods.
Here is mix-blend-mode on text:
.banner h2 {
font-size: 4rem;
mix-blend-mode: overlay;
}
The big heading now mixes with the photo behind it, so parts of the image show through the letters. If blending affects more than you want, add isolation: isolate to the parent: blending then stays inside that parent.
Cutting shapes with clip-path
clip-path cuts an element into a shape. Only the part inside the shape is visible; the rest is hidden, like cutting a photo with scissors. There are three basic shape functions:
circle(50%)– a circle. You can also set the center:circle(40% at 50% 30%).inset(10px round 12px)– a rectangle cut in from each edge, with optional rounded corners.polygon(...)– any shape made of points. Each point is "x y", measured from the top-left corner.
<img class="avatar" src="https://picsum.photos/id/237/300/300" alt="A black puppy">
<div class="arrow-badge">New</div>
.avatar {
width: 150px;
clip-path: circle(50%);
}
.arrow-badge {
display: inline-block;
padding: 8px 32px 8px 16px;
background: #dc2626;
color: white;
font-weight: bold;
clip-path: polygon(0 0, 85% 0, 100% 50%, 85% 100%, 0 100%);
}
The puppy photo becomes a circle. The red "New" badge has a pointed right side, like an arrow. The polygon points go clockwise: top-left, near top-right, the middle of the right edge (the tip), near bottom-right, and bottom-left.
Note:
clip-pathhides parts of the element, but it doesn't change its size in the layout. The space it takes up stays the same, and clicks only work on the visible part.
Animating clip-path
You can animate clip-path between two shapes of the same type. For polygon(), both shapes must have the same number of points.
.reveal-img {
clip-path: inset(0 100% 0 0);
transition: clip-path 0.6s ease;
}
.card:hover .reveal-img {
clip-path: inset(0 0 0 0);
}
At first the image is fully cut away from the right side, so you can't see it. When you hover the card, the image is "wiped" into view from left to right. You can do the same with a circle growing from circle(0%) to circle(75%).
Common mistake: Animating from
circle()topolygon(), or between polygons with a different number of points. The browser can't blend them, so the shape just jumps. Keep the same function and the same point count.
Fading edges with mask-image
A mask decides how visible each part of an element is. Where the mask is solid, the element shows; where the mask is transparent, the element disappears. Gradients make great masks because they fade smoothly.
<div class="story">
<p>Once upon a time, in a small town by the sea, there lived a girl who wanted to build robots...</p>
<p>Every day after school she collected old radios and broken toys...</p>
<p>One stormy night, her first robot finally opened its eyes...</p>
</div>
.story {
max-height: 140px;
overflow: hidden;
mask-image: linear-gradient(to bottom, black 50%, transparent 100%);
}
The top half of the text is fully visible, and then it slowly fades out towards the bottom, inviting the reader to click "Read more". The color black in a mask simply means "fully visible"; the actual color doesn't matter, only its transparency.
You can also fade the edges of a horizontal scrolling list, so users see there is more content:
.scroller {
overflow-x: auto;
mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
}
Both edges fade softly, and the middle stays sharp. Masks work in all modern browsers without a prefix. Learn more on MDN's mask-image page.
Practice exercise
Build a "Meet the team" section with three photos. Clip each photo into a circle, give the section background a photo tinted with your brand color using background-blend-mode, and add a hover effect where the circle grows from circle(45%) to circle(50%).
Hint: put transition: clip-path 0.3s on the image and change clip-path inside :hover.
Key takeaways
mix-blend-modeblends an element with what is behind it;background-blend-modeblends its own backgrounds.clip-pathcuts elements intocircle(),inset()orpolygon()shapes.- Animate
clip-pathonly between shapes of the same type and point count. mask-imagewith a gradient fades parts of an element smoothly.- Clipping and masking change what you see, not the element's layout size.