SVG Clipping Paths

Last year I published several series (25 posts in total) on the subject of SVG. First was a series on the basics of creating SVG shapes, lines, and curves and adding fill colors and strokes to them. I followed that series with another with more intermediate topics such as reusing SVG code and using patterns and gradients to fill SVG graphics. I closed the year with a series on SVG Text.

As you can probably guess, I’m not done talking about SVG. I have a few series planned throughout the year and maybe into next year starting today with a series of posts about clipping paths. I’ll follow the clipping path posts with a similar set of posts about masking with SVG.

Both SVG and CSS have ways to create clipping paths. however CSS support is still somewhere limited. No Microsoft browser currently supports the CSS clip-path property. Neither does Opera Mini. Everything else offers partial support. The good news is, all browsers support SVG in general and clipping in particular.

Clipping and Masking

Let me start by saying a couple of things about the difference between clipping and masking as they’re conceptually similar. Both are used to visually hide and show parts of an element or image.

Clipping paths define a hard boundary between what’s visible and what isn’t. Anything inside the clipping path is visible. Anything outside is hidden.

Masks, on the other hand, cover all or part of an element and control how much of the element shows through. 100% of the element might show through one pixel of the mask, while 0%, 50%, or 29% might show through a different pixel. Masks can actually behave exactly like clipping paths, but I’ll save that until we talk about masks in a few weeks.

Simple Example

The easiest way to understand clipping paths is to see them in action so let’s jump into a simple example.

Here I created an SVG with a viewport of 660px by 220px to which I added a red outline so we can see its boundaries. Inside the viewport I created a circle with a radius of 100px (r=“100”). I set the center of the circle to be located 110px from the top and left edges of the viewport (cx=“110” cy=“110”).

1
2
3
<svg width="660" height="220" style="outline: 1px solid red">  
 <circle cx="110" cy="110" r="100" fill="#9c6" />  
</svg>

I changed the fill from the default black to #9c9, which should be a desaturated green. I haven’t added a clipping path yet. This is the before so you have a frame of reference for when the circle is clipped.

Now for the after. Let’s clip the circle so only its top half is visible.

To add a clipping path you define the path using the SVG clipPath element and then you reference the clipPath by adding a clip-path property to the element or group of elements to be clipped.

Here I added a clipPath element between <defs> tags and gave it the highly original id of “clip–1.” Inside the clipPath element, I created a 200px by 100px rectangle located 10px from the top and 10px from the left edge of the viewport.

1
2
3
4
5
6
7
8
9
10
11
<svg width="660" height="220" style="outline: 1px solid red">

 <defs>  
   <clipPath id="clip-1">  
     <rect x="10" y="10" width="200" height="100" />  
   </clipPath>  
 </defs>

 <circle cx="110" cy="110" r="100" fill="#9c6" clip-path="url(#clip-1)" />

</svg>

The circle references the clipPath using the clip-path property.

1
clip-path="url(#clip-1)"

Note the form. The value of clip-path will be url() with a reference to the clipPath you want to use inside the parenthesis.

Here’s the result. The extra blue rectangle is something I added here to show the clipping path boundaries as the clipping path itself is never displayed.

As you can see anything inside the clipping path remains visible and anything outside the clipping path is hidden.

In the example I used a rectangle to create a simple clipping path, but you aren’t limited to rectangles. You can use any of the basic SVG shapes to create clipping paths. You can also use text as the path and you can create your own paths using the <path> element. You can even combine all three to create some unique clipping paths. I’ll show examples of all of these later in the series.

CSS Clipping Paths

Since I did mention CSS clipping paths, let me quickly show you how to use them. Remember this won’t work in every browser so I suggest sticking with SVG for now, but once support is there my guess is we’ll use the CSS method more.

In CSS you’ll use the CSS clip-path property, as opposed to the SVG property of the same name, to either reference an SVG clipping path or to create the path using one of the allowed CSS shapes, polygon(), circle(), inset(), and ellipse().

Here’s an example using inline CSS to reference a clipPath created in SVG.

1
2
3
4
5
6
7
8
9
<svg width="660" height="220" style="outline: 1px solid red">  
 <defs>  
   <clipPath id="clip-2">  
     <rect x="10" y="10" width="200" height="100" />  
   </clipPath>  
 </defs>

 <circle cx="110" cy="110" r="100" fill="#9c6" style="clip-path:url(#clip-2)" />  
</svg>

It looks very much like the SVG example. In fact there’s only one small change. Instead of adding the SVG clip-path property to the circle, I added the CSS clip-path property inline.

This example includes style="clip-path:url(#clip-2)" where the previous one included clip-path="url(#clip-1)". Not much of a difference and you might not even notice any difference with a quick glance.

Depending on what browser you’re currently using, you may or may not be seeing the correct result. The examples should both look like the previous one where the bottom half of the circle is hidden. Here’s an image just in case.

Clipping in CSS

In this next example I used the CSS clip-path property to directly create and apply the path as opposed to referencing the id of a path defined elsewhere.

1
2
3
<svg width="660" height="220" style="outline: 1px solid red">  
 <circle cx="110" cy="110" r="100" fill="#9c6" style="clip-path: polygon(0px 0px, 200px 0px, 200px 100px, 0px 100px);" />  
</svg>

Instead of referencing a clipPath, I created the clipping path using a polygon that takes the coordinates of the circle as its own coordinate space, which is why the initial coordinate is 0px 0px instead of 10px 10px.

Note that Firefox doesn’t support this method of adding the path directly. Firefox only supports referencing the id of a clipping path. If you’re viewing this in Firefox near the time I’ve published this post, you’ll see the full unclipped circle instead of the half circle from the last few examples.

Hopefully you agree the SVG method and the CSS method aren’t all that different. CSS allows you to create and apply the clipping path in one place, but it’s slightly more limited in what you can use to create the path.

Closing Thoughts

Let’s leave things here for today. I think you’ll agree that working with clipping paths in SVG isn’t too hard. If you know how to create basic SVG shapes and understand how to define something in one place and reference it in another, much of what’s here likely looks familiar.

In the future, I expect we’ll do more clipping in CSS, but for now browser support isn’t there and SVG is the better option until that changes. I don’t expect it will be a difficult transition. If you understand how to create a clipping path using SVG, it should be easy enough to make the change to CSS when the time is right.

For the remainder of this series, I’ll stick to SVG clipping paths where you define the path in one place using the clipPath element and then reference the id of the clipPath using the SVG clip-path property on the element you want to clip.

Next week I want to continue with SVG clipping paths. There are a few more details to talk about. In the weeks after I’ll offer some examples so you can see clipping is more than rectangles hiding circles.

Download a free sample from my book, Design Fundamentals.

6 comments

  1. On IE11, under “difference with a quick glance”, I see a clipped circle. Under “the half circle from the last few examples.”, I see the full circle. And canIuse.com backs up your statements about a total lack of IE support. Yet here we are. The Internet, so crazy.

  2. Why the insistence on using CSS styling on a SVG element. The SVG viewBox can do the same thing as shown here without any additional style coding.

    SVG clip paths are far more valuable when using photographic images. SVG allows transparency on JPG files, as opposed to having to use the nasty PNG file format.

    • I don’t recall insisting on CSS styling. What in this article led you to think I did? If anything I specifically say not to use the CSS clip-path property due to a lack of browser support. I thought I would show it though, because I imagine in time once support is there, CSS will become the preferred choice given the desire to separate structure and presentation. I also expect that in time we’ll be able to do with CSS the same things we can currently do with SVG in regards to clipping elements.

      • CSS was originally intended for styling, it was never intended to be used as a markup language.

        Why would you want to separate structure and presentation. This causes the need for two, or more, files.

        If you go to my web site using Firefox or Edge you will see that extensive CSS is not needed.

        Over reliance on doing everything with CSS just contributes to web site mediocrity.

        • I still don’t understand your point. Where exactly did I use CSS for markup?

          Do you mean because I used inline CSS in the examples? If so that’s just for the convenience of presenting the examples. I don’t think I mentioned it in this post, but this is an ongoing series and I talked about using inline CSS when I started the series.

Leave a Reply

Your email address will not be published. Required fields are marked *