Creating a Truly "Cut Out" Div

May 13, 2013

For a project at work, I wanted to make a div with a true cut out — one that that wasn’t bound to clipped images, and didn’t affect any other page elements. It would essentially be a basic frame.

The internet says “You first need to understand that a div in HTML Cannot be Masked or Clipped through SVG.” — April 2012.


I politely disagree, so here we go:

mask-box-image:

This is absolutely the easiest method, but only works in Webkit browsers.

WATCH THIS:


#clouds {
  -webkit-mask-box-image: url(logo.svg);
}

//DONE. That’s basically all the code you need to knock out a div. Truly awesome. You just link to the .svg file, and you’re finished.

Usage: -webkit-mask-box-image works for Google Chrome 1.0+ and Firefox 4.0+

If this was all we needed to do, that would make our lives SO much easier, but unfortunately you need a little more work than that. In order to get the same effect for Firefox, we’ll need to create a clipPath and reference it in the CSS with clip-path (bear with me here). 

clipPath vs. clip-path

Ladies and gentlemen, let me break the shocking news to you that sometimes code makes no sense.

Exhibit A: clipPath != clip-path

clipPath is an SVG property which can only be used inside of the SVG element (sorry, for lack of better term) area as a way to tell the browser “only fill in this space”. You use it as a clipPath tag, as a means of essentially “drawing” a path (and it’s easy to just place an image behind it to have it crop that image). The only technical difference between clipPath and a regular SVG rendering except for the fact that you must tag it as one in order to use it as a clipping path:

clip-path is a CSS property (only supported by Firefox right now — unfortunately!) which lets you separate your path and your div, and clip an entire div. YES! A div! With things animating inside of it, and any background properties you could ever want! This doesn’t just limit your clipping abilities to static images, but it opens up a whole slew of options.

The clip-path definition references a clipPath element, so they are interrelated in the sense that you can’t have one without the other.


<html>
   <svg width="100px" height="100px">
       <clipPath id="clipName">
              <!-- DRAW SVG HERE -->
       </clipPath>
     </svg>
</html>

<style>
     #divname{
          clip-path: url(#clipName);
     }   
</style>

Usage: clip-path works in Firefox 3.5+

CSS Masking

I leave masking for last because it’s kind of mysterious (no pun intended) and flakey. However, it works in much the same way as the more specified -webkit-mask-box-image (it’s essentially the same thing if you add the suffix “top left / cover” to the end of your mask. This should work for newer versions of Opera and MS based browsers with vendor prefixes, but Firefox seems to dislike linking to .svg files and would need you to embed a mask (VERY MUCH like a clipPath) onto the page like this:


<html>
     <svg width="100px" height="100px">
       <mask id="maskName">
              <!— DRAW SVG HERE —>
       </mask>
     </svg>
</html>
<style>
     #divname{
          mask: url(#maskName);
     }   
</style>

I used masking in this little demo to cover -o and -ms systems (and -webkit because who knows what’s going to happen in a few weeks with Chrome Blink). However, for Firefox, I chose the clipPath/ clip-path route instead. Give the site a second to see the animation pass by.

HERE IS THE DEMO 

Other Options

Canvas:

Broken down simply, once you make your canvas element, these two lines are essentially what  gives you a “knock-out”:

ctx.globalCompositeOperation = ‘destination-out’; //this tells you that you want to “destination-out” (knock-out) the following:

ctx.fillText(“Hello”, 120, 50); //this is the text (in this case) or it can be an image image that you’re knocking out.

cut out .svg / .png

Lastly, the way it’s been done in the past is by creating a cut out .png file or .svg file overlaid as a background image or inserted image on a div. The .png may be your best option for older browsers, though is in my opinion, not as cool.

TL;DR: SEE THE DEMO

Further Resources:

http://docs.webplatform.org/wiki/css/properties/clip-path
https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image
https://developer.mozilla.org/en-US/docs/SVG/Element/clipPath
https://developer.mozilla.org/en-US/docs/Applying_SVG_effects_to_HTML_content 
http://trentwalton.com/2011/05/19/mask-image-text/
http://sawyerhollenshead.com/writing/23/using-svg-clippath/ 

The background used in the demo was chosen to prove the interdependence of the cutout element from anything else on the page (and b/c it makes me smile). It’s from an awesome resource called the code player. You can watch a walkthrough of how to make it here: http://thecodeplayer.com/walkthrough/pure-css3-animated-clouds-background