clip-path is a very interesting property that allows to clip the visible portion of SVG elements, images or any HTML element really.
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 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%);
}
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%);
}
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 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%);
}
}
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);
}
clip-path
has 95% coverage in browsers worldwide, but be sure to include the -webkit-clip-path
prefixed variants, which are still required by Safari.Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
What a good tutorial! SVG is an amazing topic