Img error html

Is there any way to render a default image in an HTML tag, in case the src attribute is invalid (using only HTML)? If not, what would be your lightweight way to work around it?

You asked for an HTML only solution…

 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">

<head>
  <title>Object Test</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

<body>

  <p>
    <object data="https://stackoverflow.com/does-not-exist.png" type="image/png">
      <img src="https://cdn.sstatic.net/Img/unified/sprites.svg?v=e5e58ae7df45" alt="Stack Overflow logo and icons and such">
    </object>
  </p>

</body>

</html>

Since the first image doesn’t exist, the fallback (the sprites used on this web site*) will display. And if you’re using a really old browser that doesn’t support object, it will ignore that tag and use the img tag. See caniuse website for compatibility. This element is widely supported by all browsers from IE6+.

* Unless the URL for the image changed (again), in which case you’ll probably see the alt text.

A.L's user avatar

A.L

9,9099 gold badges62 silver badges96 bronze badges

answered Jun 11, 2009 at 12:55

Patrick McElhaney's user avatar

Patrick McElhaneyPatrick McElhaney

57.1k40 gold badges130 silver badges167 bronze badges

11

This works well for me. Maybe you wanna use JQuery to hook the event.

 <img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';" alt="add alternative text here">

Updated with jacquargs error guard

Updated: CSS only solution
I recently saw Vitaly Friedman demo a great CSS solution I wasn’t aware of. The idea is to apply the content property to the broken image. Normally :after or :before do not apply to images, but when they’re broken, they’re applied.

<img src="nothere.jpg" alt="add alternative text here">
<style>
img:before {
    content: ' ';
    display: block;
    position: absolute;
    height: 50px;
    width: 50px;
    background-image: url(ishere.jpg);
}
</style>

Demo: https://jsfiddle.net/uz2gmh2k/2/

As the fiddle shows, the broken image itself is not removed, but this will probably solve the problem for most cases without any JS nor gobs of CSS. If you need to apply different images in different locations, simply differentiate with a class: .my-special-case img:before { ...

Andy's user avatar

Andy

4,0802 gold badges24 silver badges46 bronze badges

answered Jun 11, 2009 at 13:06

Svend's user avatar

SvendSvend

7,7953 gold badges29 silver badges45 bronze badges

13

Found this solution in Spring in Action 3rd Ed.

<img src="../resources/images/Image1.jpg" onerror="this.src='../resources/images/none.jpg'" />

Update:
This is not an HTML only solution… onerror is javascript

answered Oct 29, 2012 at 9:35

amit bakle's user avatar

amit bakleamit bakle

3,3011 gold badge15 silver badges14 bronze badges

2

a simple img-element is not very flexible so i combined it with a picture-element. this way no CSS is needed. when an error occurs, all srcset’s are set to the fallback version. a broken link image is not showing up. it does not load unneeded image versions. the picture-element supports responsive design and multiple fallbacks for types that are not supported by the browser.

<picture>
    <source id="s1" srcset="image1_not_supported_by_browser.webp" type="image/webp">
    <source id="s2" srcset="image2_broken_link.png" type="image/png">
    <img src="image3_fallback.jpg" alt="" onerror="this.onerror=null;document.getElementById('s1').srcset=document.getElementById('s2').srcset=this.src;">
</picture>

answered Mar 10, 2017 at 11:17

bapho's user avatar

baphobapho

8108 silver badges13 bronze badges

2

Simple and neat solution involving some good answers and comment.

<img src="foo.jpg" onerror="this.src='error.jpg';this.onerror='';">

It even solve infinite loop risk.

Worked for me.

answered Mar 20, 2019 at 14:55

manish kumar's user avatar

manish kumarmanish kumar

4,2563 gold badges34 silver badges50 bronze badges

3

<style type="text/css">
img {
   background-image: url('/images/default.png')
}
</style>

Be sure to enter dimensions of image and whether you want the image to tile or not.

sehe's user avatar

sehe

365k47 gold badges440 silver badges616 bronze badges

answered Jun 11, 2009 at 12:51

lambacck's user avatar

lambaccklambacck

9,6443 gold badges33 silver badges46 bronze badges

1

I don’t think it is possible using just HTML. However using javascript this should be doable. Bassicly we loop over each image, test if it is complete and if it’s naturalWidth is zero then that means that it not found. Here is the code:

fixBrokenImages = function( url ){
    var img = document.getElementsByTagName('img');
    var i=0, l=img.length;
    for(;i<l;i++){
        var t = img[i];
        if(t.naturalWidth === 0){
            //this image is broken
            t.src = url;
        }
    }
}

Use it like this:

 window.onload = function() {
    fixBrokenImages('example.com/image.png');
 }

Tested in Chrome and Firefox

answered Jun 11, 2009 at 13:07

Pim Jager's user avatar

Pim JagerPim Jager

31.8k16 gold badges72 silver badges98 bronze badges

0

<img style="background-image: url(image1), url(image2);"></img>                                            

Use background image that let you add multiple images.
My case:
image1 is the main image, this will get from some place (browser doing a request)
image2 is a default local image to show while image1 is being loaded.
If image1 returns any kind of error, the user won’t see any change and this will be clean for user experience

Mindastic's user avatar

Mindastic

3,9532 gold badges19 silver badges20 bronze badges

answered Aug 2, 2016 at 20:48

Emiliano Barboza's user avatar

2

If you’re using Angular/jQuery then this might help…

<img ng-src="{{item.url}}" altSrc="{{item.alt_url}}" onerror="this.src = $(this).attr('altSrc')">

Explanation

Assuming that item has a property url that might be null, when it is then the image will show up as broken. That triggers execution of onerror attribute expression, as described above. You need to override the src attribute as described above, but you will need jQuery to access your altSrc. Couldn’t get it to work with vanilla JavaScript.

Might seem a little hacky but saved the day on my project.

answered Sep 6, 2014 at 1:01

Obie's user avatar

ObieObie

6806 silver badges16 bronze badges

0

angular2:

<img src="{{foo.url}}" onerror="this.src='path/to/altimg.png'">

answered Mar 7, 2016 at 15:22

user3601578's user avatar

user3601578user3601578

1,1331 gold badge16 silver badges28 bronze badges

1

An HTML only solution, where the only requirement is that you know the size of the image that you’re inserting. Will not work for transparent images, as it uses background-image as a filler.

We can successfully use background-image to link the image that appears if the given image is missing. Then the only problem is the broken icon image — we can remove it by inserting a very big empty character, thus pushing the content outside the display of img.

img {
  background-image: url("http://placehold.it/200x200");
  overflow: hidden;
}

img:before {
  content: " ";
  font-size: 1000px;
}
This image is missing:
<img src="a.jpg" style="width: 200px; height: 200px"/><br/>
And is displaying the placeholder

An CSS only solution (Webkit only)

img:before {
  content: " ";
  font-size: 1000px;
  background-image: url("http://placehold.it/200x200");
  display: block;
  width: 200px;
  height: 200px;
  position: relative;
  z-index: 0;
  margin-bottom: -16px;
}
This image is there:
<img src="http://placehold.it/100x100"/><br/>

This image is missing:
<img src="a.jpg"/><br/>
And is displaying the placeholder

answered Mar 23, 2016 at 16:23

eithed's user avatar

eithedeithed

3,8275 gold badges40 silver badges60 bronze badges

Update: 2022 (works on chrome still!!)

I recently had to build a fall back system which included any number of fallback images. Here’s how I did it using a simple JavaScript function.

HTML

 <img src="some_image.tiff"
    onerror="fallBackImg(this);"
    data-src-1="some_image.png"
    data-src-2="another_image.jpg">

JavaScript

function fallBackImg(elem){
    elem.error = null;
    let index = elem.dataset.fallIndex || 1;
    elem.src = elem.dataset[`src-${index}`];
    elem.dataset.fallIndex = ++index;
}

I feel like it’s a pretty lightweight way of handling many fallback images.

If you want «HTML only» then this

<img src="some_image.tiff"
    onerror="this.error = null;
        let i = this.dataset.i || 1;
        this.src = this.dataset[`src-${i}`];
        this.dataset.i = ++i;"
    data-src-1="some_image.png"
    data-src-2="another_image.jpg">

answered Jan 2, 2020 at 21:33

Rager's user avatar

RagerRager

6144 silver badges25 bronze badges

2

A modulable version with JQuery, add this at the end of your file:

<script>
    $(function() {
        $('img[data-src-error]').error(function() {
            var o = $(this);
            var errorSrc = o.attr('data-src-error');

            if (o.attr('src') != errorSrc) {
                o.attr('src', errorSrc);
            }
        });
    });
</script>

and on your img tag:

<img src="..." data-src-error="..." />

answered Nov 12, 2015 at 15:24

Kevin Robatel's user avatar

Kevin RobatelKevin Robatel

7,9063 gold badges45 silver badges57 bronze badges

There is no way to be sure the myriad number of clients (browsers) that will try to view your page. One aspect to consider is that email clients are defacto web browsers and may not handle such trickamajickery …

As such you should ALSO include an alt/text with a DEFAULT WIDTH and HEIGHT, like this. This is a pure HTML solution.

alt="NO IMAGE" width="800" height="350"

So the other good answer would be slightly modified as follows:

<img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';" alt="NO IMAGE" width="800" height="350">

I had issues with the object tag in Chrome, but I would imagine this would apply to that as well.

You can further style the alt/text to be VERY BIG …

So my answer is use Javascript with a nice alt/text fallback.

I also found this interesting: How to style an image’s alt attribute

Community's user avatar

answered Jul 15, 2015 at 22:38

Xofo's user avatar

XofoXofo

1,2563 gold badges17 silver badges31 bronze badges

React

<img
  src="https://example.com/does_not_exist.png"
  onError={(e) => {
    e.currentTarget.src = "https://example.com/default.png"
  }}
/>

answered Nov 23, 2022 at 2:17

Coder039's user avatar

1

The above solution is incomplete, it missed the attribute src.

this.src and this.attribute('src') are NOT the same, the first one contains the full reference to the image, for example http://my.host/error.jpg, but the attribute just keeps the original value, error.jpg

Correct solution

<img src="foo.jpg" onerror="if (this.src != 'error.jpg' && this.attribute('src') != 'error.jpg') this.src = 'error.jpg';" />

Hash's user avatar

Hash

4,6575 gold badges20 silver badges39 bronze badges

answered Jan 26, 2015 at 15:36

Seb's user avatar

3

3 solutions for this:

Consider following html file:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
   <title>Document</title>
</head>
<body>
   <img id="imageId">
   <script src="setimage.js"></script>
</body>
</html>

Solution one :
reference this block of JS code inside the body tag of your html as
<script src="setimage.js"></script>

and set the src paths, the first is the one if there is an error, the next is the one you hope works first time :)

var img = document.getElementById("imageId")
       img.onerror = () => {
           img.src= "../error.png";
       }
       img.src= "../correct.webp.png";

Solution two:

this solution is almost the same, instead you will call the method, again at the end of your body within a script tag, but would supply the paths there.

function setImageWithFallback(mainImgPath, secondaryImgPath) {
   var img = document.getElementById("imageId")
       img.onerror = () => {
           img.src= mainImgPath;
       }
       img.src= secondaryImgPath;
}

Solution three:
if its just a single image, this would be the simplest :) simply set the onerror at the img tag

<img id="imageId" src="../correct.webp.png" 
onerror="if (this.src != '../error.png') this.src = '../error.png';">

answered Aug 13, 2021 at 22:55

robskaar's user avatar

robskaarrobskaar

3842 silver badges12 bronze badges

If you are using Angular 1.x you can include a directive that will allow you to fallback to any number of images. The fallback attribute supports a single url, multiple urls inside an array, or an angular expression using scope data:

<img ng-src="myFirstImage.png" fallback="'fallback1.png'" />
<img ng-src="myFirstImage.png" fallback="['fallback1.png', 'fallback2.png']" />
<img ng-src="myFirstImage.png" fallback="myData.arrayOfImagesToFallbackTo" />

Add a new fallback directive to your angular app module:

angular.module('app.services', [])
    .directive('fallback', ['$parse', function ($parse) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var errorCount = 0;

                // Hook the image element error event
                angular.element(element).bind('error', function (err) {
                    var expressionFunc = $parse(attrs.fallback),
                        expressionResult,
                        imageUrl;

                    expressionResult = expressionFunc(scope);

                    if (typeof expressionResult === 'string') {
                        // The expression result is a string, use it as a url
                        imageUrl = expressionResult;
                    } else if (typeof expressionResult === 'object' && expressionResult instanceof Array) {
                        // The expression result is an array, grab an item from the array
                        // and use that as the image url
                        imageUrl = expressionResult[errorCount];
                    }

                    // Increment the error count so we can keep track
                    // of how many images we have tried
                    errorCount++;
                    angular.element(element).attr('src', imageUrl);
                });
            }
        };
    }])

answered Jun 14, 2017 at 10:24

Rob Evans's user avatar

Rob EvansRob Evans

6,7004 gold badges38 silver badges56 bronze badges

0

Using Jquery you could do something like this:

$(document).ready(function() {
    if ($("img").attr("src") != null)
    {
       if ($("img").attr("src").toString() == "")
       {
            $("img").attr("src", "images/default.jpg");
       }
    }
    else
    {
        $("img").attr("src", "images/default.jpg");
    }
});

answered Jun 11, 2009 at 12:57

Jon's user avatar

JonJon

5,88810 gold badges38 silver badges40 bronze badges

For any image, just use this javascript code:

if (ptImage.naturalWidth == 0)
    ptImage.src = '../../../../icons/blank.png';

where ptImage is a <img> tag address obtained by document.getElementById().

Flexo's user avatar

Flexo

86.4k22 gold badges189 silver badges271 bronze badges

answered Feb 5, 2012 at 8:10

José Esteves Pereira's user avatar

Google threw out this page to the «image fallback html» keywords, but because non of the above helped me, and I was looking for a «svg fallback support for IE below 9», I kept on searching and this is what I found:

<img src="base-image.svg" alt="picture" />
<!--[if (lte IE 8)|(!IE)]><image src="fallback-image.png" alt="picture" /><![endif]-->

It might be off-topic, but it resolved my own issue and it might help someone else too.

answered Aug 17, 2017 at 7:43

orghu's user avatar

orghuorghu

6847 silver badges25 bronze badges

In addition to Patrick’s brilliant answer, for those of you who are searching for a cross-platform angular js solution, here you go:

<object type="image/png" data-ng-attr-data="{{ url || 'data:' }}">
    <!-- any html as a fallback -->
</object>

Here’s a plunk where I was playing trying to find the right solution: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview

answered Apr 19, 2018 at 19:23

sunsay's user avatar

sunsaysunsay

1,4902 gold badges21 silver badges28 bronze badges

If you have created dynamic Web project and have placed the required image in WebContent then you can access the image by using below mentioned code in Spring MVC:

<img src="Refresh.png" alt="Refresh" height="50" width="50">

You can also create folder named img and place the image inside the folder img and place that img folder inside WebContent then you can access the image by using below mentioned code:

<img src="img/Refresh.png" alt="Refresh" height="50" width="50">

answered Mar 12, 2019 at 17:39

Yoshita Mahajan's user avatar

I am adding loading=»lazy» to img tag. In some cases it works..

answered Jan 14, 2022 at 9:57

Alex Sorkin's user avatar

here is a simple Jquery that worked for me

        $(image).on('error', function(event) {
            imgage.attr('src', 'your_image.png');})

answered Jan 22, 2022 at 13:50

zzzHarry's user avatar

Well!!
I found this way convenient , check for the height attribute of image to be 0, then you can overwrite the src attribute with default image:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image

 image.setAttribute('src','../icons/<some_image>.png');
  //check the height attribute.. if image is available then by default it will 
  //be 100 else 0
  if(image.height == 0){                                       
       image.setAttribute('src','../icons/default.png');
  }

answered Feb 7, 2018 at 11:53

suhail's user avatar

This is actually tricky, especially if you plan on returning an image url for use cases where you need to concatenate strings with the onerror condition image URL, e.g. you might want to programatically set the url parameter in CSS.

The trick is that image loading is asynchronous by nature so the onerror doesn’t happen sunchronously, i.e. if you call returnPhotoURL it immediately returns undefined bcs the asynchronous method of loading/handling the image load just began.

So, you really need to wrap your script in a Promise then call it like below. NOTE: my sample script does some other things but shows the general concept:

returnPhotoURL().then(function(value){
    doc.getElementById("account-section-image").style.backgroundImage = "url('" + value + "')";
}); 


function returnPhotoURL(){
    return new Promise(function(resolve, reject){
        var img = new Image();
        //if the user does not have a photoURL let's try and get one from gravatar
        if (!firebase.auth().currentUser.photoURL) {
            //first we have to see if user han an email
            if(firebase.auth().currentUser.email){
                //set sign-in-button background image to gravatar url
                img.addEventListener('load', function() {
                    resolve (getGravatar(firebase.auth().currentUser.email, 48));
                }, false);
                img.addEventListener('error', function() {
                    resolve ('//rack.pub/media/fallbackImage.png');
                }, false);            
                img.src = getGravatar(firebase.auth().currentUser.email, 48);
            } else {
                resolve ('//rack.pub/media/fallbackImage.png');
            }
        } else {
            img.addEventListener('load', function() {
                resolve (firebase.auth().currentUser.photoURL);
            }, false);
            img.addEventListener('error', function() {
                resolve ('https://rack.pub/media/fallbackImage.png');
            }, false);      
            img.src = firebase.auth().currentUser.photoURL;
        }
    });
}

Нередко бывает, что при загрузке веб-страницы какие-то изображения оказываются недоступны, и браузер услужливо рисует на их месте пустые контуры. В этой статье я расскажу, как обработать ошибки загрузки изображений и подставить вместо них другое изображение.

Допустим, у нас на сервере лежит файл: https://svgshare.com/i/7ck.svg

Рассмотрим следующий пример. Сколько изображений будет показано?

<html>
  <head>
    <meta charset="utf-8" content="text/html; charset=utf-8"/>
    <style>
      html, body {
        height: 100px;
        width: auto;
      }
    </style>
  </head>

  <body>
    <div class="achievement-image">
      <img src="https://svgshare.com/i/7ck.svg">
      <img src="//svgshare.com/i/7ck.svg">
      <img src="svgshare.com/i/7ck.svg">
      <img src="7ck.svg">
    </div>
  </body>
</html>

Одно, максимум два.

Ответ зависит от того, как открыть этот код. Если разместить его на сервере, вроде https://myserver.com, мы увидим первые два изображения. Если же сохранить его локально и открыть в браузере html файл — только одно. Для ясности я покажу, во что превращаются ссылки из атрибута src в обоих случаях.

В случае сервера https://myserver.com имеем:

https://svgshare.com/i/7ck.svg
https://svgshare.com/i/7ck.svg
https://myserver.com/svgshare.com/i/7ck.svg
https://myserver.com/7ck.svg

В случае локального файла из file:///home/leksa/html/example.html имеем:

https://svgshare.com/i/7ck.svg
file://svgshare.com/i/7ck.svg
file:///home/leksa/html/svgshare.com/i/7ck.svg
file:///home/leksa/html/7ck.svg

Для отслеживания и реакции на успешную или неуспешную загрузку изображения HTML предлагает нам два события, доступных для тега img: onload и onerror. Как следует из названия, первое событие возникает, когда изображение было загружено, а второе, когда что-то пошло не так.

Модифицируем наш код и проверим работу этих событий в консоли браузера.

<div class="achievement-image">
  <img src="https://svgshare.com/i/7ck.svg" 
       onload="console.log('load 1')" onerror="console.log('error 1')">
  <img src="//svgshare.com/i/7ck.svg"
       onload="console.log('load 2')" onerror="console.log('error 2')">
  <img src="svgshare.com/i/7ck.svg"
       onload="console.log('load 3')" onerror="console.log('error 3')">
  <img src="7ck.svg"
       onload="console.log('load 4')" onerror="console.log('error 4')">
</div>

Как и ожидалось, последние три изображения спровоцировали событие onerror. Назначим на него свой обработчик (потребуется подключить библиотеку JQuery) и подменим атрибут src на адрес желаемого изображения.

$(document).ready(function() {
  $(".image-container img").each(function(key, item) {
    $(item).on("error", function() {
      showDefaultImage(this);
    }).attr('src', $(item).attr('src'));
  });
});

function showDefaultImage(img) {
  $(img).attr('src', 'https://svgshare.com/i/7bo.svg');
  $(img).off("error");
}

В интернете есть много примеров решения данной задачи, однако есть один важный момент, о котором часто забывают. Хочу обратить ваше внимание на вызов

$(item).on(...).attr('src', $(item).attr('src'))

после назначения обработчика. Атрибут src устанавливается в то же значение, в котором он изначально был. Зачем это нужно?

Для ответа на этот вопрос вернёмся к последовательности возникновения событий.

  • Событие DOMContentLoaded возникает, когда построено дерево DOM, а также загружены и выполнены все скрипты. При этом внешние ресурсы, включая изображения и стили, могут быть ещё не загружены.
  • Событие load объекта window возникает, когда страница со всеми ресурсами была загружена.
  • Событие ready специфично для JQuery, согласно документации, оно аналогично событию DOMContentLoaded, то есть не дожидается загрузки мультимедийного контента.

Откроем код, приведённый ниже, и посмотрим на вывод в консоли браузера.

<html>
  <head>
    <meta charset="utf-8" content="text/html; charset=utf-8"/>

    <style>
      html, body {
        height: 100px;
        width: auto;
      }
    </style>

    <script>
      $(document).on("DOMContentLoaded", function() {
        console.log("document loaded");
      });
      $(window).on("load", function() {
        console.log("content loaded");
      });
      $(document).ready(function() {
        console.log(“JQuery ready”);
      });
    </script>
  </head>

  <body>
    <div class="image-container">
      <img src="https://svgshare.com/i/7ck.svg" 
           onload="console.log('load 1')" onerror="console.log('error 1')">
      <img src="//svgshare.com/i/7ck.svg"
           onload="console.log('load 2')" onerror="console.log('error 2')">
      <img src="svgshare.com/i/7ck.svg"
           onload="console.log('load 3')" onerror="console.log('error 3')">
      <img src="7ck.svg"
           onload="console.log('load 4')" onerror="console.log('error 4')">
    </div>
  </body>
</html>


 

Тут есть кое-что интересное. Вопреки ожиданием, событие ready срабатывает после загрузки всего контента (включая изображения), аналогично событию load. А значит, на момент создания обработчиков, события error и load уже произошли, и обработчики никогда не будут вызваны.

В браузере firefox картина примерно такая же.

Это вынуждает прибегать к не совсем красивому решению, когда мы заставляем браузер загрузить изображения заново, уже после привязки обработчиков, путём установки атрибута src в то же самое значение.

Окончательный вариант кода приведён ниже (живой пример).
 

<html>
  <head>
    <meta charset="utf-8" content="text/html; charset=utf-8"/>

    <style>
      html, body {
        height: 100px;
        width: auto;
      }
    </style>

    <script>
      // $(document).on("DOMContentLoaded", function() {
      $(document).ready(function() {
        $(".image-container img").each(function(key, item) {
          $(item).on("error", function() {
            showDefaultImage(this);
          }).attr('src', $(item).attr('src'));
        });
      });

      function showDefaultImage(img) {
        $(img).attr('src', 'https://svgshare.com/i/7bo.svg');
        $(img).off("error");
      }
    </script>
  </head>

  <body>
    <div class="image-container">
      <img src="https://svgshare.com/i/7ck.svg">
      <img src="//svgshare.com/i/7ck.svg">
      <img src="svgshare.com/i/7ck.svg">
      <img src="7ck.svg">
    </div>
  </body>
</html>

Cover image for HTML fallback images on error

Chris Bongers

The other day I encountered some issues with images for external sources not loading.

I saved a link to someone’s Twitter profile image in this case. When the user changes this image, it doesn’t auto reflect the new one.

So I decided to look into fallback images.
And it’s surprisingly easy.

What we want to achieve:

  • Load the image
  • If it doesn’t load, show the fallback

Note: Alternatively, you could decide to remove the image

HTML on error fallback images

Let’s set up a sample HTML experiment.

<img
  src="https://images.pexels.com/photos/163822/color-umbrella-red-yellow-163822.jpeg"
/>

Enter fullscreen mode

Exit fullscreen mode

This will load an Photo by Pixabay from Pexels (a stock image site).

This will work perfectly, but now let’s try and destroy it by randomly adding some numbers to the image.

<img
  src="https://images.pexels.com/photos/163822/color-umbrella-red-yellow-00000.jpeg"
/>

Enter fullscreen mode

Exit fullscreen mode

With this, we get the super annoying broken image.

Broken image

So what can we do when this happens?
We can use the onerror attribute on the image to set a fallback.

It works like this:

<img
  src="https://images.pexels.com/photos/163822/color-umbrella-red-yellow-00000.jpeg"
  onerror="this.onerror=null; this.src='https://images.pexels.com/photos/159868/lost-cat-tree-sign-fun-159868.jpeg'"
/>

Enter fullscreen mode

Exit fullscreen mode

We use the onerror to set the error to null and set the src of the image to a fallback.
In our case, a photo of a missing cat.

Note: It’s not a great practice to rely on external images. You ideally want to have the fallback image locally in the file system, so it’s a reliable fallback.

You can see it in action in the following CodePen.
The first image loads, and the second one is broken.

Thank you for reading, and let’s connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

If you develop and push to production, you most likely have experienced broken images on your dev instance. You may have also run into broken images on production due to user/admin error, etc. Wouldn’t it be nice if you could display a default placeholder image without having to take a hit on your file system, checking to see if it exists, before your load each image?

Thanks to Ryan Stille’s recent blog post, I have been made aware of a (not so great) solution. Apparently the img tag, along with others such as object, script and style have error events. We can listen for the error event and load a placeholder image in place of the default browser error image.

The catch is the event handler must be attached before the browser fires the error event. Also, the error event may not be correctly fired when the page is served locally. The error event relies on HTTP status codes and will generally not be triggered if the URL uses the “file:” protocol.

In simpler terms, the only solution I’ve found is to either place the event handler inline with the img tag, assign the img src via JavaScript or recursively search each image’s complete state or naturalWidth once the window is done loading. I’ve tried using “$().on()” and “$(“img”).error()” both after the document loads and inline before the element is loaded. However neither solution works, which doesn’t make much sense to me.

I am including multiple examples because this is not a one-solution-fits-all scenario.

The first working example displays a placeholder image using the inline method if the error event is thrown. Notice the onerror handler is reset when it’s run so you don’t run into an infinite loop if your placeholder image also fails.

<img src="images/myImage.jpg" alt="My Image" onerror="imageError(this)">

<script>
function imageError(element) {
    element.onerror='';
    element.src='/images/imgPlaceholder.png';
}
</script>

The second working example, also using the inline method, will call a script that will report the broken image and load the placeholder. The script returns an image with the proper image MIME type.

<img src="images/myImage.jpg" alt="My Image" onerror="imageError(this)">

<script>
function imageError(element) {
    element.onerror='';
    element.src='logBrokenImage.cfm?image=' + element.src';
}
</script>

The third working example uses JavaScript to load the image and displays a placeholder if that image fails to load.

<img id="myImage">

<script>
    $('img').one( 'error', function() {
        $(this).attr( 'src', '/images/imgPlaceholder.png' );
    });

    $('#myImage').attr( 'src', 'myImage.jpg' );
</script>

The final working example recursively searches through each image after the window loads. If it finds the state incomplete or the natural width of the image is 0, then it loads the placeholder image.

<img src="images/myImage.jpg" alt="My Image">

<script>
$(window).load(function() {
    $('img').each(function() {
        if ( !this.complete || ( !$.browser.msie && ( typeof this.naturalWidth == "undefined" || this.naturalWidth == 0 ) ) ) {
            this.src = '/images/imgPlaceholder.png';
        }
    });
});
</script>

#error, #event, #handler, #img, #javascript, #jquery, #src

Понравилась статья? Поделить с друзьями:
  • Img attributes style как изменить
  • Imfbigupgrade exe системная ошибка
  • Imessage activation error occurred during activation
  • Imei как изменить на телефоне самостоятельно
  • Iis ошибка 500 внутренняя ошибка сервера