Detecting if images are disabled in browsers

Posted on Friday, 21 October 2011 by Steve Faulkner

I received an email from an old friend and colleague pointing out that with images disabled in the browser, the support information in the data tables on HTML5Accessibility.com disappears. An issue and an embarrassment! This has now been fixed.

Detecting if images are disabled in browsers

I went searching on the internet to find a suitable script for detecting if images are displayed or not. I found this post Use Javascript to detect if images are disabled.The script appears to work fine in Internet Explorer and FireFox, but not in Chrome and Opera ans Safari. It also looked a bit complex for me. What I wanted was a simple method that worked cross browser.

The problem

To be clear, what I am referring to in this case is inline images, though the same method will work with CSS images as long as there is one img element on the page to test. On HTML5Accessibility.com the following pattern is being used, the CSS for which I borrowed from CSS in Action: Invisible Content Just for Screen Reader Users.

HTML

<img src="images/cross.png" width="16" height="16" alt="">
<span class="hidden">Not supported</span>

CSS

span.hidden

{
position:absolute;
left:-10000px;
top:auto;
width:1px;
height:1px;
overflow:hidden;
}

This works great if you have images enabled (the presence of the images are not announced by screen readers due to the use of alt=”” and the text is announced, although it is not on screen), but not if you don’t, because the images are not displayed and the text is still hidden off screen, d’oh!

Major modification 19/08/2012

Thanks to @thierrykoblentz for providing a much simpler method (offsetWidth) to check whether images are enabled/disabled!

After testing more found offsetWidth alone was unreliable in IE, so have gone back to more complex check using readyState in conjunction with offsetWidth. Thanks anyway @thierrykoblentz!

Tested in Firefox/Opera/Chrome/IE on windows all work fine!

Try the updated test page in your fave browser/OS.

The noImage() script

function noimage()
{

if ((document.getElementById('flag').offsetWidth==1&&document.getElementById('flag').readyState=='complete')||(document.getElementById('flag').offsetWidth==1&&document.getElementById('flag').readyState==undefined))

{
var objHead = document.getElementsByTagName('head');
var objCSS = objHead[0].appendChild(document.createElement('link'));
objCSS.rel = 'stylesheet';
objCSS.href = 'alt.css';
objCSS.type = 'text/css';
}

}

//add to body

<body onload="noimage();checkHC();">
<img id="flag" src="clear.gif" alt="">

What  the script does

It checks the value of the offsetWidth property of a 1 x 1 pixel image added to the top of the page. if the check returns true, images are enabled, if false images are disabled.   If images are enabled  it adds and external style sheet containing the style rules to hide the text off screen.  By default the text and images are visible, so that the text will be visible if users have JavaScript disabled. 

Checking for Windows High Contrast

It also seemed like a good idea to have the text visible when Windows high contrast mode is enabled (shift + alt + print screen keys), so I added the following function (borrowed from the AOL AXS script library), that checks if Windows high contrast mode is enabled. If it is enabled both images and text are displayed.

function checkHC() {

var e,c;
//Create a test div
e=document.createElement("div");
//Set its color style to something unusual
e.style.color="rgb(31,41,59)";
//Attach to body so we can inspect it
document.body.appendChild(e);
//Use standard means if available, otherwise use the IE methods
c=document.defaultView?document.defaultView.getComputedStyle(e,null).color:e.currentStyle.color;
//Delete the test DIV
document.body.removeChild(e);
//get rid of extra spaces in result
c=c.replace(/ /g,"");
//Check if we got back what we set
//If not we are in high contrast mode
if (c!="rgb(31,41,59)"){
return true;
}
}

I then wrapped then wrapped it all together and added it to HTML5Accessibility.com. There is also a test page available. The scripting is by no means elegant, if anybody wants to improve it please do!


About Steve Faulkner

Steve is the Senior Web Accessibility Consultant and Technical Director, TPG Europe. He joined The Paciello Group in 2006 and was previously a Senior Web Accessibility Consultant at Vision Australia. He is the creator and lead developer of the Web Accessibility Toolbar accessibility testing tool. Steve is a member of several groups, including the W3C HTML Working Group and the W3C Protocols and Formats Working Group. He is an editor of several specifications at the W3C including HTML 5.1, Using WAI-ARIA in HTML and HTML5: Techniques for providing useful text alternatives. He also develops and maintains HTML5accessibility

Comments

  1. You don’t need the hidden span for the text. You can use the ALT attributes with:
    img:after{content: ” (” attr(alt) “)”;}

  2. Hi Artor,
    I can’t get that to work with img. I also think that text added via CSS is not well supported by assistive tech.

  3. Using naturalWidth to detect supports works in Opera for me, but it appears that due to caching of images, we report the width even when disabled. I’ve filed a bug for this (CORE-42117) and will look into fixing it. In the mean-time, one way to work around the issue is to ensure that the image is never cached, either by HTTP headers or a hack like this:

    <img src=”test.png”>
    <script>
    var img = document.querySelector(‘img’);
    img.src += ‘?nocache=’+Math.random();
    window.onload = function() {
    var imgEnabled = document.querySelector(‘img’).naturalWidth > 0;
    alert(imgEnabled);
    };
    </script>

  4. However, Mathieu ‘p01′ Henri came up with a much neater solution that works at least in Opera:

    var imagesOn = (function(){var i=new Image();i.src=’data:image/gif,GIF89a%01%00%01%00%80%00%00%00%00%00%FF%FF%FF!%F9%04%01%00%00%00%00%2C%00%00%00%00%01%00%01%00%00%02%01D%00%3B';return!!i.width})();

    (It appears that caching doesn’t apply here, it works even when I toggle images on and off a few times.)

  5. Hi Joe,
    yes I actually worked it out prior to publishing the article, but forgot to take out the sentence about not being able to disable images in Safari. Thanks for bringing it to my attention.

  6. I would suggest trying make make it work without the checks for window.opera, this is the kind of thing that ends up being copied around and in some cases makes sites break when we fix the bugs they originally worked around. Not sure if this is such a case. Probably the short imagesOn snippet is enough for all browsers that support data: URIs, not just Opera.

    I also fixed the bug I filed about naturalWidth/Height returning something > 0 if the image happened to be cached, which I assume is what messed up your testing in Opera initially.

  7. Hi Philip,

    I would suggest trying make make it work without the checks for window.opera

    I did try, but found that the value of imagesOn was always false in IE and sometimes true in firefox when it should have been false. So needed some way to isolate the checking of the variable to Opera. If you can work out a better way that does not rely upon the window.opera check please share. I state in the article my JavScript skills are limited.

  8. correct, :before and :after only work on elements that can have content (read:html) inside. So not on IMG, BR, HR, INPUT and such.
    Opera supports
    IMG { content: attr(alt);} that I misuse for not displaying/requesting images on mobile if needed.

  9. Hi Steve,

    I used to use a much simpler technique. So looking at your solution I’m now wondering if I’m not missing something with my basic approach.
    Back in the day, when we used a shim for various reasons, I was checking the width of that image:

    document.getElementById(“shim”).offsetWidth !== 1)

    With images turned off, I would not get that 1 pixel width and that seemed to work fine. I used the logo of the site when not using a shim (any image that I knew would belong to the page).

  10. Hi Thierry,
    It may well be that there is a simpler solution, I didn’t find one when searching. I quickly tried out your code snippet but didn’t get a difference with images turned off/on. Can you provide a more complete test?

  11. Using JavaScript to detect if images are disabled in a browser?

    Isn’t it likely that a browser with images disabled also has JavaScript turned off?

  12. Hi John,
    I have no idea if there is a strong relationship between having images turned off and JavaScript disabled, do you? Note that if Javascript is disabled the default display is for the text to be dsiplayed along with the image. So in either case when Javascript is disabled I have implemented it so if images on or off the user gets the required information.

  13. Hi Steve,

    I tried the following snippet – on this page – in the console:

    alert(document.getElementsByTagName('img')[0].offsetWidth !== 60)

    The first image seems to be an avatar image which is 60 pixels wide. With “image on” the above returns false, but with “image off” (i.e. disabled via the dev toolbar), the above returns true.

  14. Hi Steve,

    Sorry to highjack your article like this; feel free to delete this comment :)

    But two things I wanted to add:

    – There is no need for the “shim” per say. Authors can avoid the extra HTTP request by using any existing image in the document (as long as the check is done against that image’s width).

    – Instead of plugging a styles sheet, which also creates an extra HTTP request, authors can plug a class on the html or body element and then style accordingly. For example:

    .hidden {
    ...
    }
    /**
    * Images are off we reset the previous rule
    */
    .imageOff .hidden {
    position:static;
    width:auto;
    height:auto;
    }

    The other advantage of this approach is that it should reduce the risk of a Flash Of Unstyle Content (since the element would be hidden from the start).

  15. Hi Thierry, no problem, I wrote the post to resolve a problem, you and others have been helping to make the solution better, any input is appreciated! I will update the script accordingly when I get a chance.

Comments for this post are closed.

Recent Posts

See all posts in the blog archive

Having worked in accessibility for quite some time I can tell you that TPG's Steve Faulkner is one of the top technical accessibility talents, and leaders, in the field and I have no reservations in giving him my endorsement.

Richard Schwerdtfeger, Distinguished Engineer and CTO for Accessibility of IBM Software