SVG Masking Examples — Text And Image Masks

Last week I showed you some masking examples where the mask was more than a rectangle, including a couple where the mask fill was a gradient or pattern. Perhaps even more interesting, you can add a mask on top of an image or use an image or text as the mask.

Today I want to share a few more examples working with text and images as the mask content. Hopefully you’ll agree they’re more interesting than masking a circle with a rectangle.

Text Masks

Before we get started, here’s the image I’ll be using throughout this post. If you’ve followed along with this series, it should be familiar. It’s an image of the Strawberry Fields Memorial in Central Park.

Text is an interesting option for the content of a mask. A common use for a text mask is to place it over an image similar to using text as a clipping path. The mask clips the image outside of the text.

In this first example, I created a text mask with the ever so original words Text Mask. I’ve given the text some basic properties like a font family, weight and size. I’ve filled it with a medium gray (#999).

1
2
3
4
5
6
7
8
9
<svg width="660" height="220" style="outline: 1px solid red">  
 <defs>  
   <mask id="text-mask-1" x="0" y="0" width="100" height="100">  
     <text x="30" y="140" font-family="Helvetica" font-weight="bold" font-size="7em" fill="#999">Text Mask</text>  
   </mask>  
 </defs>

 <image width="660" height="495" xlink:href="http://www.vanseodesign.com/blog/wp-content/uploads/2013/09/strawberry-fields.jpg" mask="url(#text-mask-1)"/>  
</svg>

The result is the image showing through the text. The values of the image that show through are a little lighter than in the original image as they’re masked by the text fill, which is #999.

Text Mask

More interesting would be to replace the solid fill color of the text mask with a pattern. Here I used the same pattern defined in last week’s pattern example.

1
2
3
4
5
6
7
8
9
10
11
12
13
<svg width="660" height="220" style="outline: 1px solid red">  
 <defs>  
   <pattern id="pattern-1" x="0" y="0" width="10" height="10" patternUnits="userSpaceOnUse">  
     <circle cx="5" cy="5" r="5" fill="#999" />  
   </pattern>

   <mask id="text-mask-2" x="0" y="0" width="100" height="100">  
     <text x="30" y="140" font-family="Helvetica" font-weight="bold" font-size="7em" fill="url(#pattern-1)">Text Mask</text>  
   </mask>  
 </defs>

 <image width="660" height="495" xlink:href="http://www.vanseodesign.com/blog/wp-content/uploads/2013/09/strawberry-fields.jpg" mask="url(#text-mask-2)"/>  
</svg>

Hopefully you agree the result is a bit more interesting than the previous example with the solid fill.

Text Mask

Firefox has an issue with the previous example. It doesn’t seem to like adding the pattern to the text mask. Here’s an image of the result in case you happen to be viewing this in Firefox

Text mask example with a pattern fill

Instead of an SVG pattern, you can also fill the text mask with a gradient as I’ve done here, by borrowing the linear gradient I used last week.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<svg width="660" height="220" style="outline: 1px solid red">  
 <defs>  
   <linearGradient id="gradient-1">  
     <stop offset="0" stop-color="white" stop-opacity="0.1" />  
     <stop offset="1" stop-color="white" stop-opacity="0.9" />  
   </linearGradient>

   <mask id="text-mask-3" x="0" y="0" width="100" height="100">  
     <text x="30" y="140" font-family="Helvetica" font-weight="bold" font-size="7em" fill="url(#gradient-1)">Text Mask</text>  
   </mask>  
 </defs>

 <image width="660" height="495" xlink:href="http://www.vanseodesign.com/blog/wp-content/uploads/2013/09/strawberry-fields.jpg" mask="url(#text-mask-3)"/>  
</svg>

Again the shape of the text clips the image and in this case applies a gradient mask so the text to the left is lighter than the text to the right.

Text Mask

Similar to the previous example, Firefox doesn’t like this one either. Here’s an image if Firefox is the browser you’re currently using.

Text mask example with gradient fill

Image Masks

Let’s reverse things and instead of adding a mask on top of an image, let’s use the same image from the previous examples as the mask content.

In this example I’m using the image of Strawberry Fields as the mask content. I placed three circles inside a group <g> and have their fill colors set to be red (#c69), green (#9c6), and blue (#69c). The image is used to mask all three as I added the reference to the mask on the group as opposed to adding it to any of the individual circles.

1
2
3
4
5
6
7
8
9
10
11
12
13
<svg width="660" height="220" style="outline: 1px solid red">  
 <defs>  
   <mask id="image-mask" x="0" y="0" width="1" height="1" >  
     <image width="660" height="495" xlink:href="http://www.vanseodesign.com/blog/wp-content/uploads/2013/09/strawberry-fields.jpg" />  
   </mask>  
 </defs>

 <g mask="url(#image-mask)">  
   <circle cx="110" cy="110" r="100" fill="#c69" />  
   <circle cx="310" cy="110" r="100" fill="#9c6" />  
   <circle cx="510" cy="110" r="100" fill="#69c" />  
 </g>  
</svg>

Here’s the result and hopefully you can tell that a different part of the image masks each of the three circles.

You don’t have to add the mask to the group. You can also add masks to individual elements in the group.

In this next example I added a second mask that uses the pattern from the earlier example. I added the same image mask to the group of all three circles, but added the pattern mask directly on the first circle in the group.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<svg width="660" height="220" style="outline: 1px solid red">  
 <defs>  
   <pattern id="pattern-2" x="0" y="0" width="10" height="10" patternUnits="userSpaceOnUse">  
     <circle cx="5" cy="5" r="5" fill="#999" />  
   </pattern>

   <mask id="pattern-mask-2" x="0" y="0" width="1" height="1" >  
     <rect x="0" y="0" width="225" height="220" fill="url(#pattern-2)"/>  
   </mask>

   <mask id="image-mask-2" x="0" y="0" width="1" height="1" >  
     <image width="660" height="495" xlink:href="http://www.vanseodesign.com/blog/wp-content/uploads/2013/09/strawberry-fields.jpg" />  
   </mask>  
 </defs>

 <g mask="url(#image-mask-2)">  
   <circle cx="125" cy="110" r="100" fill="#c69" mask="url(#pattern-mask-2)" />  
   <circle cx="325" cy="110" r="100" fill="#9c6" />  
   <circle cx="525" cy="110" r="100" fill="#69c" />  
 </g>  
</svg>

Here’s the result. As you might expect, all three circles are masked by the image, but only the first circle is masked by the pattern.

Take note that this example uses two different masks, one applied to the entire group of circles and one applied directly to the first circle in the group. It shows that you can use multiple masks in the same SVG.

Closing Thoughts

That brings me to the end of this series on SVG clipping and SVG masking. I hope you agree that both are relatively easy to work with. With either you define the clipping path or the mask in one location and then reference it in another.

I think you’ll agree that masks are more interesting than clipping paths. In fact a clipping path is really a mask with a solid fill of white (#fff).

Masks become the most interesting when you use gradients and patterns as the fill or better use an image to mask another image or graphic element.

I have another SVG series on filter effects planned for later in the summer, but I think it’s time to switch topics. Next up is a series on Sass data types. I’ll talk about numbers, strings, color, lists, and maps, and then close the series with a look at control directives in Sass

Download a free sample from my book, Design Fundamentals.

Leave a Reply

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