naturalWidth and naturalHeight work in Chrome 4+, Edge 12+, Firefox 2+, Safari 3.1+, Opera 9+, Samsung Internet 4+, and Internet Explorer 9-11. See full support.

Prince Dewani
May 6, 2026
naturalWidth and naturalHeight are read-only HTMLImageElement properties from the WHATWG HTML Standard that return an image's intrinsic dimensions in CSS pixels. Both work in Chrome 4+, Edge 12+, Firefox 2+, Safari 3.1+ macOS, Safari 3.2+ iOS, Opera 9+, Samsung Internet 4+, and Internet Explorer 9 to 11, while IE 5.5 to 8 never added support.
This guide covers what they are, the browsers that support them, how to use them in JavaScript, the difference from width, and the common pitfalls.
naturalWidth and naturalHeight are read-only properties of the HTMLImageElement interface defined by the WHATWG HTML Standard. They return the intrinsic, density-corrected width and height of the image source in CSS pixels. The values are 0 until the browser finishes decoding the image data.
naturalWidth and naturalHeight are Baseline Widely Available and ship in every modern desktop and mobile browser. Internet Explorer 9 through 11 also support both properties; IE 5.5 to 8 are the only browsers that never added them.
Chrome supports naturalWidth and naturalHeight from Chrome 4 on Windows, macOS, Linux, ChromeOS, and Android. The values are corrected for device pixel ratio, so a 2x source on a retina screen still reports its CSS pixel size. Chrome on low-end Android can downgrade image resolution, and naturalWidth then reflects the downgraded pixel size.
Microsoft Edge supports naturalWidth and naturalHeight from Edge 12 on Windows, macOS, and Linux. Edge Legacy 12 to 18 shipped both properties through the EdgeHTML engine, and Chromium-based Edge 79 onward inherits the same support from Blink.
Firefox supports naturalWidth and naturalHeight from Firefox 2 on Windows, macOS, Linux, and Android. Gecko reports 0 for SVG sources that carry only a viewBox without explicit width and height attributes, which matches the WHATWG specification but trips up authors who expect a pixel value.
Safari supports naturalWidth and naturalHeight from Safari 3.1 on macOS and Safari 3.2 on iOS and iPadOS. Both values are returned in CSS pixels, density-corrected for retina displays. Mobile Safari behaves identically to desktop Safari, including the WebKit handling of broken images, where the values stay at 0 instead of throwing.
Opera supports naturalWidth and naturalHeight from Opera 9 on Windows, macOS, and Linux. Opera Mobile picks up support from Opera Mobile 10. Both desktop and mobile Opera now ride the Blink engine, so the values match Chrome's behavior on every platform.
Samsung Internet supports naturalWidth and naturalHeight from Samsung Internet 4 on Galaxy phones and tablets. The browser inherits Chromium's density correction, so the values match what Chrome on the same Android device would return for the same image source.
The legacy Android Browser supports naturalWidth and naturalHeight from Android Browser 2.1. Modern Chrome for Android continues the same support across every Android version Google still ships. Android Browser 2.0 and earlier did not expose the properties.
Internet Explorer 9, 10, and 11 support naturalWidth and naturalHeight on Windows. IE 5.5 through 8 never shipped either property, so reading img.naturalWidth in those builds returns undefined. Microsoft has retired Internet Explorer, so most modern QA pipelines can ignore the IE 5.5 to 8 path entirely.
Note: naturalWidth and naturalHeight have edge cases on SVG sources, broken images, and density-corrected pixels. Test it on real browsers and OS with TestMu AI. Try TestMu AI free!
Read the properties off any HTMLImageElement after the image has finished decoding. The values are valid inside a load event handler, after the boolean complete property is true, or after an awaited img.decode() call.
// 1. Read intrinsic size after the image element finishes loading.
const heroImg = document.querySelector('img.hero');
heroImg.addEventListener('load', () => {
console.log('Intrinsic width:', heroImg.naturalWidth, 'CSS px');
console.log('Intrinsic height:', heroImg.naturalHeight, 'CSS px');
});
// 2. Preload an image with the Image constructor and read its size off-DOM.
const probe = new Image();
probe.addEventListener('load', () => {
const aspectRatio = probe.naturalWidth / probe.naturalHeight;
console.log('Aspect ratio:', aspectRatio.toFixed(3));
});
probe.src = '/static/banner.jpg';
// 3. Guard against the not-yet-loaded case before reading the value.
function getIntrinsicSize(img) {
if (img.complete && img.naturalWidth > 0) {
return { width: img.naturalWidth, height: img.naturalHeight };
}
return null;
}naturalWidth and width look interchangeable but they answer different questions. naturalWidth describes the source asset; width describes how the asset is rendered on the page. Same story for naturalHeight versus height.
| Dimension | naturalWidth / naturalHeight | width / height |
|---|---|---|
| What it returns | Intrinsic source dimensions in CSS pixels | Rendered dimensions on the page in CSS pixels |
| Density correction | Yes, density-corrected for the device pixel ratio | Yes, but reflects the layout box, not the source |
| Read or write | Read-only | Writable; mirrors the HTML width and height attributes |
| Affected by CSS | No, ignores CSS rules on the element | Yes, returns the layout-box size after CSS |
| Value before load | 0 until the image finishes decoding | The HTML width attribute, or 0 if unset |
| Common use case | Aspect-ratio math, lazy-loaded layout, image probing | Setting or reading the rendered size on the page |
Cross-browser support is solid, but the value is empty in more situations than authors expect. Most production bugs trace back to reading the property too early, mis-handling SVGs, or forgetting that the src reset clears the cached value.
In my experience, the trap that bites teams hardest is the cached-image case in single-page apps: a tab restore or a soft route change runs the layout code before the listener attaches, and naturalWidth is already populated but the load event never re-fires, so the dependent layout never recalculates.
All naturalWidth and naturalHeight version numbers and platform notes in this guide come from these primary sources:
Did you find this page helpful?
More Related Hubs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance