What You'll Learn
Clip elements to circles and ellipses with circle() and ellipse()
Create custom shapes with polygon() (triangles, stars, arrows, etc.)
Apply clip-path to images for creative shaped photos
Animate clip-path for shape morphing effects
Build interactive hover effects with smooth clip-path transitions
Understand coordinate systems and positioning
Use inset() for rounded rectangles and borders
Introduction to Clip Path
The clip-path property clips an element to a specific shape, hiding everything outside the clipping region. Unlike border-radius which only rounds corners, clip-path can create any geometric shape: circles, triangles, stars, custom polygons, and more.
Clipping is perfect for creative layouts, shaped images, geometric designs, and animations. The clipped area defines what's visible; everything outside becomes transparent.
Non-Destructive: clip-path doesn't modify the element itself—it only changes what's visible. The element retains its full size for layout purposes.
circle() - Circular Clipping
The circle() function clips elements to circular shapes. Specify a radius and optional center position.
/* circle(radius at x y) */
/* Circle at center (default) */
clip-path: circle(50%);
/* 50% radius creates perfect circle */
/* Smaller circle */
clip-path: circle(40%);
/* Larger circle (can exceed 50%) */
clip-path: circle(70%);
/* Circle with pixel radius */
clip-path: circle(100px);
/* Circle at custom position */
clip-path: circle(50% at 70% 30%);
/* Center at 70% horizontal, 30% vertical */
clip-path: circle(50% at right top);
/* Keywords: left, center, right, top, bottom */
/* Practical examples */
/* Circular profile picture */
.avatar {
clip-path: circle(50%);
}
/* Circular button */
.round-button {
clip-path: circle(50%);
width: 60px;
height: 60px;
}
/* Spotlight effect */
.spotlight {
clip-path: circle(30% at 50% 50%);
}
Radius Units: Use percentages for responsive circles or pixel values for fixed sizes. 50% creates a perfect circle when element has equal width and height.
ellipse() - Oval Clipping
The ellipse() function creates oval shapes with independent horizontal and vertical radii.
/* ellipse(rx ry at x y) */
/* Horizontal ellipse */
clip-path: ellipse(50% 35%);
/* 50% horizontal, 35% vertical radius */
/* Vertical ellipse */
clip-path: ellipse(35% 50%);
/* Pill shape (extreme horizontal ellipse) */
clip-path: ellipse(50% 20%);
/* Ellipse at custom position */
clip-path: ellipse(40% 50% at 70% 50%);
/* Practical examples */
/* Pill button */
.pill-button {
clip-path: ellipse(50% 25%);
padding: 0.5rem 2rem;
}
/* Vertical pill */
.vertical-pill {
clip-path: ellipse(30% 50%);
}
/* Speech bubble base */
.bubble-base {
clip-path: ellipse(45% 50%);
}
Pill Shapes: Create pill/capsule buttons by combining ellipse() clipping with appropriate padding. More flexible than border-radius: 999px.
polygon() - Custom Shapes
The polygon() function connects points to create custom shapes. Define each point as x y coordinates (percentages or pixels).
/* polygon(x1 y1, x2 y2, x3 y3, ...) */
/* Triangle (3 points) */
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
/* Point 1: top center, Point 2: bottom left, Point 3: bottom right */
/* Diamond/Rhombus (4 points) */
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
/* Top, right, bottom, left */
/* Pentagon (5 points) */
clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
/* Hexagon (6 points) */
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
/* Octagon (8 points) */
clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%,
70% 100%, 30% 100%, 0% 70%, 0% 30%);
/* Star (10 points - 5 outer, 5 inner) */
clip-path: polygon(
50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%,
50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%
);
/* Arrow pointing right */
clip-path: polygon(0% 20%, 60% 20%, 60% 0%, 100% 50%,
60% 100%, 60% 80%, 0% 80%);
/* Chevron */
clip-path: polygon(75% 0%, 100% 50%, 75% 100%,
0% 100%, 25% 50%, 0% 0%);
/* Message/speech bubble */
clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%,
75% 100%, 50% 75%, 0% 75%);
/* Parallelogram */
clip-path: polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%);
/* Trapezoid */
clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
Coordinate System: 0% 0% is top-left corner, 100% 100% is bottom-right. 50% 50% is center. List points in clockwise order for best results.
inset() - Rectangular Clipping
The inset() function creates rectangular clipping regions with optional rounded corners. Perfect for cropping with rounded edges.
/* inset(top right bottom left round border-radius) */
/* Inset all sides equally */
clip-path: inset(20px);
/* 20px inset on all sides */
/* Inset individual sides (like margin/padding) */
clip-path: inset(10px 20px 30px 40px);
/* top right bottom left */
/* Rounded rectangle */
clip-path: inset(0px round 20px);
/* No inset, but 20px rounded corners */
/* Inset with different corner radii */
clip-path: inset(10px round 20px 10px);
/* 10px inset, 20px horizontal radius, 10px vertical radius */
/* Four different corner radii */
clip-path: inset(0px round 10px 20px 30px 40px);
/* Like border-radius: top-left, top-right, bottom-right, bottom-left */
/* Practical examples */
/* Rounded image without border-radius */
.image {
clip-path: inset(0px round 16px);
}
/* Crop top and bottom */
.letterbox {
clip-path: inset(15% 0 15% 0);
}
/* Crop to center */
.centered-crop {
clip-path: inset(10% 10%);
}
inset vs border-radius: Use inset() when you need both cropping and rounding, or when combining with other clip-path effects. Otherwise, border-radius is simpler.
Clipping Images
Apply clip-path to images for creative shaped photos, gallery layouts, and profile pictures.
/* Hexagonal profile picture */
.profile-image {
width: 200px;
height: 200px;
clip-path: polygon(25% 0%, 75% 0%, 100% 50%,
75% 100%, 25% 100%, 0% 50%);
}
/* Star-shaped gallery image */
.gallery-image {
clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%,
79% 91%, 50% 70%, 21% 91%, 32% 57%,
2% 35%, 39% 35%);
}
/* Circular avatar */
.avatar {
width: 150px;
height: 150px;
object-fit: cover;
clip-path: circle(50%);
}
/* Diamond product image */
.product-thumb {
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
}
/* Message bubble thumbnail */
.message-image {
clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%,
75% 100%, 50% 75%, 0% 75%);
}
/* Masonry-style clipped grid */
.masonry-item:nth-child(3n+1) {
clip-path: polygon(0 0, 100% 0, 100% 80%, 0 100%);
}
.masonry-item:nth-child(3n+2) {
clip-path: polygon(0 20%, 100% 0, 100% 100%, 0 80%);
}
.masonry-item:nth-child(3n+3) {
clip-path: polygon(25% 0%, 75% 0%, 100% 50%,
75% 100%, 25% 100%, 0% 50%);
}
object-fit: Use object-fit: cover on images to ensure they fill the clipped shape without distortion.
Animated Clip Path
Animate clip-path to create shape morphing, reveal effects, and dynamic transitions. Both shapes must have the same number of points for smooth morphing.
/* Shape morphing animation */
@keyframes morph {
0%, 100% {
clip-path: circle(50%);
}
25% {
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
}
50% {
clip-path: polygon(25% 0%, 75% 0%, 100% 50%,
75% 100%, 25% 100%, 0% 50%);
}
75% {
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
}
.morphing-element {
animation: morph 4s ease-in-out infinite;
}
/* Text reveal effect */
@keyframes reveal {
from {
clip-path: polygon(0 0, 0 0, 0 100%, 0 100%);
}
to {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
}
.reveal-text {
animation: reveal 2s ease forwards;
}
/* Diagonal wipe */
@keyframes wipe {
from {
clip-path: polygon(0 0, 0 0, 0 100%);
}
to {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
}
/* Circle expand */
@keyframes expand {
from {
clip-path: circle(0%);
}
to {
clip-path: circle(100%);
}
}
/* Split reveal */
@keyframes split-reveal {
from {
clip-path: polygon(0 50%, 50% 50%, 50% 50%, 50% 50%,
50% 50%, 50% 50%, 100% 50%, 100% 50%);
}
to {
clip-path: polygon(0 0, 50% 0, 50% 0, 50% 50%,
50% 50%, 50% 100%, 100% 100%, 100% 0);
}
}
Matching Point Counts: For smooth polygon morphing, both shapes must have identical numbers of points. Add invisible intermediate points if needed to match counts.
Interactive Hover Effects
Combine clip-path with transitions for smooth, engaging hover effects. Shape transformations create unique interactions.
/* Circle expansion on hover */
.card {
clip-path: circle(50%);
transition: clip-path 0.5s ease;
}
.card:hover {
clip-path: circle(70%);
}
/* Square to diamond */
.box {
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
transition: clip-path 0.5s ease;
}
.box:hover {
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
}
/* Hexagon to star */
.shape {
clip-path: polygon(25% 0%, 75% 0%, 100% 50%,
75% 100%, 25% 100%, 0% 50%);
transition: clip-path 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.shape:hover {
clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%,
79% 91%, 50% 70%, 21% 91%, 32% 57%,
2% 35%, 39% 35%);
}
/* Image zoom with shape change */
.image-container {
clip-path: circle(50%);
transition: clip-path 0.4s ease, transform 0.4s ease;
}
.image-container:hover {
clip-path: circle(55%);
transform: scale(1.05);
}
/* Reveal on hover */
.reveal-hover {
clip-path: polygon(0 0, 0 0, 0 100%, 0 100%);
transition: clip-path 0.6s ease;
}
.reveal-hover:hover {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
Performance: clip-path transitions are GPU-accelerated and perform well. Use will-change: clip-path for complex animations to optimize further.
Key Takeaways
Four main functions: circle(), ellipse(), polygon(), inset()
circle(radius at x y): Perfect circles; 50% radius for centered circle
ellipse(rx ry at x y): Ovals with independent horizontal/vertical radii
polygon(x1 y1, x2 y2, ...): Custom shapes by connecting points
inset(top right bottom left round radius): Rectangular clipping with optional rounding
Coordinate system: 0% 0% = top-left, 100% 100% = bottom-right, 50% 50% = center
Polygon points: List clockwise for best results; any number of points supported
Non-destructive: Only affects visibility, not layout or element size
Animatable: Smooth transitions between shapes; requires matching point counts
Image clipping: Combine with object-fit: cover for shaped images
Hover effects: Use transition: clip-path 0.5s for smooth shape changes
Performance: GPU-accelerated; use will-change for complex animations
Online tools like Clippy (bennettfeely.com/clippy/) help visualize and generate clip-path values