Responsive Placeholder Image
Transparent Pixels
I became interested in image replacement techniques to keep page size down, AJAXing in full images later as needed, and I stumbled across The Smallest Transparent Pixel. Using a bas64 encoded 1x1 transparent pixel as a placeholder, you set the width
and height
attributes to the space you want to fill.
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw" width="200" height="150" />
Unfortunately, the 1x1 pixel images have issues with common responsive styles, due to the image's square aspect ratio.
Let's say you set img { max-width: 100%; }
to prevent images from causing horizontal scrolling on small screens. Your 1x1 pixel img's width can be squished down below what you set in the width
attribute, but the height remains the same, leaving you with an oddly shaped placeholder.
If you try to correct this with img { max-width: 100%; height: auto; }
, the height
attribute is completely ignored, and the width can be squished below the width
attribute's setting, leaving you with a square; probably not the aspect ratio you intended.
This is intended behavior in the browser and works great for regular images, but how can we fix this for this filler image?
SVG to the Rescue
GIFs and PNGs aren't the only images you can inline. Our friend SVG can even be inlined without base64. SVG also has an aspect ratio built in using the viewBox
attribute. So if we swap out our 1x1 pixel for this...
<img src="data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox%3D'0 0 200 150'%2F%3E" width="200" height="150" />
...our responsive styles work as intended! The important bit is the 116 byte src
attribute. This works all the way back to IE9 due to the encodedURIComponent
conversion of special characters, which unfortunately makes it a little more difficult to read.
Notice how the responsively sized svg
maintains its aspect ratio. This is set here viewBox%3D'0 0 200 150'
, giving the svg
a width (200) and height (150) to get the correct aspect ratio. This could be viewBox%3D'0 0 16 9'
for 16x9 images or the exact width and height of the image you plan to use as a replacement.
Image Replacement
The above is a great snippet by itself to be used in place of the standard 1x1 pixel image, but how can we apply this to image replacement?
<figure class="image-replacement" data-src="http://i.imgur.com/YVSnio4.jpg" data-width="1400" data-height="900">
<noscript><img src="http://i.imgur.com/YVSnio4.jpg" width="1400" height="900" /></noscript>
</figure>
In our HTML, we have a figure
tag with the relevant image info set in data attributes for our Javascript to pull. There's a simple noscript
fallback so that our Javascript-less bretheren don't suffer.
The placeholder svg
has been updated to display an icon instead of just being blank, but the technique is still the same of setting the correct viewBox
. The icon itself is a symbol
which has its own viewBox
, allowing it to be easily sized and centered in the main svg
. Unfortunately, the symbol can't be defined or reused outside of the individual img
, since it seems that browsers treat it as an external, self contained file.
The Javascript is very minimal, taking the data attributes of the figure
to create the placeholder, then loading the image when hovered, mainly to show how the image seamlessly replaces the placeholder. The content doesn't have to reflow and text doesn't jump around. For a real image replacement scenario, you'd likely want to configure it to load images as they come into viewport, or perhaps when they're next in the slideshow.
Summary and Closing
Use data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox%3D'0 0 200 150'%2F%3E
as the placeholder src
attribute for any image you need to replace, updating the viewBox
value to keep the correct aspect ratio.
There are other ways you can accomplish all of this, but this technique is ultra simple, self-contained and can likely be used outside of image replacement.
Comment below if you have any improvements or examples of other uses.