Have you tried Flywheel? Learn moreJoin the best designers and creative agencies in the world. Learn more

×
How to use CSS and SVG clipping and masking techniques

How to use CSS and SVG clipping and masking techniques

SVGs are great for working on the web, and clipping and masking allow for some interesting ways to show or hide pieces of your web graphics. Using these techniques also allows for more flexibility with your designs because you do not have to manually make changes and create new images – it’s all done with code. By using a combination of CSS clipping and masking techniques, you will have lots of options for your website graphics.

To help clarify things, masking and clipping are two different ways you can manipulate images with CSS. Let’s start with clipping.

Clipping basics

If you’ve ever used Photoshop, you are probably already familiar with Clipping Masks. It’s a similar kind of approach. Clipping involves laying a vector shape, like a circle or a triangle, on top of an image or an element. Any part of the image behind the shape will be visible, while everything outside the boundaries of the shape will be hidden.

For example, if a triangle clipping mask is over the top of an image of a forest, you will see the forest image within the triangle shape. The shape’s boundary is called the clip path, not to be confused with the depreciated clip property. You create the clip path by using the clip-path property.

css-svg-clipping-masking-clipping-graphic

Clipping in action

Clips are always vector paths. It can be confusing to understand, but anything outside the path will be hidden, while anything inside the path will be visible. To get a better understanding and to test this out yourself, see the sample on CodePen.

css-svg-clipping-masking-triangle-example

Here is a snippet of the HTML structure from the example:

<svg class="clip-svg">
	<defs>
		<clipPath id="polygon-clip-triangle-equilateral" clipPathUnits="objectBoundingBox">
			<polygon points="0 0.87, 0.5 0, 0.5 0, 1 0.87" />
		</clipPath>
	</defs>
</svg>

This is the CSS to make the clipping happen:

.polygon-clip-triangle-equilateral {
	-webkit-clip-path: polygon(0% 87%, 50% 0%, 50% 0%, 100% 87%);
	clip-path: polygon(0% 87%, 50% 0%, 50% 0%, 100% 87%);
	-webkit-clip-path: url("#polygon-clip-triangle-equilateral");
	clip-path: url("#polygon-clip-triangle-equilateral");
}

You can see where the clipPath id is being referenced in the HTML and how it uses the clip-path URL to do the clipping.

Clippy tool

Clippy is a great tool to generate CSS clip paths. There are a wide variety of starter shapes and sizes that can be customized.

css-svg-clipping-masking-clippy

Masking basics

Masking is done using a PNG image, CSS gradient, or an SVG element to hide part of an image or another element on the page. We will be focusing on SVG graphics, but keep in mind this can be done with other image types or styles.

The mask property and mask element

Just a refresher to help visualize, it’s important to keep in mind that the masked element is the “original” (before mask is applied) image. You may not want to see the whole image, so hiding parts of it is done with the CSS mask property. The mask is the CSS shorthand for a group of individual properties, which we’ll dive into in a second. The SVG <mask> element is used inside an SVG graphic to add masking effects. In this example, the mask is a circle and there is also a gradient applied.

Using the SVG mask element on an SVG graphic

To get a feel for the SVG <mask> we will be masking with an SVG graphic.

It might be a bit complex at a first glance, but it all works together to mask the underlying image. We have an actual image as a background, so where does the SVG come into play? Unlike the clipping examples, this background image is technically inside of an SVG element. We’ll use CSS to apply this mask to the image. Properties will come from the SVG mask element, and we’ll give it the id of masked-element in our CSS.

To see this in  action, check out this Codepen sample. Here’s the working code for the masked SVG graphic:

<svg class="masked-element" width="300" height="300" viewBox="0 0 300 300">
	<image xlink:href="image link" width="300px" height="300px" />
</svg>

css-svg-clipping-masking-masked-outline if you go to the Inspector, you can see the boundaries for the masked element. The circular shape is created with a mask.

With this CSS, we are specifying where to find the mask. It will look for the ID of #mask-this:

/* Here’s the CSS for masking */
.masked-element image {
  mask: url(#mask1);
}

css-svg-clipping-masking-svg-mask

Notice a gradient in the circle shape? A gradient has been applied, as well as setting the circle shape for the mask.

<svg class="svg-mask">
 	<defs>
 		<mask id="mask1" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
    <linearGradient id="grad" gradientUnits="objectBoundingBox" x2="0" y2="1">
      <stop stop-color="white" offset="0"/>
      <stop stop-color="green" stop-opacity="0" offset="1"/>
    </linearGradient>
    <circle cx="0.50" cy="0.50" r="0.50" id="circle" fill="url(#grad)"/>
  	</mask>
 	</defs>
</svg>

SVG text masking

Text masking can do some pretty cool things, such as showing an image through a text block. The good news is that a text element can be used inside of an SVG mask. As browser support increases in the future, this could be a really interesting way to combine images and typography.

css-svg-clipping-masking-text-mask

Here’s a basic explanation of what is going on. There is an SVG text element inside the SVG mask. We’ve specified the RGB value for white, which creates the oval area around the masked text. Anything behind the oval area shows through the text, giving a cut-out feel.

<div class="text-wrap">
    <svg class="text-demo" viewBox="0 0 600 400" width="600" height="400">
    <defs>
      <mask id="myMask">
        <rect width="100%" height="100%" fill="#fff" />
        <text x="50" y="200" id="myText">My Text</text>
        <text x="125" y="293" id="mySubtext">SVG</text>
      </mask>
    </defs>
    <ellipse class="masked" cx="300" cy="200" rx="300" ry="150" fill="rgba(255, 255, 255, 0.8)" />
  </svg>
  </div>

/* Here’s the CSS for text element */
#myText {
font-size: 125px;
font-style: bold;
fill: #000;
}

/* Here’s the CSS for masking */
.masked {
mask: url("#myMask");
}

To fully understand, it’s helpful to play around and experiment with the code. Try changing colors, changing text, and adjusting sizes in this Codepen.

Browser support

Before committing to this new way of working with graphics, it’s important to note that browser support is not consistent with clipping and masking. Clipping is more supported than masking, but Internet Explorer does not fully support clipping. Current browser support for CSS masks is also fairly limited, so it’s suggested to be used as an enhancement on a few decorative elements. That way, if it is not supported by the user’s browser, it does not affect the content viewing experience.

To test things out and see if your masks and clippings are supported, I’d recommend making a JSFiddle or Codepen and then trying it in different browsers. Don’t let the limitations get you down – it’s always good to be ahead of the game and once support is more mainstream, you will know exactly how to revolutionize your graphics. When in doubt, be sure to reference the trusted Can I Use.

Remember: You should never make changes on a live site. Our free local development app, Local by Flywheel, will help you simplify your workflow and safely experiment with your site. Try it today!

After experimenting with these examples, this should provide a good introduction to masking and clipping. Although browser support is limited at this time, this will likely become a mainstream practice in the future. It’s always fun to think about how these techniques can be used to create interesting visuals. The future of web graphics will make us less dependent on image editors and allow for more effective ways to create and modify imagery directly in the browser.

3 Comments

  • inspire says:

    Hi, is there a way to scale the image under the mask
    ( .masked-element image { mask: url(#mask1);} )

    but with keep original dimentions of the mask, when I am scaling the masked object ( .masked-element image ) – the mask defined in svg is seems to scaling too

  • That is really awesome content on how to use CSS and SVG clipping and masking techniques. Thanks a lot for sharing this nice content to us. Really helpful.

  • Jikku says:

    Is there a way to have SVG masks applied on regular HTML content?

Join the discussion

Share this article:
Get more great content in your inbox

More articles

Get content like this sent directly to your inbox!

Install WordPress locally free