【2020年夏】imgタグにはwidthとheight属性を書くのがいいらしい

Advertisement

そうなんです。

2020年夏、ページの読み込み中にレイアウトがシフトしないように、img要素にはwidthheight属性を記述するのがいいらしいんです。

<img src="link/to/image.jpg" width="300" height="400" alt="画像の説明">

その昔、これが普通の時代もあったんですけどね。レスポンシブな時代にはwidthheight属性を書かないのが一般的(?)になっていました。また、widthheight属性が記述してあってもCSSでwidth: 100%; height: auto;が指定されているとレイアウトシフトが発生してしまっていました。

参考: img要素のサイズ属性の記述の有無についてのTwitterのアンケート

なんでいまさら?

なぜなら、2019年の後半にブラウザにレイアウトシフトを回避するための新たな機能が実装されたからです。これにより、ブラウザはimg要素に指定されたwidthheight属性の値をもとにアスペクト比を計算して、ページ読み込み中に画像のスペースをより正確に保持できるようになりました。

サイズ属性を記述しない場合のページレンダリング

img要素にwidthheight属性を記述しない場合、下のGIF動画のように画像が読み込まれた後に、下にあるテキストが大幅に移動します。

ブラウザが画像のあるページを読み込んでいる様子をキャプチャしたGIF動画。img要素のサイズ属性を記述しない場合

サイズ属性を記述した場合のページレンダリング

img要素にwidthheight属性を記述した場合、下のGIF動画のようにはじめから画像のスペースが保持されていて、画像の読み込み後にも下にあるテキストの位置は変わりません。

ブラウザが画像のあるページを読み込んでいる様子をキャプチャしたGIF動画。img要素のサイズ属性を記述した場合

ちなみに、GIF動画で表示されている画像にはCSSでwidth: 100%; height: auto;が指定されているので、レスポンシブに対応した画像の表示になっています。

レスポンシブの場合どのサイズを記述すれば良いのか

レスポンシブなサイトの場合どのサイズを記述するか迷うかもしれませんが、ここで重要なのは画像のアスペクト比(縦横比)です。なので、元画像のサイズをそのまま記述しても良いですし、デスクトップでの表示をベースにサイズ属性を書いてもOKです。

Lazy-loadingにも有効

画像の読み込みを遅延させるlazy-loadingを使用する際も、画像のサイズ属性の記述がないとレイアウトシフトが発生します。それを避けるためにもサイズ属性の記述は重要です。でなければLazy-loadingのメリットがレイアウトシフトによって帳消しになってしまうことも考えられます。

<img src="link/to/image.jpg" width="300" height="400" loading="lazy" alt="画像の説明">

ページ内リンクでページ下部に飛べる場合や、高速スクロールができるホイール付きのマウスとかだと、画像が読みこまれる前にページ下部に移動できてしまうので、レイアウトシフトが顕著に邪魔になる場合があるんですよね。あれもユーザ体験をかなり損なうので注意したいですね

モダンなブラウザに実装済み

この機能はFirefox 71 Chrome 79 、SafariのTechnology Preview Release 99 から実装されていて、2020年7月現在、Chromiumベースの最新のEdgeを含むメジャーなブラウザでサポートされています。

このレイアウトシフトのことを英語では「Jank」って呼ぶんですけど、Jankによってページが読みにくくなったり、ブラウザの描画のパフォーマンスにも影響が出ます。img要素にwidthheight属性を記述するだけで、それが回避できるんだから書かない理由はないですよね。

画像が読み込まれたタイミングでレイアウトがシフトして、読んでた文章を見失ってしまった、なんてことありませんか?あれが起こると頭が混乱するし、同じところを読み返す必要があって無駄に時間を取られたりするんですよね。

むかーし、昔…

その昔、imgタグにはwidthheight属性を書くのがあたりまえの時代がありました。僕がウェブ制作を始めたのは1990年台の後半ですが、そのころはimg要素にwidthheightが記述されているか必ずチェックしていた気がします。

でも、レスポンシブWebデザインによって画像を可変で表示すようになって、img要素にwidthheight属性は記述せずに、CSSで幅を100%に指定する以下のような書き方が広まりました。

img {
  width: 100%;
  height: auto;
}

widthheight属性が記述してあってもCSSでwidth: 100%; height: auto;が指定されていると、画像がダウンロードされるまでブラウザが高さを判別できなくてレイアウトシフトが発生してしまっていました。

そして2020年、この記述方法によって多くなったJankの問題が解決されたわけです。

これを提案してくれたウェブコミュニティの方々(たぶんMozillaのJenさん )もすごいし、それをスピーディに実装した各ブラウザの開発者の方々もすごいなぁと思います。Chrome、Safari、Firefoxのすべてにこんなにスピーディに実装されるのって珍しい気がします(そんなことない?)

問題があったら、みんなで議論して、解決策を見出して、実装していく。ウェブのこういうところが本当に大好きです(ここで告白w)。だからやめられない。

注意点もいくつか

このすばらしいブラウザ機能ですが、いくつか注意点もあります。

  • CSSでwidth: 100%; height: auto;width: auto; height: 100%;を指定しないと縦横比が狂ってしまう
  • img要素しかサポートされてない(videoiframeなどでは、まだサポートされていない)
  • srcsetで複数の画像を指定する場合、すべての画像の縦横比が同じなら問題ないが違う場合は要注意
  • picture要素で違う縦横比の画像を使う場合は(まだ)使えない(2019年10月時点で仕様をまとめている状態)

注2) 2022年7月の時点で、picture要素で違うアスペクト比の画像を使う場合はimgsource要素の両方にwidth/heightを記述すれば良くなりました。詳しくはこちらの記事をご覧ください。

注1)たとえば、WebPを使うためにpicture要素を使って同じ縦横比の画像を表示したい場合は有効のようです。FirefoxとChromeでどのような挙動になるのか確認して情報を追加しておきました。

詳しい仕組みを知りたい方は、英語ですが以下のページやビデオを参考にしてみてください。日本語字幕がないですが、Jenさんのビデオが一番わかりやすいかな。Smashing Magazineの記事にはかなりの詳細が書かれています。

picture要素でWebPを使う場合

たとえば、WebPを使うためにpicture要素を使って以下の記述をした場合、img要素のwidthheight属性の記述がしっかり反映された挙動になっていました。同じ縦横比の画像を使うのであれば問題ないようです。

<picture>
  <source srcset="img/muffins-and-coffee.webp" type="image/webp">
  <img src="img/muffins-and-coffee.jpg" width="800" height="480" alt="画像の説明">
</picture>

こちら、取り急ぎFirefox 78とChrome 83で確認しました。

検証用のデモページ

以下に検証用のデモページへのリンクをはっておきます。

以下のブラウザで確認済み

いまのところ、開発ツールにスロットリング機能がついている以下のブラウザで確認しました。

  • Firefox 78.0.1(Mac/Win)
  • Chrome 83.0.4103.116(Mac/Win)
  • Chromium版Edge 83.0.478.56

その後、Safari 14.1で確認ができました。Safari 14.1ではAdditional Tools for XcodeのNetwork Link Conditionerというツールを使ってスロットリングをして確認できました。

さいごに

ということで、画像のサイズ属性は記述していきましょう!

(このブログで使ってる画像はサイズ属性いれてないんだよな。WordPressをアップデートして自動で記述されるようになおさなきゃ…)

更新情報

About the author

Rriverのステッカーが貼られたMacBookの向こうにいる自分のMemojiの似顔絵

「明日のウェブ制作に役立つアイディア」をテーマにこのブログを書いています。アメリカの大学を卒業後、ボストン近郊のウェブ制作会社に勤務。帰国後、東京のウェブ制作会社に勤務した後、ウェブ担当者として日英バイリンガルのサイト運営に携わる。詳しくはこちら

ウェブ制作・ディレクション、ビデオを含むコンテンツ制作のお手伝い、執筆・翻訳のご依頼など、お気軽にご相談ください。いずれも日本語と英語で対応可能です。まずは、Mastodon @rriver@vivaldi.net Twitter @rriver 、またはFacebook までご連絡ください。