|$ curl https://forge-ai.dev/api/markdown?path=docs/css/clip-mask
$cat docs/css-clip-&-masking.md
updated Yesterday·11 min read·published

CSS Clip & Masking

CSSClip & MaskEffectsAdvanced
Introduction

CSS clipping and masking control which parts of an element are visible. Clipping (clip-path) uses geometric shapes to define a visible region — everything outside the shape is hidden. Masking (mask-*) uses an image or gradient to control visibility based on pixel alpha values.

While both techniques hide portions of an element, they differ fundamentally: clip-path is a vector-based approach using paths and shapes, while masking is a raster-based approach using image data. Clipping is generally more performant for simple shapes.

clip-mask-intro.css
CSS
1.clip-example {
2 clip-path: circle(50% at center);
3 /* Only shows a circular region of the element */
4}
5
6.mask-example {
7 mask-image: linear-gradient(black, transparent);
8 /* Fades out from top to bottom */
9}
clip-path

The clip-pathproperty creates a clipping region that defines which part of an element is visible. The element's background, borders, shadows, and even child content are all clipped to the defined shape.

clip-path-basics.css
CSS
1.element {
2 /* Basic clip path shapes */
3 clip-path: none; /* no clipping (default) */
4 clip-path: inset(10%); /* rectangle inset from edges */
5 clip-path: circle(50%); /* circular clip */
6 clip-path: ellipse(25% 40%); /* elliptical clip */
7 clip-path: polygon(50% 0%, ...); /* custom polygon */
8 clip-path: path('M0 0 ...'); /* SVG path (modern browsers) */
9
10 /* With position */
11 clip-path: circle(30% at top right);
12 clip-path: polygon(0 0, 100% 0, 100% 75%, 50% 100%, 0 75%);
13}
preview
Shape Functions

The clip-path property accepts several shape functions, each with its own parameters for defining the clipping region.

inset()

Creates a rectangular clip region inset from the element's edges. Supports optional round for rounded corners.

inset.css
CSS
1.inset {
2 /* inset(top, right, bottom, left) */
3 clip-path: inset(10px 20px 10px 20px);
4 clip-path: inset(10%); /* 10% from all edges */
5 clip-path: inset(0 round 12px); /* clipped to rounded rectangle */
6 clip-path: inset(10% 5% 10% 5% round 8px);
7}

circle()

Creates a circular clip region defined by radius and center position.

circle.css
CSS
1.circle {
2 clip-path: circle(50%); /* half the element size */
3 clip-path: circle(30% at top left); /* centered at top-left */
4 clip-path: circle(50px at 50% 50%); /* fixed radius at center */
5}

ellipse()

ellipse.css
CSS
1.ellipse {
2 clip-path: ellipse(25% 40%); /* wide ellipse */
3 clip-path: ellipse(60px 30px at center); /* fixed dimensions */
4 clip-path: ellipse(50% 50% at 0 50%); /* half-ellipse on left */
5}

polygon()

Creates a custom polygonal clip region from a set of coordinate pairs. This is the most versatile shape function, capable of creating complex clipping regions.

polygon.css
CSS
1.triangle {
2 clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
3}
4
5.hexagon {
6 clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
7}
8
9.star {
10 clip-path: polygon(
11 50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%,
12 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%
13 );
14}
15
16.chevron {
17 clip-path: polygon(0% 0%, 75% 0%, 100% 50%, 75% 100%, 0% 100%, 25% 50%);
18}

path()

The path() function accepts an SVG path data string, enabling arbitrary shapes defined by cubic and quadratic bezier curves.

path.css
CSS
1.custom-shape {
2 clip-path: path('M 0 0 L 100 0 L 100 100 L 50 80 L 0 100 Z');
3 /* SVG path syntax for maximum flexibility */
4}
clip-path with Animations

clip-path can be animated when transitioning between compatible shapes (same shape type with matching number of points for polygons). This enables smooth morphing effects.

clip-path-animations.css
CSS
1.morph {
2 clip-path: circle(30%);
3 transition: clip-path 0.5s ease;
4}
5
6.morph:hover {
7 clip-path: circle(70%);
8 /* Smoothly grows the circle on hover */
9}
10
11.polygon-morph {
12 clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
13 transition: clip-path 0.5s ease;
14}
15
16.polygon-morph:hover {
17 clip-path: polygon(20% 0%, 80% 0%, 100% 80%, 0% 100%);
18 /* Morphs to an irregular quadrilateral */
19}
20
21@keyframes reveal {
22 0% { clip-path: circle(0% at center); }
23 100% { clip-path: circle(100% at center); }
24}
25
26.reveal-anim {
27 animation: reveal 0.8s ease-out forwards;
28}
preview
📝

note

For polygon animations, the number of vertex points must be the same in both the start and end states. Otherwise, the animation falls back to a discrete jump instead of a smooth morph.
The mask Property

The mask property and its sub-properties use image data to determine which parts of an element are visible. Unlike clip-path which uses hard vector shapes, masking uses alpha channels for smooth transitions and gradient-based fades.

mask-basics.css
CSS
1.element {
2 /* Mask with a linear gradient — smooth fade */
3 mask-image: linear-gradient(black, transparent);
4 -webkit-mask-image: linear-gradient(black, transparent);
5
6 /* Multiple mask shorthand properties */
7 mask-mode: alpha; /* use alpha channel (default) */
8 mask-mode: luminance; /* use luminance values */
9
10 mask-repeat: no-repeat;
11 mask-position: center;
12 mask-size: cover;
13
14 /* Shorthand */
15 mask: url('mask.png') alpha center / cover no-repeat;
16}
mask-image

mask-image defines the image used as the mask. The alpha channel (or luminance, depending on mask-mode) determines visibility: opaque regions of the mask show the element, transparent regions hide it.

mask-image.css
CSS
1.gradient-fade {
2 /* Linear gradient mask */
3 mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
4 -webkit-mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
5 /* Fades out the bottom 40% of the element */
6}
7
8.radial-reveal {
9 mask-image: radial-gradient(ellipse at center, black 30%, transparent 70%);
10 -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 70%);
11 /* Reveals the center of the element in a soft vignette */
12}
13
14.image-mask {
15 mask-image: url('mask-texture.png');
16 -webkit-mask-image: url('mask-texture.png');
17 mask-size: cover;
18}
19
20/* Useful gradients for masking */
21.fade-right {
22 mask-image: linear-gradient(to right, black, transparent);
23}
24
25.fade-all-sides {
26 mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, black 30%, transparent 70%);
27}
preview
mask-mode & Other Sub-properties

The mask sub-properties mirror the background-* properties and control how the mask image is applied and rendered.

mask-mode.css
CSS
1.mask-demo {
2 /* mask-mode — determines which channel to use */
3 mask-mode: alpha; /* use alpha channel (default) */
4 mask-mode: luminance; /* use luminance values */
5 mask-mode: match-source; /* auto-detect from image type */
6
7 /* mask-clip — clipping area for the mask */
8 mask-clip: border-box; /* default */
9 mask-clip: content-box;
10 mask-clip: padding-box;
11
12 /* mask-composite — combine multiple mask layers */
13 mask-composite: add; /* default — union */
14 mask-composite: subtract; /* subtract from below */
15 mask-composite: intersect; /* intersection */
16 mask-composite: exclude; /* exclude overlapping areas */
17}

info

Remember to include the -webkit- prefix for all mask properties. While standard CSS masking is supported in modern browsers, Safari and older browsers require the vendor prefix for many mask features.
Practical Examples

Image Reveal

image-reveal.css
CSS
1.image-reveal {
2 position: relative;
3 overflow: hidden;
4}
5
6.image-reveal img {
7 clip-path: circle(0% at center);
8 transition: clip-path 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
9}
10
11.image-reveal:hover img {
12 clip-path: circle(100% at center);
13}
14
15/* Gradient reveal alternative */
16.gradient-reveal {
17 mask-image: linear-gradient(to right, transparent 0%, black 20%, black 80%, transparent 100%);
18 -webkit-mask-image: linear-gradient(to right, transparent 0%, black 20%, black 80%, transparent 100%);
19 mask-size: 200% 100%;
20 mask-position: 100% 0;
21 transition: mask-position 0.5s ease;
22}
23
24.gradient-reveal:hover {
25 mask-position: 0 0;
26}

Terminal Window Shapes

terminal-shapes.css
CSS
1.terminal-window-clip {
2 clip-path: polygon(
3 12px 0%, /* top-left corner radius */
4 100% 0%,
5 100% 100%,
6 0% 100%,
7 0% 12px
8 );
9 /* Creates a terminal-like window with clipped top-left corner area */
10 /* More accurately, use border-radius for actual terminal windows */
11 border-radius: 8px;
12}
13
14/* Terminal scanline mask overlay */
15.scanline-mask {
16 position: absolute;
17 inset: 0;
18 background: repeating-linear-gradient(
19 0deg,
20 transparent 0px,
21 transparent 2px,
22 rgba(0, 0, 0, 0.1) 2px,
23 rgba(0, 0, 0, 0.1) 4px
24 );
25 mix-blend-mode: overlay;
26 pointer-events: none;
27}
28
29/* Hexagonal grid layout for terminal dashboard */
30.hex-clip {
31 clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
32 transition: clip-path 0.3s ease;
33}
34
35.hex-clip:hover {
36 clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 100% 100%, 0% 100%, 0% 50%);
37}

Smooth Scroll Reveal

scroll-reveal.css
CSS
1.scroll-reveal {
2 mask-image: linear-gradient(to right, transparent 0%, black 50%, transparent 100%);
3 -webkit-mask-image: linear-gradient(to right, transparent 0%, black 50%, transparent 100%);
4 mask-size: 200% 100%;
5 animation: sweep-reveal 1.5s ease-out forwards;
6}
7
8@keyframes sweep-reveal {
9 0% { mask-position: -100% 0; }
10 100% { mask-position: 0% 0; }
11}
12
13/* Diagonal reveal */
14.diagonal-reveal {
15 clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);
16 transition: clip-path 0.6s ease-out;
17}
18
19.diagonal-reveal.visible {
20 clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
21}
Best Practices
Use clip-path for hard-edged geometric shapes — it's more performant than masking
Use mask with gradients for smooth fades and soft-edged reveals
Always include -webkit- prefix for mask properties to support Safari
For polygon animation morphing, ensure both states have the same number of vertices
Prefer clip-path over SVG clipping for simple shapes — less markup, same result
Use clip-path: inset(0 round 8px) as an alternative to border-radius for clipping children
Mask gradients can be animated by animating mask-position or mask-size
clip-path creates a new stacking context — account for z-index implications
Test clipped/masked elements on HiDPI screens to ensure crisp edges
$Blueprint — Engineering Documentation·Section ID: CSS-26·Revision: 1.0