Tailwind CSS 62 🎨 Masking, Clipping Paths (clip-path), and Visual Geometry Utilities
Rectangles are the default shape of the web. Every element is a box, and every box has four straight edges. The clip-path property and the CSS masking properties break that default. A clip path removes everything outside a geometric shape, and a mask applies an image or a gradient as an alpha channel. Tailwind exposes the clip paths through arbitrary values and a small set of utilities, and the masking properties through the mask-* utilities in v4. The result is buttons that are not rectangular, images that fade at the edges, and layouts where the shape itself is part of the design.
Key point: A clip path removes the parts of the element outside the shape, and the element still occupies its full box in the layout. A mask controls the opacity of each pixel, and the element occupies its full box. Neither changes the layout; both change the paint.
Why masking and clipping exist
The shape problem. The design calls for a hexagonal avatar, a circular profile picture, a diagonal section divider, or a text block that wraps around a shape. The border-radius produces the rounded rectangle and nothing else. The clip-path produces the geometric shapes.
The blend problem. An image must fade into the background at the edges. A gradient over the top of the image produces the fade, and the mask applies the gradient as the alpha channel. The mask-image is the mechanism.
The performance problem. A shape produced by an SVG with an image mask or a complex path is heavy. The clip-path is GPU-accelerated in the modern browsers, and the animations run on the compositor.
The responsive problem. The shape must adapt to the element’s size. The clip-path: polygon() uses the percentage coordinates, so the shape scales with the element. A fixed pixel path does not.
The accessibility problem. The clip path removes the visual content without removing the DOM. A screen reader still reads the text, and the keyboard still focuses the button. The clip-path: circle(0) hides the element from the sighted user but not from the assistive technology. The design must consider the hidden content.
The animation problem. The clip-path is animatable, and the mask is animatable. The hover reveal, the scroll-driven reveal, and the shape transition all use the animation of the clip path or the mask.
The design-system problem. The shapes are part of the design system. A set of the common clip paths, a set of the common masks, and the tokens for the sizes and the angles. The Tailwind utilities and the design tokens together make the shapes consistent.
a. The clip-path utilities
The clip-path property removes the parts of the element outside the shape. The common shapes are the circle, the ellipse, the inset, the polygon, and the path.
The basic circle
<img class="[clip-path:circle(50%)]" src="avatar.jpg" alt="" />
The circle(50%) clips the image to a circle with the radius equal to 50% of the smaller dimension. The image is a circle, and the layout box is unchanged.
The Tailwind arbitrary values
Tailwind does not have the built-in clip-path utilities in the core. The arbitrary values are the mechanism.
<div class="[clip-path:circle(50%)]">Circle</div>
<div class="[clip-path:ellipse(50%_35%)]">Ellipse</div>
<div class="[clip-path:inset(10%_20%_10%_20%)]">Inset</div>
<div class="[clip-path:polygon(50%_0%,_100%_50%,_50%_100%,_0%_50%)]">Diamond</div>
The arbitrary value syntax is [clip-path:value]. The underscores are the spaces.
The circle
<div class="[clip-path:circle(50%)]"></div>
<div class="[clip-path:circle(40%_at_30%_30%)]"></div>
The circle(40% at 30% 30%) places the circle center at the 30% 30% position with the 40% radius.
The ellipse
<div class="[clip-path:ellipse(50%_35%)]"></div>
<div class="[clip-path:ellipse(50%_35%_at_50%_40%)]"></div>
The ellipse(50% 35%) is the ellipse with the 50% horizontal radius and the 35% vertical radius.
The inset
<div class="[clip-path:inset(10%_20%_10%_20%)]"></div>
<div class="[clip-path:inset(10%_20%_10%_20%_round_16px)]"></div>
The inset(10% 20% 10% 20%) clips the rectangle from the top, the right, the bottom, and the left. The round 16px adds the rounded corners.
The polygon
<div class="[clip-path:polygon(50%_0%,_100%_50%,_50%_100%,_0%_50%)]"></div>
<div class="[clip-path:polygon(0%_0%,_100%_0%,_100%_80%,_50%_100%,_0%_80%)]"></div>
The polygon is the set of the points, and each point is the x% y% coordinate. The shape is closed automatically.
The path
<div class="[clip-path:path('M_0_0_L_100_0_L_100_100_Z')]"></div>
The path() uses the SVG path syntax. The path is in the user units, not the percentages, so the shape does not scale with the element.
The clip-path table
| Shape | Syntax | Use Case |
|---|---|---|
| Circle | circle(50%) | The avatar |
| Ellipse | ellipse(50% 35%) | The rounded rectangle |
| Inset | inset(10% 20%) | The rectangle with the custom edges |
| Polygon | polygon(x y, x y, ...) | The hexagon, the diamond, the arrow |
| Path | path('M ...') | The complex shape |
The clip-path animation
The clip-path is animatable. The transition between the two polygons produces the morph.
<div class="
transition-[clip-path] duration-500
[clip-path:polygon(50%_0%,_100%_50%,_50%_100%,_0%_50%)]
hover:[clip-path:polygon(50%_10%,_90%_50%,_50%_90%,_10%_50%)]
">
</div>
The clip-path accessibility
The clipped content is still in the DOM. The screen reader reads it, and the keyboard focuses it. The design must not hide the interactive content outside the clip path.
b. The masking utilities
The mask-image property applies an image or a gradient as the alpha channel. The pixels with the opaque mask are visible, and the pixels with the transparent mask are hidden.
The basic mask
<div class="[mask-image:linear-gradient(to_bottom,_black,_transparent)]">
Content that fades at the bottom.
</div>
The gradient is the mask. The black is the opaque, and the transparent is the hidden.
The Tailwind v4 mask utilities
Tailwind v4 introduces a set of the mask-* utilities.
<div class="mask-b-from-50%">Fade the bottom</div>
<div class="mask-t-from-50%">Fade the top</div>
<div class="mask-l-from-50%">Fade the left</div>
<div class="mask-r-from-50%">Fade the right</div>
The mask-b-from-50% fades the bottom from the 50% point. The mask-t, the mask-l, and the mask-r are the other directions.
The radial mask
<div class="mask-radial-from-50%">Radial fade</div>
<div class="mask-radial-at-center">Centered radial</div>
The mask-radial-from-50% produces the radial gradient mask.
The conic mask
<div class="mask-conic-from-50%">Conic fade</div>
The conic gradient mask produces the sweep.
The mask composite
The mask-composite property combines the multiple masks.
<div class="[mask-image:linear-gradient(black,transparent),linear-gradient(transparent,black)]
[mask-composite:intersect]">
</div>
The intersect combines the two masks, and the visible area is the intersection.
The mask size and position
<div class="[mask-size:cover] [mask-position:center] [mask-repeat:no-repeat]">
</div>
The properties control the size, the position, and the repeat of the mask image.
The mask table
| Utility | Effect |
|---|---|
mask-b-from-50% | Fade the bottom |
mask-t-from-50% | Fade the top |
mask-l-from-50% | Fade the left |
mask-r-from-50% | Fade the right |
mask-radial-from-50% | The radial fade |
mask-conic-from-50% | The conic fade |
The mask accessibility
The mask hides the pixels visually, and the DOM is unchanged. The screen reader reads the text, and the keyboard focuses the elements. The mask must not hide the interactive content.
c. The visual geometry utilities
The geometry utilities are the ones that change the shape or the perspective of the element. The transform, the perspective, and the transform-style are the ones.
The perspective
<div class="[perspective:1000px]">
<div class="[transform:rotateY(45deg)]">3D card</div>
</div>
The perspective sets the distance between the viewer and the z=0 plane. The rotateY(45deg) rotates the child in the 3D space.
The transform-style
<div class="[transform-style:preserve-3d]">
<div class="[transform:translateZ(50px)]">Floating</div>
</div>
The preserve-3d makes the children respect the 3D transforms of the parent.
The backface-visibility
<div class="[backface-visibility:hidden]">Card back</div>
The hidden hides the element when it faces away from the viewer.
The transform-origin
<div class="[transform-origin:top_left] [transform:rotate(45deg)]"></div>
The transform-origin sets the pivot point. The top left is the corner, and the center is the default.
The 3D card flip
<div class="[perspective:1000px]">
<div class="relative h-64 w-48 [transform-style:preserve-3d] transition-transform duration-500 hover:[transform:rotateY(180deg)]">
<div class="absolute inset-0 [backface-visibility:hidden]">Front</div>
<div class="absolute inset-0 [backface-visibility:hidden] [transform:rotateY(180deg)]">Back</div>
</div>
</div>
The two faces are the front and the back, and the hover rotates the card.
The geometry table
| Utility | Effect |
|---|---|
[perspective:1000px] | The 3D perspective |
[transform-style:preserve-3d] | The children respect the 3D |
[backface-visibility:hidden] | Hide when facing away |
[transform-origin:top_left] | The pivot point |
[transform:rotateY(45deg)] | The rotation |
The geometry accessibility
The 3D transforms can trigger the motion sickness in the users. The prefers-reduced-motion handles the case.
@media (prefers-reduced-motion: reduce) {
.flip-card { transition: none; }
.flip-card:hover { transform: none; }
}
Complete Example Session
<!-- ============================================
PART 1: THE BASIC CLIP PATH
============================================ -->
<img class="h-32 w-32 [clip-path:circle(50%)]" src="avatar.jpg" alt="" />
<!-- ============================================
PART 2: THE POLYGON SHAPES
============================================ -->
<div class="h-32 w-32 bg-blue-500 [clip-path:polygon(50%_0%,_100%_50%,_50%_100%,_0%_50%)]">
Diamond
</div>
<div class="h-32 w-48 bg-green-500 [clip-path:polygon(0%_0%,_100%_0%,_100%_80%,_50%_100%,_0%_80%)]">
Banner
</div>
<!-- ============================================
PART 3: THE INSET
============================================ -->
<div class="h-32 w-48 bg-red-500 [clip-path:inset(10%_20%_10%_20%_round_16px)]">
Inset
</div>
<!-- ============================================
PART 4: THE CLIP PATH ANIMATION
============================================ -->
<button class="
h-12 w-32 bg-blue-600 text-white
transition-[clip-path] duration-300
[clip-path:polygon(0%_0%,_100%_0%,_100%_100%,_0%_100%)]
hover:[clip-path:polygon(10%_0%,_90%_0%,_100%_100%,_0%_100%)]
">
Hover me
</button>
<!-- ============================================
PART 5: THE GRADIENT MASK
============================================ -->
<div class="[mask-image:linear-gradient(to_bottom,_black_60%,_transparent)]">
<p>Content that fades at the bottom.</p>
</div>
<!-- ============================================
PART 6: THE TAILWIND V4 MASK UTILITIES
============================================ -->
<div class="mask-b-from-50%">
Content that fades at the bottom.
</div>
<div class="mask-radial-from-50%">
Content that fades radially.
</div>
<!-- ============================================
PART 7: THE IMAGE FADE
============================================ -->
<div class="relative">
<img class="w-full [mask-image:linear-gradient(to_bottom,_black_50%,_transparent)]" src="hero.jpg" alt="" />
</div>
<!-- ============================================
PART 8: THE 3D CARD FLIP
============================================ -->
<div class="[perspective:1000px]">
<div class="
relative h-64 w-48
[transform-style:preserve-3d]
transition-transform duration-500
hover:[transform:rotateY(180deg)]
">
<div class="absolute inset-0 [backface-visibility:hidden] bg-blue-500">
Front
</div>
<div class="absolute inset-0 [backface-visibility:hidden] [transform:rotateY(180deg)] bg-red-500">
Back
</div>
</div>
</div>
<!-- ============================================
PART 9: THE REDUCED MOTION
============================================ -->
<style>
@media (prefers-reduced-motion: reduce) {
.flip-card {
transition: none;
}
.flip-card:hover {
transform: none;
}
}
</style>
<!-- ============================================
PART 10: THE COMPLETE PATTERN
============================================ -->
<!--
1. Use clip-path for the geometric shapes.
2. Use the polygon for the custom shapes.
3. Use the percentage coordinates for the responsive shapes.
4. Use the mask-image for the gradient fades.
5. Use the Tailwind v4 mask utilities for the common directions.
6. Use the mask-composite for the combined masks.
7. Use the perspective for the 3D effects.
8. Use the transform-style: preserve-3d for the nested 3D.
9. Use the backface-visibility: hidden for the card flip.
10. Use prefers-reduced-motion for the accessibility.
-->
The ten parts showed the basic clip path, the polygon shapes, the inset, the clip path animation, the gradient mask, the v4 mask utilities, the image fade, the 3D card flip, the reduced motion, and the complete pattern.
Quick Reference
The clip-path Shapes
| Shape | Syntax | Responsive |
|---|---|---|
| Circle | circle(50%) | Yes |
| Ellipse | ellipse(50% 35%) | Yes |
| Inset | inset(10% 20%) | Yes |
| Polygon | polygon(x y, x y, ...) | Yes |
| Path | path('M ...') | No |
The Mask Utilities (v4)
| Utility | Effect |
|---|---|
mask-b-from-50% | Fade the bottom |
mask-t-from-50% | Fade the top |
mask-l-from-50% | Fade the left |
mask-r-from-50% | Fade the right |
mask-radial-from-50% | The radial fade |
mask-conic-from-50% | The conic fade |
The Geometry Properties
| Property | Purpose |
|---|---|
perspective | The 3D distance |
transform-style | The 3D context |
backface-visibility | The facing-away hide |
transform-origin | The pivot point |
transform | The rotation, scale, translate |
The Common Polygons
| Shape | Points |
|---|---|
| Diamond | 50% 0%, 100% 50%, 50% 100%, 0% 50% |
| Hexagon | 25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50% |
| Triangle | 50% 0%, 100% 100%, 0% 100% |
| Arrow | 0% 20%, 60% 20%, 60% 0%, 100% 50%, 60% 100%, 60% 80%, 0% 80% |
The Browser Support
| Feature | Chrome | Firefox | Safari |
|---|---|---|---|
clip-path | 55+ | 54+ | 9.1+ |
mask-image | 120+ | 53+ | 15.4+ |
mask-composite | 120+ | 53+ | 15.4+ |
perspective | Yes | Yes | Yes |
Best Practices
✅ Do This:
<!-- Use the percentage coordinates for the responsive shapes. -->
<div class="[clip-path:polygon(50%_0%,_100%_50%,_50%_100%,_0%_50%)]"> <!-- ✅ -->
<!-- Use the mask-image for the gradient fades. -->
<div class="[mask-image:linear-gradient(to_bottom,_black,_transparent)]"> <!-- ✅ -->
<!-- Use the v4 mask utilities for the common directions. -->
<div class="mask-b-from-50%"> <!-- ✅ -->
<!-- Use the perspective for the 3D. -->
<div class="[perspective:1000px]"> <!-- ✅ -->
<!-- Use the backface-visibility for the card flip. -->
<div class="[backface-visibility:hidden]"> <!-- ✅ -->
<!-- Use the prefers-reduced-motion for the accessibility. -->
@media (prefers-reduced-motion: reduce) { ... } <!-- ✅ -->
<!-- Use the @supports for the fallback. -->
@supports (clip-path: circle(50%)) { ... } <!-- ✅ -->
❌ Don’t Do This:
<!-- Don't use the path() for the responsive shape. -->
<div class="[clip-path:path('M_0_0_L_100_0_L_100_100_Z')]"> <!-- ❌ Does not scale -->
<!-- Don't forget the underscores in the arbitrary values. -->
<div class="[clip-path:polygon(50% 0%, 100% 50%)]"> <!-- ❌ The space breaks the class -->
<!-- Don't use the clip-path for the layout change. -->
<!-- The element still occupies the full box. --> <!-- ❌ -->
<!-- Don't hide the interactive content with the mask. -->
<div class="[mask-image:linear-gradient(transparent,transparent)]">
<button>Click</button> <!-- ❌ The button is invisible -->
</div>
<!-- Don't skip the reduced-motion handling. -->
<!-- The 3D flip can cause the motion sickness. --> <!-- ❌ -->
<!-- Don't use the fixed pixel coordinates for the responsive shapes. -->
<div class="[clip-path:polygon(0px_0px,_100px_0px)]"> <!-- ❌ Does not scale -->
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Shape does not scale | The fixed pixel coordinates | Use the percentages |
| Class does not apply | The space in the arbitrary value | Use the underscores |
| Layout shifts | The clip-path changes the paint only | The layout is unchanged |
| Mask hides the text | The mask covers the content | Adjust the mask |
| 3D does not work | No perspective | Add the perspective |
| Card flip is flat | No transform-style: preserve-3d | Add the property |
| Back is visible | No backface-visibility: hidden | Add the property |
| Motion sickness | No reduced-motion handling | Add the media query |
Real-World Examples
1. Circle Avatar
<img class="h-32 w-32 [clip-path:circle(50%)]" src="avatar.jpg" alt="" />
2. Diamond
<div class="[clip-path:polygon(50%_0%,_100%_50%,_50%_100%,_0%_50%)]">
3. Hexagon
<div class="[clip-path:polygon(25%_0%,_75%_0%,_100%_50%,_75%_100%,_25%_100%,_0%_50%)]">
4. Inset
<div class="[clip-path:inset(10%_20%_10%_20%_round_16px)]">
5. Gradient Mask
<div class="[mask-image:linear-gradient(to_bottom,_black,_transparent)]">
6. V4 Mask
<div class="mask-b-from-50%">
7. Radial Mask
<div class="mask-radial-from-50%">
8. Perspective
<div class="[perspective:1000px]">
9. Card Flip
<div class="[transform-style:preserve-3d] hover:[transform:rotateY(180deg)]">
10. Reduced Motion
@media (prefers-reduced-motion: reduce) { .flip { transition: none; } }
Visual
The clip-path Shapes
┌────────────────────────────────────────────────────────────┐
│ THE clip-path SHAPES │
│ │
│ CIRCLE POLYGON (diamond) │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ ████ │ │ ▲ │ │
│ │ ████████ │ │ █████ │ │
│ │ ██████████ │ │ █████████ │ │
│ │ ████████ │ │ █████ │ │
│ │ ████ │ │ ▼ │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ INSET HEXAGON │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ ████████████ │ │ ███████ │ │
│ │ ████████████ │ │ ███████████ │ │
│ │ ████████████ │ │ ███████████ │ │
│ │ ████████████ │ │ ███████ │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ The element occupies the full box. The clip path │
│ determines what is painted. │
└────────────────────────────────────────────────────────────┘
The Mask
┌────────────────────────────────────────────────────────────┐
│ THE MASK │
│ │
│ mask-image: linear-gradient(to bottom, black, transparent)│
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Content: fully visible (black = opaque) │ │
│ │ Content: partially visible │ │
│ │ Content: fading │ │
│ │ Content: transparent (transparent = hidden) │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ The mask is an alpha channel. The black is opaque, │
│ the transparent is hidden. │
└────────────────────────────────────────────────────────────┘
The 3D Card Flip
┌────────────────────────────────────────────────────────────┐
│ THE 3D CARD FLIP │
│ │
│ <div class="[perspective:1000px]"> │
│ <div class="[transform-style:preserve-3d] │
│ hover:[transform:rotateY(180deg)]"> │
│ │
│ FRONT (visible) │
│ ┌──────────────────────────────────────────┐ │
│ │ [backface-visibility:hidden] │ │
│ │ Front content │ │
│ └──────────────────────────────────────────┘ │
│ │
│ BACK (hidden, rotated 180deg) │
│ ┌──────────────────────────────────────────┐ │
│ │ [backface-visibility:hidden] │ │
│ │ [transform:rotateY(180deg)] │ │
│ │ Back content │ │
│ └──────────────────────────────────────────┘ │
│ │
│ On hover, the parent rotates, and the back becomes │
│ visible. │
└────────────────────────────────────────────────────────────┘
The Coordinate Systems
┌────────────────────────────────────────────────────────────┐
│ THE COORDINATE SYSTEMS │
│ │
│ clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%) │
│ │
│ (0,0) ─────────────── (50%,0) ─────────────── (100%,0) │
│ │ ▲ │ │
│ │ / \ │ │
│ │ / \ │ │
│ │ / \ │ │
│ (0,50%) ────────── (50%,50%) ─────────── (100%,50%) │
│ │ \ / │ │
│ │ \ / │ │
│ │ \ / │ │
│ │ ▼ │ │
│ (0,100%) ────────── (50%,100%) ───────── (100%,100%) │
│ │
│ The coordinates are the percentages of the element. │
│ The shape scales with the element. │
└────────────────────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
clip-path | Removes the parts outside the shape |
circle() | The circle shape |
ellipse() | The ellipse shape |
inset() | The rectangle from the edges |
polygon() | The custom shape from the points |
path() | The SVG path, not responsive |
mask-image | The alpha channel from the image |
mask-b-from-* | The v4 bottom fade |
perspective | The 3D distance |
transform-style: preserve-3d | The 3D context |
backface-visibility: hidden | The facing-away hide |
Key takeaways:
- The
clip-pathremoves the parts of the element outside the shape. The element still occupies its full box in the layout. The circle, the ellipse, the inset, the polygon, and the path are the shapes. The percentage coordinates make the shape responsive. - The
mask-imageapplies an image or a gradient as the alpha channel. The black is the opaque, and the transparent is the hidden. Thelinear-gradientproduces the fade, and theradial-gradientproduces the vignette. - The Tailwind v4 mask utilities cover the common directions. The
mask-b-from-50%, themask-t-from-50%, themask-l-from-50%, and themask-r-from-50%are the directional fades. Themask-radial-from-50%and themask-conic-from-50%are the radial and the conic. - The
mask-compositecombines the multiple masks. Theintersectproduces the intersection, and theaddproduces the union. The combined masks produce the complex shapes. - The
perspectiveand thetransform-styleproduce the 3D. Theperspectivesets the viewer distance, and thepreserve-3dmakes the children respect the 3D transforms. Thebackface-visibility: hiddenhides the element when it faces away. - The
transform-originsets the pivot point. The default is the center, and thetop leftis the corner. The pivot determines the rotation and the scale behavior. - The clipped and the masked content is still in the DOM. The screen reader reads it, and the keyboard focuses it. The design must not hide the interactive content.
- The reduced-motion handling is the accessibility. The 3D transforms and the clip path animations can trigger the motion sickness. The
prefers-reduced-motionmedia query disables the motion.
Remember: The clip-path and the masking properties break the rectangular default of the web. The clip-path removes the parts of the element outside the shape, and the mask-image applies the alpha channel. The Tailwind arbitrary values and the v4 mask utilities expose the properties, and the design tokens keep the shapes consistent. The perspective and the transform-style produce the 3D effects, and the backface-visibility produces the card flip. The result is an interface where the shape is part of the design, the fades are smooth, and the 3D effects are hardware-accelerated.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!