Inputting a default image in case the src attribute of an html <img> is not valid?

HtmlImage

Html Problem Overview


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

Html Solutions


Solution 1 - Html

You asked for an HTML only solution...

http://www.w3.org/TR/html4/strict.dtd">

Object Test

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

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.

Solution 2 - Html

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';">

Updated with jacquargs error guard

Updated: CSS only solution I recently saw [Vitaly Friedman][1] 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">
<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 { ...

[1]: https://www.smashingmagazine.com/2016/03/dirty-tricks-dark-corners-front-end-slides-pdf/ "Dirty Tricks From The Dark Corners Of Front-End"

Solution 3 - Html

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

Solution 4 - Html

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>

Solution 5 - Html

<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.

Solution 6 - Html

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

Solution 7 - Html

<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

Solution 8 - Html

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.

Solution 9 - Html

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.

Solution 10 - Html

angular2:

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

Solution 11 - Html

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

Solution 12 - Html

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="..." />

Solution 13 - Html

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-fallIndex="1"
    data-fallback1="some_image.png"
    data-fallback2="some_image.jpg">

JavaScript

function fallBackImg(elem){
    elem.onerror = null;
    let index = +elem.dataset.fallIndex;
    elem.src = elem.dataset[`fallback${index}`];
    index++;
    elem.dataset.fallbackindex = index;
}

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

Solution 14 - Html

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: https://stackoverflow.com/questions/16671428/how-to-style-an-images-alt-attribute

Solution 15 - Html

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';" />

Solution 16 - Html

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);
				});
			}
		};
	}])

Solution 17 - Html

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';">

Solution 18 - Html

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");
    }
});

Solution 19 - Html

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().

Solution 20 - Html

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.

Solution 21 - Html

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

Solution 22 - Html

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">

Solution 23 - Html

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

Solution 24 - Html

here is a simple Jquery that worked for me

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

Solution 25 - Html

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');
  }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAhmedView Question on Stackoverflow
Solution 1 - HtmlPatrick McElhaneyView Answer on Stackoverflow
Solution 2 - HtmlSvendView Answer on Stackoverflow
Solution 3 - Htmlamit bakleView Answer on Stackoverflow
Solution 4 - HtmlbaphoView Answer on Stackoverflow
Solution 5 - HtmllambacckView Answer on Stackoverflow
Solution 6 - HtmlPim JagerView Answer on Stackoverflow
Solution 7 - HtmlEmiliano BarbozaView Answer on Stackoverflow
Solution 8 - Htmlmanish kumarView Answer on Stackoverflow
Solution 9 - HtmlObieView Answer on Stackoverflow
Solution 10 - Htmluser3601578View Answer on Stackoverflow
Solution 11 - HtmleithedView Answer on Stackoverflow
Solution 12 - HtmlKevin RobatelView Answer on Stackoverflow
Solution 13 - HtmlRagerView Answer on Stackoverflow
Solution 14 - HtmlXofoView Answer on Stackoverflow
Solution 15 - HtmlSebView Answer on Stackoverflow
Solution 16 - HtmlRob EvansView Answer on Stackoverflow
Solution 17 - HtmlrobskaarView Answer on Stackoverflow
Solution 18 - HtmlJonView Answer on Stackoverflow
Solution 19 - HtmlJosé Esteves PereiraView Answer on Stackoverflow
Solution 20 - HtmliorguView Answer on Stackoverflow
Solution 21 - HtmlsunsayView Answer on Stackoverflow
Solution 22 - HtmlYoshita MahajanView Answer on Stackoverflow
Solution 23 - HtmlAlex SorkinView Answer on Stackoverflow
Solution 24 - HtmlzzzHarryView Answer on Stackoverflow
Solution 25 - HtmlsuhailView Answer on Stackoverflow