The folks over at Devour maintain a nice collection of videos, wrapped in a clean interface. One of the touches is that each video is presented using what I call the Devour Effect: a text description in the foreground and a still from the video blurred in the background.
I was curious how Devour produced the blurred effect and so I took a look at their code. It turns out they simply preprocess the images in something like Photoshop. Sure, that may be the most bulletproof approach, but where’s the fun in that?
What follows is a comparison between Devour’s approach and four other, more programmatic techniques, including a pure CSS solution. The ones that utilize canvas or SVG are based on Matt Riggott’s work. And as a point of reference, you can see the actual rendering from Devour above and what an unblurred version looks like below.
Preprocess with Photoshop
As I mentioned, Devour creates blurred stills in advance. The text is then overlaid by assigning it a negative top margin. I’ve recreated this here. The only difference to the actual rendering above, you might notice, is that I use Futura since I don’t have access to Proxima Nova Condensed.
View the code and live render.
Blur with Canvas and JavaScript
An alternative approach is to create a canvas element and embed the image in it. JavaScript can be used within a canvas to manipulate images, from scaling or rotating all the way down to pixel-specific operations. This is precisely how the blur action in Pixastic works. Here, the blurring function loops through the image several times and averages each pixel’s color value with that of its neighbors.
View the code and live render. You might notice that the image here is Base64 encoded. This is to overcome a cross-domain security issue with JS Bin. You should be able to reference the image in the normal way.
Blur with SVG and XML
SVG is an image format that has a number of filter effects built right into it. While SVG is normally reserved for vector graphics, you can also embed a bitmap image in it. Then all it takes is a few lines of XML to apply a Gaussian blur to it. One thing to note is the weird glow around the border.
View the code and live render. If you were to open the SVG file in a text editor, you would discover markup like this.
Layer with Canvas and JavaScript
In contrast to the pixel-based algorithms used in the previous techniques, the final two use a simple trick to blur more efficiently. Copies of the image are stacked upon each another, offset by a few pixels and partially transparent.
Here, a canvas element is created and the image is embedded at full opacity. With each call of the blurring function, copies of the image are stacked on itself recursively, set at an opacity of 12.5 percent and offset in each direction by a pixel. Each iteration results in an increasingly blurred image.
View the code and live render.
Layer with CSS
Finally, I wanted to see if I could achieve a similar effect using pure CSS — that is, without the aid of JavaScript, canvas, or SVG. Here, copies of the original image are set to an opacity of 12.5 percent and offset from the original by two pixels in each of eight directions.
A couple of remarks about the code. The copies are all given absolute positioning, meaning they are positioned relative to their common parent. CSS classes are used to set the offset of an image in a cardinal direction; a combination of these classes is used to offset an image diagonally. Finally, in order to use z-index to keep text at the top of the stack, all of the elements using z-index are given a position other than default static.
View the code and live render.
Conclusion
So how do these approaches measure up? As you can see from the side-by-side comparison, they all do an adequate job. Click to enlarge.
If you don’t want to bust out Photoshop and wrangle with a bunch of images, or you want to create a dynamic effect, try one of the alternative approaches. If, on top of that, you’re not comfortable programming, you can get by with just CSS.
But if you want what’s speediest and most robust on the client, do as Devour does.