CSS Clip-Path Tutorial
Master the art of clipping elements to create stunning visual effects and unique shapes with CSS
What is CSS Clip-Path?
The CSS clip-path
property creates a clipping region that determines which parts of an element are visible. Parts inside the region are shown, while parts outside are hidden. This powerful property allows you to create complex shapes and visual effects that were previously only possible with images or SVG.
Key Benefits:
- Create non-rectangular layouts and elements
- Add visual interest without additional images
- Improve performance compared to image-based solutions
- Animate between different shapes for engaging effects
- Combine with other CSS properties for unique designs
How Clip-Path Works:
Think of clip-path as a cookie cutter that you press into an element. The cookie cutter defines the visible area, and everything outside that area becomes transparent. Unlike the deprecated clip property, clip-path can handle complex shapes and offers more flexibility.
Understanding Clip-Path Coordinate Systems
Coordinate Systems
Clip-path uses different coordinate systems depending on the function:
- Percentage values: Relative to the element's dimensions
- Length values: Fixed pixel or other unit measurements
- Position values: For circle and ellipse functions
- SVG coordinates: When using SVG clipPath elements
Browser Rendering
How browsers process clip-path:
- The clipping region is calculated
- Only the visible portion is rendered
- The rest becomes transparent
- Mouse events only work on visible areas
- Can affect performance with complex shapes
Clip-Path Functions Explained
1. Basic Shape Functions
circle()
Creates a circular clipping region. Syntax: circle(radius at position)
ellipse()
Creates an elliptical clipping region. Syntax: ellipse(rx ry at position)
inset()
Creates a rectangular clipping region inset from the element's edges. Syntax: inset(top right bottom left round border-radius)
polygon()
Creates a polygonal clipping region defined by multiple points. Syntax: polygon(x1 y1, x2 y2, ...)
2. SVG Clip Paths
For more complex shapes, you can define clip paths using SVG and reference them in CSS. This approach offers the most flexibility but requires more setup.
Practical Applications of Clip-Path
1. Creative Layouts
Break away from traditional rectangular designs with creative clipping:
- Diagonal section dividers
- Non-rectangular image galleries
- Unique card designs with angled edges
- Custom-shaped navigation elements
2. Visual Effects
Enhance your designs with visually interesting effects:
- Reveal animations by transitioning clip paths
- Create custom-shaped image masks
- Design unique hover effects
- Implement creative loading animations
3. Responsive Design
Clip-path works well with responsive design principles:
- Use percentage-based values for fluid shapes
- Combine with media queries for adaptive designs
- Create shapes that scale with container size
- Maintain aspect ratios for consistent appearance
Performance Considerations
Potential Performance Issues
- Complex polygon shapes with many points
- Animating clip-path on many elements simultaneously
- Using SVG clip paths with complex paths
- Applying to large elements or many elements
- Older browsers may have performance limitations
Optimization Tips
- Use simpler shapes when possible
- Limit the number of points in polygons
- Consider using will-change for animations
- Test performance on target devices
- Provide fallbacks for older browsers
Browser Support & Compatibility
Current Support Status
CSS clip-path is well-supported in modern browsers, but there are some considerations:
- Basic shape functions supported in Chrome 55+, Firefox 54+, Safari 12.1+, Edge 79+
- SVG clip paths have broader support but different syntax
- Some older browsers require vendor prefixes (-webkit-clip-path)
- Internet Explorer has very limited support
- Always test on your target browsers and devices
Progressive Enhancement Strategy:
For critical design elements, consider providing fallbacks for browsers that don't support clip-path. You can use feature detection with @supports to provide alternative styling.
CSS Clip-Path Implementation
Complete Example Code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CSS Clip-Path Tutorial</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } :root { --primary-color: #6a11cb; --secondary-color: #2575fc; --accent-color: #ff416c; --dark-color: #2c3e50; --light-color: #f8f9fa; --text-color: #333; --text-light: #fff; --spacing-sm: 0.5rem; --spacing-md: 1rem; --spacing-lg: 1.5rem; --spacing-xl: 2rem; --border-radius: 0.5rem; --font-main: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; --font-heading: 'Montserrat', sans-serif; } body { font-family: var(--font-main); line-height: 1.6; color: var(--text-color); background: linear-gradient(135deg, var(--light-color) 0%, #eef2f5 100%); padding: var(--spacing-md); min-height: 100vh; } .container { max-width: 1200px; margin: 0 auto; } header { text-align: center; margin-bottom: var(--spacing-xl); padding: var(--spacing-lg); background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: var(--text-light); border-radius: var(--border-radius); box-shadow: 0 4px 15px rgba(0,0,0,0.1); } h1 { font-family: var(--font-heading); font-size: clamp(1.8rem, 5vw, 3rem); margin-bottom: var(--spacing-sm); } h2 { font-family: var(--font-heading); font-size: clamp(1.4rem, 4vw, 2rem); margin: var(--spacing-lg) 0 var(--spacing-md); color: var(--dark-color); padding-bottom: var(--spacing-sm); border-bottom: 2px solid var(--primary-color); } .example { background: white; border-radius: var(--border-radius); padding: var(--spacing-lg); margin-bottom: var(--spacing-lg); box-shadow: 0 5px 15px rgba(0,0,0,0.08); } .demo { border: 2px solid #e9ecef; border-radius: var(--border-radius); padding: var(--spacing-lg); margin: var(--spacing-md) 0; background: #f8f9fa; } .clip-container { display: flex; flex-wrap: wrap; gap: var(--spacing-md); justify-content: center; } .clip-item { width: 150px; height: 150px; border-radius: var(--border-radius); overflow: hidden; position: relative; box-shadow: 0 4px 8px rgba(0,0,0,0.1); background: linear-gradient(45deg, var(--primary-color), var(--secondary-color)); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; } .clip-label { position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.7); color: white; padding: 0.3rem; text-align: center; font-size: 0.8rem; } .code-block { background: #2d2d2d; color: #f8f8f2; padding: var(--spacing-md); border-radius: var(--border-radius); overflow-x: auto; margin: var(--spacing-md) 0; font-family: 'Consolas', 'Monaco', monospace; font-size: 0.875rem; } .btn { display: inline-block; padding: var(--spacing-sm) var(--spacing-md); background: var(--primary-color); color: var(--text-light); border: none; border-radius: var(--border-radius); cursor: pointer; font-size: 0.875rem; margin-right: var(--spacing-sm); transition: all 0.3s ease; } .btn:hover { background: #5a0fb5; transform: translateY(-2px); } .btn-copy { background: var(--secondary-color); } .btn-copy:hover { background: #1c67e3; } /* Basic shapes */ .circle-clip { clip-path: circle(50% at center); } .ellipse-clip { clip-path: ellipse(40% 50% at 50% 50%); } .inset-clip { clip-path: inset(20% 10% 15% 30%); } .polygon-clip { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); } /* Advanced examples */ .star-clip { clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); } .talk-bubble { clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%); } .heart-clip { clip-path: polygon(50% 0%, 100% 35%, 100% 70%, 50% 100%, 0% 70%, 0% 35%); } .infinity-clip { clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%); } /* Animation examples */ .animated-clip { animation: clipAnimation 4s infinite alternate; } @keyframes clipAnimation { 0% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); } 50% { clip-path: polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%); } 100% { clip-path: polygon(0% 0%, 75% 0%, 100% 100%, 25% 100%); } } /* Image clipping */ .image-clip { width: 200px; height: 200px; background: url('https://images.unsplash.com/photo-1506744038136-46273834b3fb'); background-size: cover; } .image-heart { clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 50% 75%, 18% 100%, 0% 38%); } .image-circle { clip-path: circle(40% at center); } .image-polygon { clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%); } /* Practical examples */ .card-clip { width: 250px; height: 150px; background: linear-gradient(45deg, var(--primary-color), var(--secondary-color)); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; clip-path: polygon(0 0, 100% 0, 100% 70%, 90% 100%, 0 100%); } .ribbon-clip { width: 200px; height: 50px; background: var(--accent-color); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; clip-path: polygon(0 0, 95% 0, 100% 50%, 95% 100%, 0 100%); } /* SVG clip paths */ .svg-clip-container { width: 200px; height: 200px; } .svg-clip-path { clip-path: url(#customClip); } </style> </head> <body> <div class="container"> <header> <h1>CSS Clip-Path Tutorial</h1> <p>Create stunning visual effects by clipping elements with CSS</p> </header> <section class="example"> <h2>1. Basic Shape Functions</h2> <p>CSS provides several basic shape functions for clipping elements.</p> <div class="demo"> <div class="clip-container"> <div class="clip-item circle-clip"> Circle <div class="clip-label">circle()</div> </div> <div class="clip-item ellipse-clip"> Ellipse <div class="clip-label">ellipse()</div> </div> <div class="clip-item inset-clip"> Inset <div class="clip-label">inset()</div> </div> <div class="clip-item polygon-clip"> Polygon <div class="clip-label">polygon()</div> </div> </div> </div> <div class="code-block"> .circle-clip { clip-path: circle(50% at center); } .ellipse-clip { clip-path: ellipse(40% 50% at 50% 50%); } .inset-clip { clip-path: inset(20% 10% 15% 30%); } .polygon-clip { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); } </div> </section> <section class="example"> <h2>2. Advanced Shapes</h2> <p>Create complex shapes using the polygon() function with multiple coordinate points.</p> <div class="demo"> <div class="clip-container"> <div class="clip-item star-clip"> Star <div class="clip-label">polygon()</div> </div> <div class="clip-item talk-bubble"> Talk Bubble <div class="clip-label">polygon()</div> </div> <div class="clip-item heart-clip"> Heart <div class="clip-label">polygon()</div> </div> <div class="clip-item infinity-clip"> Infinity <div class="clip-label">polygon()</div> </div> </div> </div> <div class="code-block"> .star-clip { clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); } .talk-bubble { clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%); } .heart-clip { clip-path: polygon(50% 0%, 100% 35%, 100% 70%, 50% 100%, 0% 70%, 0% 35%); } .infinity-clip { clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%); } </div> </section> <section class="example"> <h2>3. Image Clipping</h2> <p>Apply clip-path to images for creative visual effects.</p> <div class="demo"> <div class="clip-container"> <div class="clip-item image-clip image-heart"> <div class="clip-label">Heart Shape</div> </div> <div class="clip-item image-clip image-circle"> <div class="clip-label">Circle</div> </div> <div class="clip-item image-clip image-polygon"> <div class="clip-label">Octagon</div> </div> </div> </div> <div class="code-block"> .image-heart { clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 50% 75%, 18% 100%, 0% 38%); } .image-circle { clip-path: circle(40% at center); } .image-polygon { clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%); } </div> </section> <section class="example"> <h2>4. Animated Clip-Paths</h2> <p>Create smooth animations by transitioning between different clip-path shapes.</p> <div class="demo"> <div class="clip-container"> <div class="clip-item animated-clip"> Animated <div class="clip-label">CSS Animation</div> </div> </div> </div> <div class="code-block"> .animated-clip { animation: clipAnimation 4s infinite alternate; } @keyframes clipAnimation { 0% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); } 50% { clip-path: polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%); } 100% { clip-path: polygon(0% 0%, 75% 0%, 100% 100%, 25% 100%); } } </div> </section> <section class="example"> <h2>5. Practical Applications</h2> <p>Use clip-path in real-world UI components and designs.</p> <div class="demo"> <div class="clip-container"> <div class="card-clip"> Featured Card </div> <div class="ribbon-clip"> Sale 50% Off </div> </div> </div> <div class="code-block"> .card-clip { clip-path: polygon(0 0, 100% 0, 100% 70%, 90% 100%, 0 100%); } .ribbon-clip { clip-path: polygon(0 0, 95% 0, 100% 50%, 95% 100%, 0 100%); } </div> </section> <section class="example"> <h2>6. SVG Clip Paths</h2> <p>Use SVG-defined clip paths for even more complex shapes.</p> <div class="demo"> <div class="clip-container"> <svg width="0" height="0" viewBox="0 0 100 100"> <defs> <clipPath id="customClip" clipPathUnits="objectBoundingBox"> <path d="M0.5,0 C0.7,0,0.8,0.2,0.8,0.4 C0.8,0.6,0.9,0.8,0.7,0.8 C0.5,0.8,0.3,1,0.5,1 C0.7,1,0.9,0.8,0.9,0.6 C0.9,0.4,1,0.2,0.8,0.2 C0.6,0.2,0.4,0,0.5,0 Z" /> </clipPath> </defs> </svg> <div class="clip-item svg-clip-path svg-clip-container"> SVG Path <div class="clip-label">SVG clipPath</div> </div> </div> </div> <div class="code-block"> <svg width="0" height="0" viewBox="0 0 100 100"> <defs> <clipPath id="customClip" clipPathUnits="objectBoundingBox"> <path d="M0.5,0 C0.7,0,0.8,0.2,0.8,0.4 C0.8,0.6,0.9,0.8,0.7,0.8 C0.5,0.8,0.3,1,0.5,1 C0.7,1,0.9,0.8,0.9,0.6 C0.9,0.4,1,0.2,0.8,0.2 C0.6,0.2,0.4,0,0.5,0 Z" /> </clipPath> </defs> </svg> .svg-clip-path { clip-path: url(#customClip); } </div> </section> </div> </body> </html>
Clip-Path Best Practices
Do's
- Use percentage values for responsive designs
- Experiment with different shape functions
- Combine with transitions for smooth animations
- Test across different browsers and devices
- Use SVG for complex, reusable clip paths
Don'ts
- Don't overuse complex shapes that impact performance
- Avoid too many points in polygon functions
- Don't rely solely on clip-path for critical content
- Avoid using for large numbers of elements
- Don't forget to provide fallbacks for older browsers
Ready to Experiment with CSS Clip-Path?
Try these CSS clip-path examples in our interactive editor. Create your own shapes, experiment with different functions, and see how you can transform ordinary elements into visually striking components.