Progressive Enhancement Code Pattern Using Sass and Modernizr
Sass is a CSS Preprocessing language and Compass is a kickass framework built on top of it. Modernizr is modern feature detection. Both rock, and here’s a simple Progressive Enhancement code pattern I’ve been using leveraging Modernizr’s CSS class hooks and Sass nesting.
What I’m doing in this pattern is defining properties directly underneath
.foo that should be applied regardless of if the feature I’m looking for is available (anything from box model to design), then I’m nesting the Modernizr feature detection parent selectors underneath, allowing me to see both my feature-present (
.feature &) and feature-absent (
.no-feature &) styling in line, making future maintenance easier by leaps and bounds. I include the
So what exactly is all of that? We’re going to combine the power of Compass image sprites, dimension helpers, and inlining capabilities to build a future friendly image replacement complete with progressive enhancement up to SVG to make our image replacement resolution independent (yay!). First step is first, we import our Social png icons to create a Compass Image Sprite. Yes, this will build a full image sprite from individual images; it rocks. Next, we’re going to use the Compass Image Dimension Helpers to grab the height and width of the PNG image so we don’t need to hard code them, making them super dynamic if we choose to change the size of our images later; Compass will handle all of the changes for us in the background. We’re then going to grab the hide-text Text Replacement Mixin to hide our text. The final piece of our generic styling is to stop our background from repeating, because we don’t want that on a text replacement.
Now onto the fun stuff, the Modernizr powered feature detection. First up, SVG. For it’s background-image property, we’re going to use the Inline Image Data Helper to Base64 Encode our SVG, reducing HTTP requests for modern browsers and caching the image with the CSS at the cost of a slightly larger CSS file (a tradeoff I’m okay with making). If we want, say, if our SVG is of larger dimensions than our PNG, we can write a background-size property and set it to the same dimensions as our PNG to ensure the two stay in lock-step (we could feature detect for background-size, but according to the awesome Caniuse.com, all browsers that support SVG also support unprefixed background-size, and I’m cool with assuming that). Finally, for our no-js and no-svg folks, we include the sprite placement for our icon, thus completing the circle. The net result of all of this? For modern browsers, they make 0 additional HTTP requests for our image replacement (which is resolution independent), get our image replacement cached with the CSS, and shouldn’t download the image sprite because none of the sprite selectors apply to anything on page! For older browsers, while they will have slightly larger download sizes for their CSS, that then gets cached and they only need 1 additional HTTP request to grab their icons.
I can hear you now, though, saying: “Hey Sam, that looks like a lot I’ve got to write each and every time! Can’t you make it easier?” Yes. Yes I can. Presenting the Progressive Enhancement Text Replace Mixin.
Hope people find this useful. If there are any bugs in the mixin, let me know and I’ll update the mixin here. Happy coding!