Responsive SVG Clipping Mask on Image

Hey everyone,

I recently struggled with an issue, which I found a lot of you have in common: How to clip an image with a custom svg shape in webflow? It is easy and well documented with text though, but it really bothered me to find a propper solution for svg shapes. Therefore, I tried for myself (even if i’m not a developer) and after a few hours of research, try and error I came up with this:

https://share.getcloudapp.com/bLug6BEo

It is really a svg shape, not only an png image. :hugs:
And here is how I built it:

1. First I created the shape in sketch, and export it as an SVG (no filling, no stroke attached. Just disable the filling, after you finished your shape)

2. Open your SVG with TextEdit on your Mac, to see the SVG-Code. In my example I had this:

    <?xml version="1.0" encoding="UTF-8"?>
<svg width="1970px" height="1480px" viewBox="0 0 1970 1480" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>home-mask</title>
    <g id="Assets" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <path d="M1571.04568,-92.679823 C2009.5503,-55.9798063 2048.66877,482.070131 1745.45071,1095.19191 C1442.23264,1708.31369 702.346791,1824.66598 361.646219,1328.41801 C83.5773885,923.397557 177.946731,721.798912 408.635909,427.881013 C639.325087,133.963114 781.062304,277.431632 1022.16146,144.837655 C1263.26062,12.2436786 1348.30953,-111.321406 1571.04568,-92.679823 Z" id="Path" transform="translate(1066.464217, 771.768991) rotate(-138.000000) translate(-1066.464217, -771.768991) "></path>
    </g>
</svg>

**3. In Webflow drag and drop the image element from your media section on your canvas. Give it a class. In my example it has the class clipping-mask.

4. The next step is, to copy your SVG Code and to place it inside the head-section from your custom code panel. We don’t need the whole thing, just these lines will do. Than wrap your shape in a clipPath element and wrap the clipPath in a defs block, to tell the browser that you want to use your SVG as a clipping-mask and give it an ID:

EDIT: Please be sure to set the svg width and hight to “0”, otherwise you got some weird positioning issues.

6. Below that you need a style-tag to tell your image (in my case clipping-mask) to apply the shape from #mask and that you want to cover the image inside the shape with a total width of 100%:

<style>
	.clipping-mask {
  	-webkit-clip-path: url(#mask);
    clip-path: url(#mask);
    object-fit: cover;
    width: 100%;
    }
</style>

Now, if you save and publish your site, you should already see your image inside your svg shape. (This won’t work in preview mode, you need to publish your site)

But as you can see, the svg isn’t responsive yet. Let’s do the last step:

7. We need to ad clipPathUnits=“objectBoundingBox” and transform=“scale()” to our clipPath-tag. The formula for the width an hight is:

1 / [your SVG width]
1 / [your SVG height]

In my example:
1 / 1970 = 0.000507614213198
1 / 1480 = 0.000675675675676

Safe and publish again. Now your SVG clipping mask should be also responsive :slight_smile:

Here is the final code:

<svg width="0" 
	height="0" 
    viewBox="0 0 1970 1480"  
    xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <g id="Assets" fill="none">
    		<defs>
    		<clipPath id="mask" clipPathUnits="objectBoundingBox" transform="scale(0.000507614213198, 0.000675675675676)">
        <path d="M1675.36269,-364.434932 C2113.86732,-327.734916 2152.98578,210.315022 1849.76772,823.436801 C1786.44006,951.488441 1704.06533,1057.87144 1610.25811,1141.53058 C1471.01269,1265.71242 1015.73754,1678.13346 1015.73754,1678.13346 C1015.73754,1678.13346 693.522403,1317.51047 531.111878,1139.05814 C508.090096,1113.76242 486.314497,1086.30557 465.963232,1056.6629 C187.894401,651.642448 282.263744,450.043803 512.952922,156.125904 C743.642099,-137.791995 885.379317,5.67652257 1126.47847,-126.917454 C1367.57763,-259.511431 1452.62654,-383.076516 1675.36269,-364.434932 Z" id="Path" transform="translate(1170.781230, 655.913211) rotate(-138.000000) translate(-1170.781230, -655.913211) "></path>
        </clipPath>
        </defs>
    </g>
</svg>

<style>
	.clipping-mask {
  	-webkit-clip-path: url(#mask);
    clip-path: url(#mask);
    object-fit: cover;
    width: 100%;
    }
</style>

Here is my read-only link:
https://preview.webflow.com/preview/responsive-svg-clipping-mask-on-image?utm_medium=preview_link&utm_source=designer&utm_content=responsive-svg-clipping-mask-on-image&preview=7c2442b0d3beef18c132a1668cb18307&mode=preview

Live-Preview:
https://responsive-svg-clipping-mask-on-image.webflow.io/

I hope this solution works for you too! :relaxed:

Nadine

12 Likes

Thanks for the tips !
:metal:

Thanks, @youngandhyperactive - this is great and the detail is just perfect! :blush:

That little bit about transform scale is something I never knew! Thank you!

This is great, tricky to position perfectly, I was wondering if anyone has figured out how to add a stroke to this svg shape? Cant seem to get it to show up

Hello,

I can’t figure out why the shape is off for me. Can someone take a look at it?

As you can see, the left border of the clipped image is not like the svg below. The path is exactly the same. Why is this happening?

Read-only: https://preview.webflow.com/preview/zoldterv?utm_medium=preview_link&utm_source=designer&utm_content=zoldterv&preview=2e7d0472838bfbd22ae9f5e6aaeec271&pageId=61b72d219f25d82589b922a8&workflow=preview

Thanks!

Not gonna lie: this all seems like a very complicated way to mask images—especially for someone like me that uses Webflow to get away from custom code as much as possible. Seems to me just making an inverse SVG of the shape desired is much easier. Here’s what I just made, and even added animation affects of scale and a decreased opacity of the insides of the logo: Logo Animation

2 Likes

Hi Michael,
I was also puzzled with the stroke and I got help with the code which works nicely, but I just found out that the whole SVG thingy doesnt work in the EDITOR at all, it shows me empty space :confused: any idea?

https://preview.webflow.com/preview/svg-mask-stroke?utm_medium=preview_link&utm_source=dashboard&utm_content=svg-mask-stroke&preview=a12a268d26695a8e99f20486189f73e0&workflow=preview

This was so helpful! Very elegant solution.

Hey, thanks for posting this. I got it to work well on chrome but it’s gone strange on safari. Any particular reason you know of? Here’s an image of the two browsers

Chrome

Safari

To do this, you need to go to the designer and add the original that you exported with the same as your clip path, except this time adding the stroke and stroke-width to it.

In the designer you would make something similar to:
->.img-wrapper (position: relative) you can also define width: 360px
—>.img (width:100%)
—>.path-svg-stroke {
position: absolute;
left: 0%;
top: 0%;
right: 0%;
bottom: 0%;
} (this is a webflow embed element)
Now copy and paste the SVG you exported from illustrator,figma,etc. Make sure to include stroke and stroke-width.



Hope this helps.