As web developers and designers, we love our CSS shapes, shadows, and other effects. It’s totally understandable, CSS generated images and effects remove the need for an image to achieve the same result; this is a win in a world where every byte counts. Using CSS generated images also lets us control the graceful degradation of these effects. For example, in older browsers a circle will become a square, and we can rely on that. CSS generated visuals are just another way we can embrace the fluidity of the web.
Simple and Right
Browser issues and inconsistencies aside, sometimes using these awesome shapes isn’t so straight forward. Take for instance this ribbon effect (or a square missing a triangle-shaped piece).
It looks like what we’d expect: nice, right angle, solid lines, crisp, and perfect. The reason this looks so good is that the cutout is a right angle and doesn’t need any antialiasing to show up nice and crisp. Now let’s look at this slightly different ribbon.
It has one big difference. See those “stair-steppy” 8-bit sides in the cutout portion? We would need antialiasing here to smooth those out, but that’s not happening. This is one of the flaws in CSS shapes, rendering an angle that’s not simply 90 degrees can result in epic Atari-level graphics. Those jagged sides are only present in Chrome, Firefox, and Safari; iOS handles everything here just fine.
Don’t Give Up!
Until recently, I always decided it was good enough (or more realistically, it got tabled and forgotten about), or I fell back to using an image to achieve that level of perfection. On a recent project, I decided to spend a little time and investigate any possible solutions—after all, we web folk are a stubborn, persistent lot.
A Solution Emerges
And as usual, StackOverflow delivered in a big way. One proposed solution was to put a transform: rotate
; on the triangle. Some answers proposed using some value like 0.05deg
, but honestly, a simple 360deg
rotation has the same effect and is totally predictable. Once applied to the element, the jaggy edges are smoothed out. The elegance of this approach is that it’s inline with the philosophy of the shapes themselves: if a browser doesn’t support rotation, then we have the jaggy edges as before, and we could use feature detection for rotation to control the fallback experience even more.
Shadows and Shapes Working in Harmony
The other downside to doing CSS shapes is that (aside from very simple shapes) CSS box-shadows and shapes don’t get along. The shadow isn’t aware of the actual outlines of the shape, so we end up with a weird box shadow defiling our awesome ribbon shape.
We can address this by using CSS3 filter’s drop-shadow effect.
This effect correctly traces the outline of the shape, unlike a box-shadow. The best part of this approach is that browsers that don’t support filters will simply not show them, and we can use feature detection to provide a fallback experience if necessary.
Final Product
So we’ve navigated through some of the issues surrounding CSS shapes and effects. Obviously, our final solution is only going to look “perfect” in Webkit and Blink browsers, but we’ll get the basic shape all the way back to IE8. Here’s an example of putting all that work together, a ribbon heading.
This is how we achieved this effect on the new Build Right section headers. There’s no extra request, no image download, and it looks pin-sharp on Retina to boot!