HTML5 Responsive Design: How to Determine the Real Dimensions of an Image in JavaScript

Responsive design is one of the most useful web techniques to appear during the past few years. A website layout can adapt to a device’s screen and look beautiful no matter what resolution is used.

Responsive images are normally coded without width and height attributes, e.g.


<img id="myimage" src="myimage.jpg" alt="my image" />

The image will size itself and we can add a little CSS to ensure an image cannot exceed its real dimensions.


#myimage
{
	max-width: 100%;
}

It’s often necessary to manipulate these scaled images in JavaScript; perhaps for a game, lightbox or animation effect. In those situations, you need to determine the image’s real height and width. However, the width and height properties return the current (resized) dimensions:


var myimage = document.getElementById("myimage");
var w = myimage.width;	// current width, e.g. 400px
var h = myimage.height;	// current height, e.g. 300px

Fortunately, the modern HTML5 browsers provide two further properties:


var rw = myimage.naturalWidth;	// real image width
var rh = myimage.naturalHeight;	// real image height

The properties are supported in IE9, Firefox, Chrome, Safari and Opera. Note the image must be fully downloaded before the dimensions are available. To ensure it’s ready, you can either attach a “load” event to the window or the image itself or check the image’s .complete property before testing the dimensions.

IE6, 7 and 8

.naturalWidth and .naturalHeight are not supported in the older editions of Internet Explorer. We can still determine the real dimensions by loading the image into an in-memory object and examining the standard width and height properties, e.g.


var myimage = document.getElementById("myimage");

if (typeof myimage.naturalWidth == "undefined") {
	// IE 6/7/8
	var i = new Image();
	i.src = myimage.src;
	var rw = i.width;
	var rh = i.height;
}
else {
	// HTML5 browsers
	var rw = myimage.naturalWidth;
	var rh = myimage.naturalHeight;
}

I’m continually amazed to discover these new properties and methods; they make our lives a little easier.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Ian

    Nice find!

    In your example, you have used ‘i.src = myimage.src;’. Is that required to achieve the dimensions or are you providing an example of what properties are available?

    • http://www.optimalworks.net/ Craig Buckler

      That line loads the image into an image object by setting the same source.

  • kaf

    why use the naturalwidth/naturalheight way at all when the ie way works in all browsers and is not a hack?
    Seems like extra code for no purpose….

    • http://www.deathshadow.com deathshadow

      EXACTLY what I was thinking… though I’d probably put a onload method on “i” just in case the image isn’t done loading when the script fires… since then it wouldn’t be complete in the cache. That would hinge on when you go in asking for the width/height though.

    • http://www.optimalworks.net/ Craig Buckler

      You certainly could do that. But there would be no need if you were only supporting HTML5 browsers, say for a canvas-based game.

  • http://bigyouthworld.com aditi khan

    it seems to be good with new features

  • http://markadrake.com Mark Drake

    Wow, it’s kind of like you were looking over my back the past day or two! I had to write a hover / click effect for an image that scaled it (maintaining ratio) depending on screen size. I didn’t know HTML 5 added those attributes! I had to load the image into an object off screen to manipulate it correctly (your IE6/7/8 hack).

    Thanks for the tip Craig.

  • http://andywalpole.me/ Andy Walpole

    Good work Craig

    I took your function and made it a bit more user-friendly:

    elemDimensions = function(doc) {
    if (typeof doc.naturalWidth == “undefined”) {
    // IE 6/7/8
    var i = new Image();
    return {
    width: i.width,
    height: i.height
    }
    } else {
    return {
    width: doc.naturalWidth,
    height: doc.naturalHeight
    }
    }
    };

    elemDimensions(document.getElementById(“div-here”)).width;
    elemDimensions(document.getElementById(“div-here”)).height;