While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

Introduction

clip-path is a very interesting property that allows to clip the visible portion of SVG elements, images or any HTML element really.

Defining Basic Shapes With clip-path

clip-path makes it easy to clip-out basic shapes using either of the polygon, ellipse, circle or inset keywords, which are part of the CSS exclusion module.

Polygon

Polygon is the most flexible of all the available shapes because it allows you to specify any amount of points, a little bit like an SVG path. The provided points are pairs of X and Y coordinates that can be of any unit (eg: pixel or percent-based). Because it’s the most flexible, it’s also the most complex and you’ll probably want to use a tool to define your points.

Let’s illustrate with an example. First you’ll see our starting image, then our image with a clip-path applied to get a triangle shape, followed by a more complex X-shape, and then finally a star shape:

/* Triangle */ .polygon1 { -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%); clip-path: polygon(50% 0%, 0% 100%, 100% 100%); } /* X */ .polygon2 { -webkit-clip-path: polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%); clip-path: polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%); } /* Star */ .polygon3 { -webkit-clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }

Circle

Circles are defined with this syntax: circle(radius at posX posY). The position is optional and will default to 50% 50%. Here are two examples to illustrate:

.circle { -webkit-clip-path: circle(50%); clip-path: circle(50%); } .circle2 { -webkit-clip-path: circle(70% at 70% 20%); clip-path: circle(70% at 70% 20%); }

Ellipse

Ellipses are defined using this syntax: ellipse(radiusX radiusY at posX posY). Once again, the position is optional and will default to 50% 50%. Here are two examples:

.ellipse { -webkit-clip-path: ellipse(50% 35%); clip-path: ellipse(50% 35%); } .ellipse2 { -webkit-clip-path: ellipse(50% 65% at 70% 50%); clip-path: ellipse(50% 65% at 70% 50%); }

With inset you can define an inner rectangle and everything outside will be cut-out. This makes it easy to effectively crop an image or an element directly in the browser. You can also make the rectangle rounded with the round keyword and a border radius value:

.inset { -webkit-clip-path: inset(20% 25% 20% 10%); clip-path: inset(20% 25% 20% 10%); } .inset2 { -webkit-clip-path: inset(45% 0% 33% 10% round 10px); clip-path: inset(45% 0% 33% 10% round 10px); }

Animations and Transitions

Animations and transitions can also be applied with clip-path to create interesting effects. Just make sure that all the steps in your animation contains the same amount of points. Let’s demonstrate with an example:

Here’s the CSS rules used to create this animation:

.trigger-btn:hover + img { animation: magic 4s infinite; } @keyframes magic { 0% { -webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); } 20% { -webkit-clip-path: polygon(28% 0, 73% 0, 100% 100%, 0% 100%); clip-path: polygon(28% 0, 73% 0, 100% 100%, 0% 100%); } 40% { -webkit-clip-path: polygon(0 0, 100% 72%, 100% 100%, 0 35%); clip-path: polygon(0 0, 100% 72%, 100% 100%, 0 35%); } 60% { -webkit-clip-path: polygon(50% 0, 50% 0, 100% 100%, 0% 100%); clip-path: polygon(50% 0, 50% 0, 100% 100%, 0% 100%); } 80% { -webkit-clip-path: polygon(0 70%, 100% 0, 100% 32%, 0 100%); clip-path: polygon(0 70%, 100% 0, 100% 32%, 0 100%); } 100% { -webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); } }

Custom SVG Shapes

You can also define any arbitrary SVG shape to act as the clip-path value. You’ll obviously want to start in a tool like Sketch to create your shape and then copy the SVG markup into a text editor. In your SVG markup, simply wrap your shape in a clipPath element and wrap the clipPath in a defs block.

Something like this for example:

<svg width="0" height="0"> <defs> <clipPath id="my-shape"> <path d="M89.6342913,129 C86.6318679,137.611315 85,146.865086 85,156.5 C85,200.767808 119.448105,236.989829 163,239.821749 L163,300 L300,300 L300,163 L251.750745,163 C251.915896,160.855015 252,158.687329 252,156.5 C252,110.384223 214.615777,73 168.5,73 C146.712501,73 126.873981,81.3445721 112.006052,95.0121046 L64.5,0 L0,129 L89.6342881,129 Z"> </path> </clipPath> </defs> </svg>

And now you can apply the defined shape as the clip-path value using the url keyword and the id of the SVG shape:

.svg-shape { -webkit-clip-path: url(#my-shape); clip-path: url(#my-shape); }

Additional Resources