Every element on the web is a rectangle. Headers, cards, images, buttons -- all rectangles. CSS clip-path breaks that constraint by letting you define a visible region using shapes or SVG paths. Anything outside the path is invisible.
I started using clip-path for simple diagonal sections and ended up using it for complex geometric layouts, image reveals, and scroll-triggered animations.
The basic shapes
clip-path supports four basic shape functions:
circle(): Clips to a circle.
.avatar {
clip-path: circle(50% at 50% 50%);
}
The first value is the radius, at defines the center. 50% at 50% 50% creates a circle centered on the element using the full width/height.
ellipse(): Clips to an ellipse with separate horizontal and vertical radii.
.banner {
clip-path: ellipse(60% 40% at 50% 50%);
}
inset(): Clips to a rectangle with optional rounded corners. Useful for revealing portions of an element.
.reveal {
clip-path: inset(10% 20% 10% 20% round 15px);
}
polygon(): Clips to any polygon defined by vertex coordinates. This is where the real power is.
.diagonal-section {
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
}
This creates a section where the top edge is straight and the bottom edge angles from 85% height on the right to 100% height on the left, producing a diagonal cut.
Practical patterns
Angled section dividers: Instead of straight horizontal boundaries between page sections, use polygon clip-paths:
.hero {
clip-path: polygon(0 0, 100% 0, 100% calc(100% - 80px), 0 100%);
}
.next-section {
margin-top: -80px;
clip-path: polygon(0 80px, 100% 0, 100% 100%, 0 100%);
}
This creates a seamless angled transition between sections. The negative margin on the second section eliminates the gap created by the angled cut.
Hexagonal images: Social media profiles and team pages use non-rectangular image crops:
.hexagon {
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}
Arrow shapes: Buttons or navigation elements with an arrow pointing right:
.arrow-button {
clip-path: polygon(0 0, calc(100% - 20px) 0, 100% 50%, calc(100% - 20px) 100%, 0 100%);
}
Animation with clip-path
clip-path is animatable between shapes of the same type with the same number of points. This enables reveal effects:
.reveal-left {
clip-path: inset(0 100% 0 0);
transition: clip-path 0.6s ease-out;
}
.reveal-left.visible {
clip-path: inset(0 0 0 0);
}
This creates a left-to-right reveal animation. The element starts fully clipped (right inset at 100%) and transitions to fully visible. Triggered by adding a class via JavaScript (on scroll, on click, etc).
For more complex reveals:
.circle-reveal {
clip-path: circle(0% at 50% 50%);
transition: clip-path 0.8s ease-out;
}
.circle-reveal.visible {
clip-path: circle(75% at 50% 50%);
}
This creates a circle expanding from the center, revealing the content outward.
Browser support and fallbacks
clip-path with basic shapes has excellent support in all modern browsers. The path() function (using SVG path syntax) has more limited support.
For older browsers, provide a fallback:
.clipped {
/* Fallback - no clipping */
overflow: hidden;
border-radius: 50%;
}
@supports (clip-path: circle(50%)) {
.clipped {
clip-path: circle(50%);
border-radius: 0;
overflow: visible;
}
}
The generator
Polygon coordinates are tedious to write by hand because you are working in percentage coordinates without visual feedback. Moving a vertex from 75% 25% to 78% 22% requires trial and error. I built a CSS clip-path generator with a visual editor where you can drag vertices, see the shape in real time, and copy the generated CSS.
I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.
Top comments (0)