• HTMLImageElement (<img>) の width/height は、実際の表示サイズに引っ張られて値が変化する。(明示的に指定してても引っ張られる!)
  • 元の大きさを取得したければ naturalWidth/naturalHeight を見る。
  1. 結論から
  2. 実験1: 普通に取得
  3. 実験2: 間接的に縮小して取得
  4. 実験3: 間接的に縮小&明示的に指定して取得

結論から

レスポンシブ対応してるサイト作ってて、レイアウトから画像がはみ出さないよう <img>max-width:100% とか設定してたら、縮小されてる時に img.width に依存するJavaScriptがうまく動かなかった。

確認してみたところ、どうも HTMLImageElementwidth/height には原寸ではなく実際の表示サイズがセットされてる模様。しかも、明示的に指定してても、必ず実際の表示サイズがセットされてるっぽい。

元の大きさを取得したければ、以下のように naturalWidth/naturalHeight を見る。

var img = document.getElementById('id-of-img');
console.log(img.naturalWidth);
console.log(img.naturalHeight);

実験1: 普通に取得

↓の多幸感に溢れた画像は、原寸が 256 × 256 px。

この <img> タグの大きさを、以下のようにJavaScriptで取得する。

HTML
<img src="img.gif" alt="" id="img1" />
JavaScript
var img = document.getElementById('img1');
console.log(img.width);          // -> 256
console.log(img.height);         // -> 256
console.log(img.naturalWidth);   // -> 256
console.log(img.naturalHeight);  // -> 256
console.log(img.style.width);    // -> (カラ文字)
console.log(img.style.height);   // -> (カラ文字)

imgwidth/height および naturalWidth/naturalHeightは、もちろん 256。

style は設定していないので、img.stylewidth/height はカラ文字となり、取得できなかった。

実験2: 間接的に縮小して取得

↓の画像は、さっきと同じ画像。ただし <img> の外側のボックスをスタイルシートで 128 × 128px にしたうえで、<img>stylemax-width:100% を指定しているので、小さく表示されてる。

<img>stylewidth/height を直接指定せず、遠回しに表示上のサイズを変えてるのがミソ。この <img> タグの大きさを、先程と同様にJavaScriptで取得する。

HTML
<div style="width:128px; height:128px;">
	<img src="img.gif" alt="" id="img2" style="max-width:100%;" />
</div>
JavaScript
var img = document.getElementById('img2');
console.log(img.width);          // -> 128
console.log(img.height);         // -> 128
console.log(img.naturalWidth);   // -> 256
console.log(img.naturalHeight);  // -> 256
console.log(img.style.width);    // -> (カラ文字)
console.log(img.style.height);   // -> (カラ文字)

imgwidth/height が 128 となることに注目! 実際の表示サイズが反映されてる。

naturalWidth/naturalHeight なら元の大きさ 256 を取得できる。

実験3: 間接的に縮小&明示的に指定して取得

じゃあ <img>width/height をHTML上で明示的に指定してたらどうなるの? というわけで、先程の条件に追記して実験。

  • <img> の外側のボックスをスタイルシートで 128 × 128px にする。
  • <img>stylemax-width:100% を指定する。
  • <img>width/height に 200 を指定する。

ハチャメチャ。max-width のせいで縦長になっちゃってる。そしてこの <img> タグの大きさを、先程と同様にJavaScriptで取得すると……。

HTML
<div style="width:128px; height:128px;">
	<img src="img.gif" alt="" id="img3" style="max-width:100%;" width="200" height="200" />
</div>
JavaScript
var img = document.getElementById('img3');
console.log(img.width);                   // -> 128
console.log(img.height);                  // -> 200
console.log(img.naturalWidth);            // -> 256
console.log(img.naturalHeight);           // -> 256
console.log(img.style.width);             // -> (カラ文字)
console.log(img.style.height);            // -> (カラ文字)
console.log(img.getAttribute('width'));   // -> "200"
console.log(img.getAttribute('height'));  // -> "200"

明示的に指定したにも関わらず、imgwidth が 128 になってる。ということは、HTMLImageElementwidth/height には、本当に実際の表示サイズがセットされてるらしい。

一応、HTML上で明示的に設定した width/heightgetAttribute() で取得できたけど、HTMLの <img> とJavaScriptの HTMLImageElement は同一視しないほうがよさそうだ。