Using CSS3 Pseudo Elements and Box Shadows Instead of Images for HiDPI Geometric Shapes

Published 4 years 5 months ago on January 14, 2013 — 6 min read

With every project I try to take on something new, something I haven’t tried before. Sometimes it ends up being a huge time saver and other times I end up with something that just didn’t quite work out. Even when it doesn’t work out though, I’ve now got some applicable experience that I can use in a subsequent project that I know it’ll help with. Lately I’ve been experimenting with HiDPI (retina) time-saving techniques.

I think we can consider HiDPI officially making it’s way into the mainstream. It started with smartphones but has now progressed to laptop displays and likely soon enough desktop displays at some point in time. I can’t say for sure how I feel about it’s proliferation resulting in high resolution displays being more common than ‘standard’ definition, but I think the percentage will be great enough for us all to take it seriously. As a front end developer I want to stay as far ahead of that curve as I can, even if my clients aren’t using HiDPI displays. They might some day, and I’d love for them to be pleasantly surprised (or not even notice) that we were accommodating.

The deal with high resolution

HiDPI in Web design is kind of a double-edged sword for a front end developer. We now have two nearly separate environments (in some cases) that need attention. That sometimes results in double the style rules, double the image assets, and feature detection. Addition of anything is often the opposite of what we try to do, so it’s important to be as smart as possible when approaching management of HiDPI assets and styles in our projects.

More often than not we can streamline our approach by sizing down a 2x image and therefore accommodating both HiDPI and standard resolution displays. Doing so is as simple as cutting img dimensions in half or taking advantage of background-size which allows us to achieve the same result with background images in CSS. Luckily background-size is pretty well supported, and if IE8 is a concern you could include a browser-specific stylesheet with references to 1x versions of your 2x images.

caniuse-background-size

The disadvantage here is that we’re by default sending a bigger asset that takes longer to transmit and we’re relying on the browser to scale down the image which might result in an undesired outcome. While these shortcomings will more often than not be negligible, you’ll notice some issues when working with fine lines and hard edges that get blurry when scaled down by the browser on standard definition monitors. I hit that very issue on a recent project we launched for Terra Nova Church in a number of places. In my opinion Kevin hit it out of the park with the redesign. Sure I might be biased because I love everything he designs, and Terra Nova is our church so I’m just really happy to have been involved in the project. Gushing aside, there are a number of areas I took issue with the results of background-sized images with hard edges, in particular the Locations bit:

terra-nova-locations

The orange brackets and center line looked anything but sharp when I was testing on a standard definition monitor. It was likely a result of the pixel widths but I wanted to respect the design one-to-one as much as I could and thought there must be a better way. I recalled seeing a post during my travels that was a proof-of-concept for drawing shapes in CSS and it immediately came to mind as I was pondering an alternative method to getting this design element in place. After reviewing the article I thought it was a really clever approach to what I was trying to do so I gave it a shot. The idea behind drawing the shapes was to take advantage of pseudo elements and box shadows to implement the desired effect without using extraneous markup or images.

CSS3 pseudo elements and box shadows are super useful

If there’s one thing I really latched on to last year it was pseudo elements. In particular :before and :after have become exponentially useful. Utilizing :before and :after makes sense to me because it’s a nice balance of not having to bloat your markup for the sake of styling and it also helps avoid making additional HTTP requests for images.

It turns out :before and :after were indispensable when recreating Kevin’s Locations design element on the Terra Nova website. After dissecting more of The Shapes of CSS the cleverness started to hit me, in particular the Space Invader example. While there’s a ton of CSS getting the job done there, it was the lightbulb moment for me because I realized how the author was essentially creating 1em x 1em ‘pixels’ to work with, and arranging them in the form he wanted. I thought that was genius and started recreating that for the Terra Nova website. I set up my ‘pixels’ and recreated the left and right brackets using them. It worked great! I wasn’t really comfortable with the generated styles, however. It took a lot of ‘pixels’ to get the effect, and I quickly realized I was over-thinking it.

I regrouped and realized that I wasn’t utilizing :before and :after to their full potential, in fact I could cut it down to just a single use of :after with two box-shadows. I liked the sound of that. After some experimentation I ended up with the following:

Paying particular attention to lines 18-20 of this snippet of a Sass partial within the project you can see the brackets are implemented solely using box-shadow which helps us avoid any issues with browser image scaling and saves us an HTTP request.

To get a closer look at what’s actually happening in the browser, we can have a look at this 3D render of how the pseudo elements are doing their thing:

terra-nova-3d-view

Paying particular attention to the bracket area, you can see that I took advantage of the fact that this particular design element had flat colors everywhere, so I simply stacked rectangles upon rectangles to achieve the effect. Some rectangles were created using a simple background-color, others with box-shadow as outlined above, and another using a simple border-top. My intention was to avoid images in this case and remain resolution independent. The outcome in my opinion worked great, the lines look sharp both on HiDPI and standard resolution displays.

Use cases are semi-limited

Techniques like this aren’t always applicable when concerning every design, but that comes with the territory sometimes. With this hyper trend of flat design that took us by storm last year though, chances are you might be able to use this in an upcoming project to save some time, bandwidth, and keystrokes.

I parlayed this technique to other areas of the Terra Nova website as well. As with most new things I really got hooked on it and wanted to see other areas it would be useful. One in particular were the headings of The Gospel page. I really liked the look of the headings and wanted to implement them using CSS only.

[is_not_paid]

A walkthrough of the style implementation for the headlines on The Gospel page are restricted to Members. For access to this content and all Member content, sign up today!

[/is_not_paid][is_paid]

Pseudo-elements saved the day here as well, but I didn’t need to go so far as to use box-shadow here and instead opted to use only a background-color to get my 1px line elements. The trick here was the dynamic length of the text within the headline and the custom bullets on either side of the text. Handling that was a matter of wrapping the text in a span and taking advantage of it’s display:inline; property, tacking on a multiple background image and :before & :after pseudo-elements for the lines. I recorded a quick walkthrough of how this was implemented, have a look:

[/is_paid]

As with many things, the combination of markup and style here is pretty unique to the Terra Nova design, but hopefully seeing how that was done will help you out with a project down the line that implements something at least partially similar.

Copyright © 2006—2017 Jonathan Christopher