Clipping masks are a great way to make rectangles less boring. They're easy to create in design tools like Sketch but a little more tricky to use in CSS. In this article I explain an easy way of achieving it. Here is one in action.
This technique fits well with more organic designs. You can use it to clip full width elements like a hero or a footer, but also images or to to make a modal a little boring. I've used them a lot on nieuw-allardsoog.nl.
The first thing we need is an SVG. I drew up a simple shape in Sketch and exported it. However there is one important step: set the width and the height of the vector shape to 1. Export the svg, minify it. We only need the path
and it should look something like this.
1<path d="M1,0.957354558 L0.999934191,0.0357375784 L0.811941317,0.00893439459 C0.784541966,0.00595626306 0.759109013,0.00372266441 0.735642457,0.00223359865 L0.630577366,0.00122742984 L0.408197713,0.0122742984 L0.069513569,0.0196589929 C0.0486866486,0.0206885563 0.0255515086,0.0219755105 0.000108149156,0.0235198555 L0,0.994004352 L0.367864746,1 L0.672319698,0.994004352 L0.855668573,0.982384564 C0.905167808,0.977835717 0.943049987,0.972611285 0.969315109,0.96671127 L1,0.957354558 Z"></path>
A minified SVG path.
Note that we don't need any attributes like fill
here. Ditch it all and keep the snippet small.
The next thing we need to do is wrap it in an svg
tag and setup a clipPath
.
1<svg width="0" height="0" >2 <clipPath id="mask" clipPathUnits="objectBoundingBox">3 <path d="M1,0.957354558 L0.999934191,0.0357375784 L0.811941317,0.00893439459 C0.784541966,0.00595626306 0.759109013,0.00372266441 0.735642457,0.00223359865 L0.630577366,0.00122742984 L0.408197713,0.0122742984 L0.069513569,0.0196589929 C0.0486866486,0.0206885563 0.0255515086,0.0219755105 0.000108149156,0.0235198555 L0,0.994004352 L0.367864746,1 L0.672319698,0.994004352 L0.855668573,0.982384564 C0.905167808,0.977835717 0.943049987,0.972611285 0.969315109,0.96671127 L1,0.957354558 Z"></path>4 </clipPath>5</svg>
The path in an SVG tag with a clipPath.
Note that the width
and the height
of the SVG is set to 0 as we don't actually want to render this SVG as is. We only want to reference it to clip another part of the page. An image in our case. The clipPathUnits
is set to objectBoundingBox
to make sure that all coördinates within the clipPath
are relative to the bounding box. This way the mask will cover the element we're gonna clip. This is also the reason we need the actual vector shape to have a maximum width and height of 1.
Since we gave the SVG an id
we can add a bit of inline CSS to create a class with the clip-path
property.
1<style>2 .mask { clip-path: url(#mask); }3</style>
Reference the mask in CSS.
Now we can add the mask class to anything we want to clip.
1<div class="py-8 flex items-center"> 2 <div class="mask w-full aspect-[3/1]"> 3 <img class="w-full h-full object-cover" src="https://images.unsplash.com/photo-1441974231531-c6227db76b6e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2071&q=80"> 4 </div> 5 <style> 6 .mask { clip-path: url(#mask); } 7 </style> 8 <svg width="0" height="0" > 9 <clipPath id="mask" clipPathUnits="objectBoundingBox">10 <path d="M1,0.957354558 L0.999934191,0.0357375784 L0.811941317,0.00893439459 C0.784541966,0.00595626306 0.759109013,0.00372266441 0.735642457,0.00223359865 L0.630577366,0.00122742984 L0.408197713,0.0122742984 L0.069513569,0.0196589929 C0.0486866486,0.0206885563 0.0255515086,0.0219755105 0.000108149156,0.0235198555 L0,0.994004352 L0.367864746,1 L0.672319698,0.994004352 L0.855668573,0.982384564 C0.905167808,0.977835717 0.943049987,0.972611285 0.969315109,0.96671127 L1,0.957354558 Z"></path>11 </clipPath>12 </svg>13</div>
The final code. An image clipped with an SVG clipping path.
Did you like this article or do you have any questions? Please reach out.