Fallback image with CSS

I have found a solution on Codepen, which I would like to share with you: https://codepen.io/anon/pen/Eqgyyo

I prefer this solution, because it works with real image tags, not background images.

body {
  color: #2c3e50;
  font-family: 'verdana';  
  line-height: 1.35em;
  padding: 30px;
}
h1 {
  margin-bottom: 40px;
}
ul {
  list-style: none;
  padding: 0;
}
* {
  box-sizing: border-box;
}

img {
  color: #95a5a6;
  font-size: 12px;
  min-height: 50px;
  position: relative;
  
}
img:before {
  background: #f1f1f1;
  border: 1px solid #ccc;
  border-radius: 3px;
  content: '\1F517' ' broken image of 'attr(alt);
  display: block;
  left: 0;
  padding: 10px;
  position: absolute;
  top: -10px;
  width: 100%;
}
<h1>Broken image fallback CSS</h1>
<img src="no-image-here" alt="Cats with synthesizers in the space " />

<br /><br />
<ul>
  <li>✓ Firefox</li>
  <li>✓ Chrome</li>
  <li>✓ Opera</li>
  <li>✗ Safari (desktop, mobile)</li>
  <li>✗ iOS webview</li>
</ul>

Unfortunately, you can't achieve both without Javascript or object tag.

You could do this to avoid the missing image icon:

Place your image in a container (it might already be in one). Make the container have the same width and height as the image.

  1. Set the fallback image as the background image of the container.
  2. Set the remote image as the background image of your img tag.
  3. Load an 1x1 pixel transparent png as the src of your image (see code for how that can be done without an extra HTTP request).

Code:

HTML

<!-- you could use any other tag, such as span or a instead of div, see css below -->
<div class="cc_image_container fallback">
    <img class="cc_image" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" style="background-image: url(*your remote image*)"/>
</div>

CSS

.fallback {
    background-image: url(*fallback image here*);
    display: inline-block; /*to ensure it wraps correctly around the image, even if it is a a or span tag*/
    min-width: specify a minimum width (could be the width of the fallback image) px; 
    min-height: specify a minimum height (could be the height of the fallback image) px;
    background-position: center center; // fallback for older browsers
    background-size: cover;
    background-repeat: no-repeat;
}

.cc_image {
    min-width: same as container px;
    min-height: same as container px;
    background-position: center center; // fallback for older browsers
    background-size: cover;
    background-repeat: no-repeat;
}
  • min-width and max-width make sure that the background images remain visible.
  • background-position makes sure that the central part of the images remains visible and is a graceful degradation for older browsers
  • background-size resizes the background image to fill the element background. The cover value means that the image will be resized so it will completely cover the element (some of the outer edges of the image may be cropped)
  • The base64 data in the img src tag is a transparent 1px png.
  • This will have an additional benefit that regular users and some bots may not be able to save your images (a rudimentary image protection)
  • The only drawback is, that you will still have one extra HTTP request for the fallback image.