Quick answer
CSS clip-path hides every part of an element outside a shape, so a plain box can render as a triangle, circle, star or arrow without any image. In Playxoft's free CSS Clip-Path Generator, pick a shape, drag its points or handles on the preview (click an edge to add a point), and copy the clip-path as CSS, Tailwind, SCSS or an SVG clipPath. Percent values keep the shape responsive; px values fix it to one element size.
- Drag-and-drop points
- Polygon, circle, ellipse, inset
- Click an edge to add points
- Snap to grid
- 19 one-click presets
- Percent or px output
- SVG clipPath export
- Import existing CSS
How to use the Clip-Path Generator
- 1Choose Polygon, Circle, Ellipse or Inset, or click a shape under Presets to start from a triangle, star, arrow or frame.
- 2Drag the handles on the preview. On a polygon, click an edge to add a point there and press Delete to remove the selected point.
- 3Fine-tune exact values in the settings panel, and turn on Snap to grid when you want tidy, round coordinates.
- 4Pick Percent or Pixels under Output units (set the element Width and Height for px), then copy from the CSS, Tailwind, SCSS or SVG tab.
- 5Click Share to copy a link that reopens this exact shape, or paste an existing clip-path into Import CSS to keep editing it.
What does CSS clip-path do?
clip-path defines a region, and only the part of the element inside it is painted. Everything outside, including the background, borders, box-shadow and child content, is cut away. The element still takes up its full rectangle in the layout, so clipping never makes surrounding content reflow.
.hero-image {
clip-path: polygon(0% 0%, 100% 0%, 100% 85%, 0% 100%); /* slanted bottom edge */
}Clipped-away areas also stop receiving clicks and hovers, so a clipped button is only clickable inside its visible shape. The property is defined in the CSS Masking specification, and the shape functions in CSS Shapes.
Which clip-path shape functions can I use?
| Function | Example | Good for | Notes |
|---|---|---|---|
inset() | inset(10% 20% round 12px) | Crops, rounded windows | Offsets use margin order: top, right, bottom, left |
circle() | circle(40% at 50% 50%) | Avatars, circular reveals | A % radius is relative to √(width² + height²) / √2 |
ellipse() | ellipse(45% 35% at 50% 50%) | Ovals, spotlights | Horizontal radius uses the width, vertical the height |
polygon() | polygon(50% 0%, 100% 100%, 0% 100%) | Triangles, stars, arrows, badges | Straight edges only; optional evenodd fill rule |
path() | path("M 0 0 L 200 0 L 100 160 Z") | Curves | Coordinates are px only, so it does not scale |
shape() | shape(from 0% 0%, line to 100% 0%, line to 50% 100%, close) | Responsive curves | In all major engines since early 2026 (Chrome and Edge 135, Safari 18.4, Firefox 148) |
url() | url(#my-clip) | Reusing an SVG <clipPath> | Export one from the SVG tab |
After the shape you can name a reference box, such as polygon(...) content-box. Without one, coordinates are measured against the border box.
How do polygon coordinates work?
Each point is an x y pair. The origin is the element's top-left corner, x grows to the right and y grows down, so 100% 100% is the bottom-right corner. Percentages are relative to the element's own width (for x) and height (for y), which is why a percentage polygon stretches with the element. Pixel values stay fixed.
The browser joins the points in order and closes the shape back to the first point, so the order matters: crossing edges create a bow-tie. To cut a hole, as in the Frame preset, trace the outer edge, step inward along a zero-width slit, trace the inner edge the opposite way and step back out. With the default nonzero fill rule the opposite winding leaves the middle empty; polygon(evenodd, ...) makes any overlapping loop a hole regardless of direction.
/* A right-pointing block arrow: 7 points, clockwise from the tail */
.arrow {
clip-path: polygon(0% 20%, 60% 20%, 60% 0%, 100% 50%, 60% 100%, 60% 80%, 0% 80%);
}How do I animate between two clip-path shapes?
Browsers interpolate clip-path only between the same shape function. Two polygons must also have the same number of points (and the same fill rule); otherwise the change jumps instead of morphing. When one shape has fewer points, pad it with duplicates sitting on top of each other:
.badge {
/* A triangle written with 4 points: the first two are the same */
clip-path: polygon(50% 0%, 50% 0%, 100% 100%, 0% 100%);
transition: clip-path 0.4s ease;
}
.badge:hover {
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
}
@media (prefers-reduced-motion: reduce) {
.badge { transition: none; }
}Circles animate radius and center, insets animate each offset and the corner radius, so a circle(0% at 50% 50%) to circle(75% at 50% 50%) transition is the classic circular reveal.
Should I use clip-path or mask?
clip-path | mask-image | |
|---|---|---|
| Edge | Hard, geometric outline | Soft: any level of transparency |
| Defined by | Shape function or SVG <clipPath> | Image, gradient or SVG <mask> |
| Fades and feathering | No | Yes, e.g. linear-gradient(black, transparent) |
| Responsive shapes | Yes, with percentages | Yes, with mask-size |
| Best for | Cut-outs, angled sections, reveals | Fading edges, texture or logo-shaped masks |
Reach for clip-path when the edge is a crisp geometric line, and mask when you need partial transparency.
Why is my box-shadow cut off by clip-path?
Clipping removes everything the element paints outside the shape, and a box-shadow sits outside the shape by definition. Focus outlines are clipped too. The fix is to move the shadow to a wrapper and use filter: drop-shadow(), which follows the visible pixels rather than the box:
.shape-shadow {
filter: drop-shadow(0 10px 16px rgb(0 0 0 / 0.25));
}
.shape-shadow > .shape {
clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
}Build the shadow values with the box shadow generator in drop-shadow mode, and give clipped buttons a focus style that stays inside the shape, such as an inset ring or a color change.
Frequently asked questions
Last updated by the Playxoft engineering team.