Webkit SVG background fix!
Hi guys! If you follow me on Twitter, you know that I’ve been running into a bug in Webkit that causes an embedded SVG to have a white background, rather than transparent. That was causing my SVG logo on http://alpha.spherecat1.com/ to look terrible in Safari and Chrome, so I have been looking for a fix for some time. I found one!
Update: Here’s a link to the official bug in the MacOSForge mailing list.
And here’s one for Chrome.
Intro
One of the new CSS 3 properties available in Webkit-based browsers is CSS Masks. There’s a complete article on masks here, but the basis of it is that you can cut out part of a box using a mask image. Since it works on any box and not just images, we can apply it to our embedded SVGs. You can probably see where I’m going with this.
Adding the CSS code
Basically all you have to do in CSS is add the following code:
{
-webkit-mask-box-image: url(“images/mask.png”) 0;
}
Where “#logosvg” would be replaced by the id of your <embed> or <object> tag, and “images/mask.png” would be replaced by the url to your mask image, which we’ll create in a second. That really is it! Just make sure to fix the id and url, or nothing will happen.
Creating the mask
Now to create the mask image. For this, we can either use a PNG, or another SVG (which seems odd, since they get filled in, but it does work).
- First, you need to open up your SVG in the editor of choice. Be careful not to save the SVG during the next few steps, because we’ll be changing the color of all of the elements. You may want to just save it as “mask.svg” or something similar, in case you accidentally push save.
- Now that you have the logo open, the first thing you need to do is go through and remove the stroke of any object that have one.
Disclaimer: I’ve only tested this on my logo, and I had to remove the stroke to get a clean edge. Your results may vary, and please let me know if they do. I’ll update this post with the latest info. - If you have a shadow on anything in your image, like in “Before Masking” below, you’ll have to remove that completely, or it’ll show up as a white glow instead. You’ll want to remove them from the original too, since they’ll just be masked out anyway, but save that for later, because I have a tip for that at the end.
- This is the easiest step. Select every object in the SVG and change their fill to black, and opacity/alpha to 255/100%, whichever your editor uses.
- If you’re using a PNG as the mask, this is the time to export it. Make sure to export it as the whole page, so it lines up with the SVG, or strange things will happen. If you’re using an SVG mask, just save this as mask.svg if you haven’t already.
Wrap-up and notes
And that should be about it! A couple more pieces of info that I’d like to pass along:
- If your SVG is animated during it’s time on the page, and you move objects inside of it, they will be cut off at the edges of the mask. I’m going to look into a way to dynamically generate a mask for every frame of animation, and I’ll update this post if that gets anywhere.
- If you plan on changing the opacity of any elements in the SVG while it’s on the page, it will change the opacity fine, but it will appear as though they are in front of a white background, because they are. The only fix I’ve found for this is to copy the object that changes opacity, place it behind the original, and set the copy to the color it’ll be in front of during the animation. Obviously this won’t work well for complex or animated backgrounds, so if anyone finds a better solution, please let me know!
- If you removed any shadows during the masking phase, and want them back, you can go back to the original image, remove everything except for the shadows, and export them as a PNG. Then, add them into your HTML document, and position them underneath the <embed> or <object> using CSS. You may need to play with your z-indexes.
And now you’ve reached the end! Thanks for reading, and I hope I’ve helped somebody out with their project. Here’s the final result of all of this with my logo:
If you want to see the final result live, check out http://alpha.spherecat1.com/!
Billy



