I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my other blogs

Massive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

A Sass color keyword system for designers. Replaces CSS defaults with improved hues and more memorable, relevant color names.

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.


Text Clipping Masks With SVG


Estimated reading time: 2 minutes, 56 seconds

The concept of a clipping mask is simple: a shape is used to constrain an image, such that the picture is only visible within the confines of the shape, creating a “cookie-cutter” effect.

In past examples I’ve shown how to use various combinations of border-radius, radial-gradient and overflow: hidden to create masks for images, but using text as a mask is somewhat trickier. The Webkit team has a CSS3 proposal to do so, but it’s not yet supported in browsers outside of Safari and Chrome. I wanted a solution that would work cross-browser… even in IE9.

The spec has supported clipping masks for years. Building on what we know of SVG text, it’s pretty easy to integrate a solution.

First, place your image on the page. For all intents and purposes this will be your “background” image, which will show through the clipping mask. I’m using , so I can just place an image directly in the body:

<img src="yukon-river.jpg" alt="Knockout" id="knockout-text">

In my case, that image (supplied by Keith Williams under Creative Commons) looks like this: Yukon River

There are just two conditions for this image: it must be large enough to contain our text, and it must have an id value, which will be referenced in the we will write shortly.

Next, we’ll create our file. This will be a separate document named knockout.svg, with a simple structure:

<svg xmlns="" version="1.1" xmlns:xlink="">
<mask id="mask">
<text x="0" y="100" id="knockout" fill="white" style="font-size:120px; font-family: Blue Highway, Arial Black, sans-serif;">KNOCKOUT</text>
  <use xlink:href="#knockout"/>

Concentrate on the <text> element: the x and y values are the offset positions for the text, and the fill is the color for the letters. (This must be specified, even though we are showing our image through the letters). The font(s) we wish to use are written in an inline style, exactly as we do in CSS.

The part that is different is the <defs> and <mask> elements around our text. Very simply, this will allow use to specify the fact that we should use the text as a mask (note that the mask has an id). The penultimate line: <use xlink:href="#knockout"/> references the id provided to the text.

Finally, marry the SVG to our HTML content with CSS:

#knockout-text { mask: url(knockout.svg#mask);
   -webkit-mask-image: url(knockout.svg); }

The mask CSS property, used by Firefox, Opera and IE, refers to <mask id="mask"> in the knockout.svg file. Chrome and Safari need the second line, which pick up the mask where it is in specified in the file.

“But,” you might say, “How can I know that what you’re showing here is such an effect? It looks just like a picture!”

Indeed, that’s true: you’ll find that you can’t select the “KNOCKOUT” at the top of this article as text. But if you drag the element to your desktop, you’ll see that it saves as an image: removed from the clipping mask effect, you’ll see the entire landscape. And as I’ll show you shortly, you can edit the text in the SVG document to be anything you want… which is far quicker than going through PhotoShop.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.