PageSourceSearch

https://terkel.github.io/srcset-sizes/

html terkel.github.io collected 2026-10-03 10:04:07 UTC 40,440 bytes, 579 lines download raw bytes

1<!DOCTYPE html>
2<html lang="ja">
3<head>
4<meta charset="UTF-8">
5<title>srcsetとsizes</title>
6<meta name="description" content="レスポンシブ画像のための新しい手法、srcsetとsizesを紹介">
7<meta name="viewport" content="width=device-width, initial-scale=1">
8<link rel="apple-touch-icon" href="/apple-touch-icon.png">
9<link rel="preconnect" href="https://s3-ap-northeast-1.amazonaws.com" crossorigin>
10<link rel="stylesheet" href="./css/minimal.css">
11<script>
12(function(d) {
13    var config = {
14    kitId: 'wvd1kpq',
15    scriptTimeout: 3000,
16    async: true
17    },
18    h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+" wf-inactive";},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+=" wf-loading";tk.src='https://use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)
19})(document);
20</script>
20
21</head>
22<body>
23
24<main>
25
26<header role="banner">
27    <h1>srcset<span class="amp">と</span>sizes</h1>
28    <div class="meta">
29        <p class="author">エリック・ポーティス</p>
30        <p class="translator">鈴木丈<span class="separator">=</span>訳</p>
31    </div>
32</header>
33
34<section id="part-1">
35
36<h2>パート1:メディア・クエリのどこがまずいのか?</h2>
37
38<p>そう、もし君がウェブサイトを作っている時代が<a href="http://1997.webhistory.org/www.lists/www-talk.1993q1/0182.html">1993年2月23日</a>から<a href="http://alistapart.com/article/responsive-web-design/">2010年5月25日</a>の間だったら、画像の扱いなんてチョロかったね!&ensp;それはこんなふうに単純だった。</p>
39
40<ul>
41<li>幅の固定されたレイアウトをにらみつける</li>
42<li>画像が<em>きっかり</em>何ピクセルかを測る&#x2015;&#x2015;その画像は<em>あらゆる</em>ユーザーの画面で<em>変わらない</em>スペースを占めることになる</li>
43<li>Photoshopのエンジンをかける</li>
44<li>画像をさっき測ったとおりのサイズで「ウェブ用に保存」する</li>
45<li>それを<code>&lt;img&gt;</code>タグでマークアップする</li>
46<li>グラスにビールを注ぎ(または新鮮なグリンピースの缶を開け)、仕事がうまくいったことを祝う</li>
47</ul>
48
49<figure>
50    <img alt="穴の大きさを巻き尺で測る豆男"
51        src="./img/measuring-hole/half.png"
52        srcset="./img/measuring-hole/full.png 2118w,
53                ./img/measuring-hole/half.png 1059w,
54                ./img/measuring-hole/quarter.png 530w,
55                ./img/measuring-hole/8th.png 265w">
56</figure>
57
58<figure>
59    <img alt="「画像」と書かれたブロックをサイズに合わせて切り出す豆男"
60        src="./img/measuring-image/half.png"
61        srcset="./img/measuring-image/full.png 2448w,
62                ./img/measuring-image/half.png 1224w,
63                ./img/measuring-image/quarter.png 612w,
64                ./img/measuring-image/8th.png 306w">
65</figure>
66
67<figure>
68    <img alt="ブロックをハンマーで穴にはめ込む豆男"
69        src="./img/hammering/half.png"
70        srcset="./img/hammering/full.png 2232w,
71                ./img/hammering/half.png 1116w,
72                ./img/hammering/quarter.png 558w,
73                ./img/hammering/8th.png 279w">
74</figure>
75
76<figure>
77    <img alt="グリンピースの缶を手に満面の笑みを浮かべる豆男"
78        src="./img/yay-peas/half.png"
79        srcset="./img/yay-peas/full.png 1613w,
80                ./img/yay-peas/half.png 807w,
81                ./img/yay-peas/quarter.png 404w,
82                ./img/yay-peas/8th.png 202w">
83</figure>
84
85<p>ときおり聡明なる預言者が荒野から現れては、この手法に潜む問題について<a href="http://alistapart.com/article/dao/">深遠な真実</a>を説くこともあった。それでもこのやり方は、20年もの間、ウェブ・デザイナーを生業とするものたちに受け入れられてきた。</p>
86
87<p>しかし、時代は変わる。</p>
88
89<p><time datetime="2010-05-25">4年前</time>、イーサン・マーコットが<a href="http://alistapart.com/article/responsive-web-design/">ある記事を書いた</a>。<time datetime="2010-06-07">その13日後</time>、スティーヴ・ジョブズは<a href="http://ja.wikipedia.org/wiki/IPhone_4">ある携帯電話</a>を発表した。突如として「<a href="http://unstoppablerobotninja.com/entry/fluid-images">フルード(流動的)</a>」で「<a href="http://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%86%E3%82%A3%E3%83%8A%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4">レティナ(高精細)</a>」な画像が重要になった。そしてそれ以来、そこらじゅうから<a href="https://www.google.com/search?q=site:lists.whatwg.org%20responsive%20images">歯ぎしり</a>が聞こえてくる。</p>
90
91<figure>
92    <video id="oops" loop autoplay muted controls>
93        <source src="./video/oops/oops-1080.mp4" type="video/mp4">
94        <source src="./video/oops/oops-1080.ogv" type="video/ogg">
95    </video>
96</figure>
97
98<p>フルードとかレティナとかレスポンシブとかいった画像を実装することになったとき、僕らはまずどうするだろうか。直感的に、レスポンシブ・レイアウトで使うのと同じ道具に手を伸ばすんじゃないかな。そう、メディア・クエリだ!</p>
99
100<figure>
101    <img alt="3つのサイズのブロックに張り紙をする豆男。「小さい穴にはこれ」「中くらいの穴にはこれ」「大きい穴にはこれ」"
102        src="./img/media-queries/half.png"
103        srcset="./img/media-queries/full.png 2221w,
104                ./img/media-queries/half.png 1111w,
105                ./img/media-queries/quarter.png 556w,
106                ./img/media-queries/8th.png 278w">
107</figure>
108
109<p>ブラウザーは、まだ読み込んでないウェブサイトについてはなんにも知らないけど、自分たちが描画をおこなう内部の環境については、つねに把握している。ビューポートのサイズや、ユーザーの画面の解像度や、そういったこと。メディア・クエリの狙いは、ウェブ・ディベロッパーが特定の環境に向けてなにかできるようにしよう、というものだ。もしビューポートの幅が1,000px以上なら、サイドバーを左側に表示せよ。そうでなければ、そいつをメインのコンテンツの下に。もしユーザーの画面がレティナなら大きな画像を使え。そうでなければ小さなやつ。</p>
110
111<p>カンタンカンタン。</p>
112
113<figure>
114    <img alt="フォークとナイフを手にグリンピースをほおばる豆男"
115        src="./img/easypeas/half.png"
116        srcset="./img/easypeas/full.png 2258w,
117                ./img/easypeas/half.png 1129w,
118                ./img/easypeas/quarter.png 565w,
119                ./img/easypeas/8th.png 283w">
120</figure>
121
122<p>でも残念なことに、レスポンシブ画像では話が違ってくる。多くの場合、実際に画像のソースを取ってくるのにメディア・クエリを使うと「<a href="http://www.xanthir.com/b4Su0">クソまずいこと</a>」になるんだ。</p>
123
124<figure>
125    <img alt="グリンピースをほおばったままびっくりする豆男。「へっ?」"
126        src="./img/gulp/half.png"
127        srcset="./img/gulp/full.png 2244w,
128                ./img/gulp/half.png 1122w,
129                ./img/gulp/quarter.png 561w,
130                ./img/gulp/8th.png 281w">
131</figure>
132
133<p>
133メディア・クエリを使ってレスポンシブ画像のソースを取ってくるとまずいことになるのはなぜか、その理由をちょっと探ってみよう。まず、ほとんどのデザイナーは、ページのレイアウトをレスポンシブに変化させるとき、1つの変数(ビューポートの幅)をもとにすることに慣れきってる。でもレスポンシブ<em>画像</em><sup id="fnref-1"><a href="#fn-1">1</a></sup>を扱うとなると、3つもの変数がからんでくるんだ。</p>
134
135<ul>
136<li>レイアウトにおける画像の(CSSピクセルでの)描画サイズ</li>
137<li>画面密度</li>
138<li>サイズの異なる画像ファイルそれぞれの寸法</li>
139</ul>
140
141<p>つまり、メディア・クエリがややこしくなるってこと。</p>
142
143<p>この3つがわかれば、問題の解決はどうってことない。ひと組のソースがあったら、その中で寸法が<var>描画サイズ</var>×<var>画面密度</var>より大きくて、かついちばん小さなやつを選べばいい。</p>
144
145<p>だがしかし!&ensp;残念ながら<var>描画サイズ</var>ってやつは突き止めるのにちょっと手こずるんだ。ウェブ・ディベロッパーはそいつを知ることが<em>できない</em>。なぜなら、画像のサイズを固定せずフレキシブルにすると、画像は伸び縮みするので、レスポンシブ・レイアウトでは<var>描画サイズ</var>はあらゆる可能性が考えられる。そしてびっくりするかもしれないけど、ブラウザーが画像の読み込みをはじめるとき、ブラウザーも<var>描画サイズ</var>をまだ知らないんだ。<var>描画サイズ</var>が決まるのはそのページのCSS次第なんだけど、CSSが解析されるのは、画像の読み込みがはじまったずっとあとなんだ。</p>
146
147<p>メディア・クエリを画像ソースに当てはめると、この<var>描画サイズ</var>がわからないという問題をうまく避けられるように見える。メディア・クエリによって<var>描画サイズ</var>は次の2つから求められるようになり……</p>
148
149<ul>
150<li>ビューポートの寸法</li>
151<li>ビューポートに対する画像の相対的なサイズ</li>
152</ul>
153
154<p>そして製作者は、メディア・クエリでビューポートの寸法と画面密度だけを指定すればいい。そのほかの全部について、<s>いくつかの</s>たくさんの<s>カンタンな</s>ややこしい計算を済ませたあとでね。</p>
155
156<p>どんな計算かって?&ensp;ちょっとためしてみよう。</p>
157
158<figure>
159    <img alt="学校の机で、電卓と鉛筆を手に準備万端の豆男"
160        src="./img/study-up/half.png"
161        srcset="./img/study-up/full.png 2244w,
162                ./img/study-up/half.png 1122w,
163                ./img/study-up/quarter.png 561w,
164                ./img/study-up/8th.png 281w">
165</figure>
166
167<p>(注意。僕はシンプルに書こうと努めてるけど、これから親愛なる読者諸君のお目にかける例は、メディア・クエリの計算の過程がどれだけ退屈かつ間違いやすいかを示すためだけにあるんだ。だからもしそのことが飲み込めたと思ったら、すぐに<a href="#part-2">パート2</a>に飛んでもぜんぜんかまわないよ。)</p>
168
169<p>手元に同じ画像の3つのバージョンがあるとしよう。</p>
170
171<ul>
172<li><code>large.jpg</code>(1024 × 768)</li>
173<li><code>medium.jpg</code>(640 × 480)</li>
174<li><code>small.jpg</code>(320 × 240)</li>
175</ul>
176
177<p>そして、そのうちの1つを取り出し、フレキシブルなグリッドの中で読み込みたいとする。グリッドのカラムは、はじめは1つだけど、ビューポートが大きければ3つに切り替わる。<a href="http://ericportis.com/assets/2014-03-24-srcset-sizes/wolves/">こんなふうに</a>。</p>
178
179<p>さらに、1xと2xの<code>デバイスピクセル比</code>をサポートしたい。</p>
180
181<p>さてメディア・クエリをどうやって組み立てるか?&ensp;最初から見ていこう。</p>
182
183<p><code>large.jpg</code>は本当に必要なときにだけ読み込まれるべきだ。つまり<code>
183small.jpg</code>と<code>medium.jpg</code>がどちらも小さすぎるときだけ。もっと正確に言うと、次の式が成り立つときだけ、<code>large.jpg</code>が読み込まれてほしい。</p>
184
185<pre><code><var>描画される幅</var> × <var>画面密度</var>
186    &gt; <var>次に小さいファイルの幅</var>
187</code></pre>
188
189<p>僕たちの例では、<var>描画される幅</var>は単純に<var>ビューポートの幅</var>に対するパーセンテージだ。したがって、</p>
190
191<pre><code><var>描画される幅</var> =
192    <var>ビューポートに対する画像の相対的な幅</var> ×
193    <var>ビューポートの幅</var>
194</code></pre>
195
196<p>次に小さいファイルは<code>medium.jpg</code>なので、</p>
197
198<pre><code><var>次に小さいファイルの幅</var> = 640px
199</code></pre>
200
201<p>こいつらをひとまとめにすると次の不等式になる。</p>
202
203<pre><code><var>ビューポートに対する画像の相対的な幅</var> ×
204<var>ビューポートの幅</var> ×
205<var>画面密度</var>
206  &gt; 640px
207</code></pre>
208
209<p><var>ビューポートの幅</var>を中心にすると次のようにも書ける。</p>
210
211<pre><code><var>ビューポートの幅</var> &gt;
212  640px ÷
213  ( <var>ビューポートに対する画像の相対的な幅</var> ×
214    <var>画面密度</var> )
215</code></pre>
216
217<p>そしてここからメディア・クエリを組み立てるには、<var>ビューポートに対する画像の相対的な幅</var>と<var>画面密度</var>がとる可能性のある値すべてについて、それぞれ対応する<var>ビューポートの幅</var>を求めなきゃいけない。</p>
218
219<p><var>ビューポートに対する画像の相対的な幅</var>は次の2つのうちどちらかだ。ブレイクポイント(36em)に届く前なら100<a href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">vw</a>、それ以降なら33.3vw。</p>
220
221<p><var>画面密度</var>については……なんというか、<a href="http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density">たくさんの可能性が考えられる</a>んだけど、僕たちがサポートする<code>device-pixel-ratio</code>は1xと2xだけと決めた。</p>
222
223<p><var>ビューポートに対する画像の相対的な幅</var>の可能性が2つに、<var>画面密度</var>の可能性が2つ。これらをかけ合わせると4つのシナリオを考えなã
223ã‚ƒã„けないってことになる。ひとつずつ見ていこう。</p>
224
225<h3 id="1x-でブレイクポイント以下の場合">1xでブレイクポイント以下の場合</h3>
226
227<p>ここでのブレイクポイントは36emなので、次のことはわかってる。</p>
228
229<pre><code><var>ビューポートの幅</var> &lt; 36em
230</code></pre>
231
232<p>「<var>ビューポートに対する画像の相対的な幅</var> = 100vw」と「<var>画面密度</var> = 1x」を、さっき考えた不等式に入れてみよう。</p>
233
234<pre><code><var>ビューポートの幅</var> &gt;
235  640px ÷ ( 100vw × 1x ) = 640px = 40em
236</code></pre>
237
238<p>この2つを合わせると、ありえない結果になる。</p>
239
240<pre><code>36em &gt; <var>ビューポートの幅</var> &gt; 40em
241</code></pre>
242
243<p>つまり僕たちはこのシナリオは捨ててしまっていい&#x2015;&#x2015;1xでレイアウトがシングル・カラムのとき、<code>large.jpg</code>が必要になることはない。 </p>
244
245<h3 id="2x-でブレイクポイント以下の場合">2xでブレイクポイント以下の場合</h3>
246
247<p>まずはさっきと同じ。</p>
248
249<pre><code><var>ビューポートの幅</var> &lt; 36em
250</code></pre>
251
252<p>でも今度は2xに当てはめる。</p>
253
254<pre><code><var>ビューポートの幅</var> &gt;
255  640px ÷ ( 100vw × 2x ) = 320px = 20em
256</code></pre>
257
258<p>この2つを組み合わせると……</p>
259
260<pre><code>36em &gt; <var>ビューポートの幅</var> &gt; 20em
261</code></pre>
262
263<p>つまり、2xの画面で<code>large.jpg</code>を読み込んでほしいのは、ビューポートがこの範囲内だった場合ということになる。</p>
264
265<h3 id="1x-でブレイクポイント以上の場合">1xでブレイクポイント以上の場合</h3>
266
267<p>今回はブレイクポイント以上なので、こう。</p>
268
269<pre><code><var>ビューポートの幅</var> &gt; 36em
270</code></pre>
271
272<p>そして1xの画面では3カラム・レイアウトなので、こう。</p>
273
274<pre><code><var>ビューポートの幅</var> &gt;
275  640px ÷ ( 33.3vw × 1x ) = 1920px = 120em
276</code></pre>
277
278<p>ビューポートが120emより大きいならもちろん36emより大きいわけだから、36emの方は忘れちゃっていい。1xの画面で<code>large.jpg</code>を読み込みたいのは、次の場合ということになる。</p>
279
280<pre><code><var>ビューポートの幅</var> &gt; 120em
281</code></pre>
282
283<p>よし、次で最後だ!</p>
284
285<h3 id="2x-でブレイクポイント以上の場合">2xでブレイクポイント以上の場合</h3>
286
287<pre><code><var>ビューポートの幅</var> &gt; 36em
288</code></pre>
289
290<p>……そして……</p>
291
292<pre><code><var>ビューポートの幅</var> &gt;
293  640px ÷ ( 33.3vw × 2x ) = 960px = 60em
294</code></pre>
295
296<p>……2xの画面で<code>large.jpg</code>を読み込むのは、この場合。</p>
297
298<pre><code><var>ビューポートの幅</var> &gt; 60em
299</code></pre>
300
301<p>さあ、こいつらをメディア・クエリでひとまとめにしよう。</p>
302
303<pre><code>( (min-device-pixel-ratio: 1.5) and (min-width: 20.001em) and (max-width: 35.999em) ) or
304( (max-device-pixel-ratio: 1.5) and (min-width: 120.001em) ) or
305( (min-device-pixel-ratio: 1.5) and (min-width: 60.001em) )
306</code></pre>
307
308<p>これと同じ計算を<code>medium.jpg</code>用に繰り返すのは、読者の練習問題としておこう。</p>
309
310<p>こうして出来上がったのが、<code>&lt;picture&gt;</code>の最初の提案にのっとったこんなマークアップ。</p>
311
312<pre><code>&lt;picture&gt;
313
314    &lt;source src="large.jpg"
315            media="( (min-device-pixel-ratio: 1.5) and (min-width: 20.001em) and (max-width: 35.999em) ) or
316                 ( (max-device-pixel-ratio: 1.5) and (min-width: 120.001em) ) or
317                 ( (min-device-pixel-ratio: 1.5) and (min-width: 60.001em) )" /&gt;
318    &lt;source src="medium.jpg"
319            media="( (max-device-pixel-ratio: 1.5) and (min-width: 20.001em) and (max-width: 35.999em) ) or
320                 ( (max-device-pixel-ratio: 1.5) and (min-width: 60.001em) ) or
321                 ( (min-device-pixel-ratio: 1.5) and (min-width: 10.001em) )" /&gt;
322    &lt;source src="small.jpg" /&gt;
323
324    &lt;!-- fallback --&gt;
325    &lt;img src="small.jpg" alt="A rad wolf" /&gt;
326
327&lt;/picture&gt;
328</code></pre>
329
330<p>うっ、頭痛が……!</p>
331
332<p>なにしろこのマークアップの山は、<code>device-pixel-ratio</code>が2より大きいか1より小さい場合をサポートしてないし、2と1の間の
332値にしてもサポートは不十分。もし<code>device-pixel-ratio</code>をより広くサポートしようとしたら、考えなきゃいけないシナリオもぐんと増える。</p>
333
334<p>そしてこのマークアップの<em>最悪</em>なところは、そこに含まれる値を1つでも変更しようとしたときにあきらかになる。ソース画像のサイズ、サポートするデバイスの解像度、または画像のサイズに関わるレイアウトのアスペクト比&#x2015;&#x2015;これらを変更するたび、僕たちはあの計算をぜんぶ、やり直さいないといけない。</p>
335
336<figure>
337    <img alt="食べたグリンピースをトイレで吐く豆男"
338        src="./img/barf/half.png"
339        srcset="./img/barf/full.png 2244w,
340                ./img/barf/half.png 1122w,
341                ./img/barf/quarter.png 561w,
342                ./img/barf/8th.png 281w">
343</figure>
344
345<p>さあ、<a href="#part-2">パート2</a>へ急ごう。</p>
346
347</section>
348
349<section id="part-2">
350
351<h2>パート2:srcset+sizes=最高!</h2>
352
353<p>どうやらメディア・クエリはこの仕事には向いてないらしい。さて、どうしよう?</p>
354
355<p>ここで、さっき見たレスポンシブ画像の基本となる変数のリストに戻って、それらが<em>いつ</em>変化し、<em>誰が何を知っているのか</em>を考えてみよう。</p>
356
357<table>
358    <thead>
359        <tr><th>変数</th><th>製作者が<br>コードを書くとき</th><th>ブラウザーが<br>ページを読み込むとき</th></tr>
360    </thead>
361    <tbody>
362        <tr><th>ビューポートの寸法</th><td class="no">知らない</td><td class="yes">知ってる</td></tr>
363        <tr><th>ビューポートに対する画像の相対的な幅</th><td class="yes">知ってる</td><td class="no">知らない</td></tr>
364        <tr><th>画面密度</th><td class="no">知らない</td><td class="yes">知ってる</td></tr>
365        <tr><th>ソース・ファイルの寸法</th><td class="yes">知ってる</td><td class="no">知らない</td></tr>
366    </tbody>
367</table>
368
369<p>一方が「知ってる」のとき、もう一方は必ず「知らない」である点に注目!&ensp;製作者とブラウザーが知ってることは異なり、互いにおぎない合ってる。我らは鍵の神、彼らは門の神。僕らのパワーをひとつに合わせれば……</p>
370
371<p>このギャップをどう埋めるか?</p>
372
373<p>メディア・クエリは災害対策の詰め合わせみたいなものだ。僕たちはブラウザーにこう話しかける。「なあ、僕はビューポートがどのくらいの大きさになるかわからないんだけど、でももしこのくらいの大きさなら、このファイルを使ってほしい。もしもっと大きければ、こっち。あと、こっちのやつは画面がレティナだった場合に使うけど、でもレイアウトが3カラムに切り替わったらそれじゃなくて……」。僕らは様々な可能性についてのラベルをファイルに貼っていく。そのラベルに書いてある内容は、ブラウザーは「知ってる」ことだけど、コードを書いてる僕らは「知らない」ことだ。</p>
374
375<p>でもさっき見たとおり、実際にこれをやるのはとても骨が折れる。</p>
376
377<p>じゃあ、もしこの状態をひっくり返したらどうだろう?</p>
378
379<p>ブラウザーに対してごちゃごちゃした災害対策を提供するかわりに、シンプルに<em>ブラウザーが知らないことを教えてやったら</em>?&ensp;つまり、ビューポートに対する画像の相対的なサイズと、ソース・ファイルの寸法を。<em>僕ら</em>はこのどちらも知ってる。もしこの知ってることをブラウザーと共有できたら、ブラウザーはソースを選ぶのに必要なことがすべて手に入ることになるんじゃない?</p>
380
381<p>だよね!&ensp;実際、<a href="http://picture.responsiveimages.org/"><code>&lt;picture&gt;</code>仕様の最新にしてもっとも偉大なる草稿</a>の、<code>sizes</code>属性と、<code>srcset</code>の中の<code>w</code>ディスクリプターは、まさにそのためにあるんだ。さっきの表をもう一度見てみよう。</p>
382
383<table>
384    <thead>
385        <tr><th>変数</th><th>製作者が<br>コードを書くとき</th><th>ブラウザーが<br>ページを読み込むとき</th></tr>
386    </thead>
387    <tbody>
388        <tr><th>ビューポートの寸法</th><td class="no">知らない</td><td class="yes">知ってる</td></tr>
389        <tr><th>
389ビューポートに対する画像の相対的な幅</th><td class="yes">知ってる</td><td><s class="no">知らない</s> <span class="yes">知ってる!</span> <code>sizes</code>があれば!</td></tr>
390        <tr><th>画面密度</th><td class="no">知らない</td><td class="yes">知ってる</td></tr>
391        <tr><th>ソース・ファイルの寸法</th><td class="yes">知ってる</td><td><s class="no">知らない</s> <span class="yes">知ってる!</span> <code>srcset</code>があれば!</td></tr>
392    </tbody>
393</table>
394
395<figure>
396    <img alt="「sizes」と「srcset」の間にかかる虹と豆男。満面の笑みを浮かべ、両手を広げている"
397        src="./img/rainbow/half.png"
398        srcset="./img/rainbow/full.png 2208w,
399                ./img/rainbow/half.png 1104w,
400                ./img/rainbow/quarter.png 552w,
401                ./img/rainbow/8th.png 276w">
402</figure>
403
404<p>これを詳しく見る前に、確認しておきたいことが3つある。</p>
405
406<p>まず第一に、これらを実装しているブラウザーはまだない。見通しは明るい<sup id="fnref-2"><a href="#fn-2">2</a></sup>けど、仕様はまだ流動的だ(画像のサイズが流動的なのといっしょ)。だから使うのはちょっと待ってほしい。今はまだ動かないけど、もうすぐ使えるようになる。</p>
407
408<p>ふたつめ。かつて、<a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-May/035855.html"><code>srcset</code></a>と呼ばれるレスポンシブ画像の提案があった。僕たちが話題にしている新しい提案も、<em>同じく<code>srcset</code>と呼ばれる</em>属性をもとにしている。古い<code>srcset</code>も新しい<code>srcset</code>も、カンマ区切りの<abbr>URL</abbr>のリストで<code>w</code>ディスクリプターを使うけど、それぞれの<code>w</code>は<em>まったく違う意味</em>なんだ!&ensp;古い<code>w</code>はメディア・クエリのショートハンドで、<em>ビューポート</em>の幅をあらわしてた。一方、新しい<code>w</code>は<em>ファイル</em>の幅をあらわす。僕らはこれから新しい<code>w</code>について見ていくので、今のところは、『メン・イン・ブラック』の記憶消去装置みたいなやつを使って、<code>srcset</code>と<code>w</code>について知ってることをぜんぶ忘れてほしい。</p>
409
410<figure>
411    <img alt="ピカッ"
412        src="./img/men-in-black/half.png"
413        srcset="./img/men-in-black/full.png 2236w,
414                ./img/men-in-black/half.png 1118w,
415                ./img/men-in-black/quarter.png 559w,
416                ./img/men-in-black/8th.png 280w">
417</figure>
418
419<p>忘れたかな?&ensp;よし。</p>
420
421<p>みっつめは、以前の<code>&lt;picture&gt;</code>仕様を期待を込めて追っかけてたひとへのお知らせ。新しい<code>&lt;picture&gt;</code>仕様でも、メディア・クエリによるソースの切り替えと、ソースURLでの解像度ディスクリプターは有効だ。もし<a href="http://usecases.responsiveimages.org/#art-direction">アート・ディレクション</a>したり<a href="http://usecases.responsiveimages.org/#device-pixel-ratio-based-selection">固定サイズの画像を解像度によって出し分け</a>たりしてるなら、間違いなくこれらの機能を使うことになるだろう。でもシンプルに画像を伸び縮みさせるだけなら、ここで紹介する新しいツールが使える。</p>
422
423<p>オーケー。これできれいさっぱり、準備が整った。<a href="http://ericportis.com/assets/2014-03-24-srcset-sizes/wolves/">さっきの例</a>に戻って、今度は<code>srcset</code>と<code>sizes</code>を使ってみよう。</p>
424
425<p>確認しとくと、僕たちが用意した画像には3つのバージョンがある。</p>
426
427<ul>
428<li><code>large.jpg</code>(1024 × 768)</li>
429<li><code>medium.jpg</code>(640 × 480)</li>
430<li><code>small.jpg</code>(320 × 240)</li>
431</ul>
432
433<p>そして36emのブレイクポイントでグリッドが1カラムから3カラムに切り替わる。</p>
434
435<p>マークアップはこう。</p>
436
437<pre><code>&lt;img src="small.jpg"
438     srcset="large.jpg 1024w,
439             medium.jpg 640w,
440             small.jpg 320w"
441     sizes="(min-width: 36em) 33.3vw,
442            100vw"
443     alt="A rad wolf" /&gt;
444</code></pre>
445
446<p><a href="http://picture.responsiveimages.org/">“picture”仕様</a>をもとにしてるのに<code>&lt;picture&gt;</code>要素が見当たらない、って気づいたかもしれない。<code>srcset</code>と<code>sizes</code>属性は<code>&lt;img&gt;</code>要素にも組み込むことができるんだ。この例のように、シンプルで、「アート・ディレクション」も「画像フォーマットの切り替え」もいらないようなとき、レスポンシブ画像ã
446®ãƒžãƒ¼ã‚¯ã‚¢ãƒƒãƒ—には僕らの古い友人である<code>&lt;img&gt;</code>が使えるし、そうしたほうがいい。</p>
447
448<p>おなじみの<code>&lt;img&gt;</code>に、新しい属性。ひとつずつ見ていこう。</p>
449
450<pre><code>src="small.jpg"
451</code></pre>
452
453<p>おっと、これはちっとも新しくなかったね!&ensp;この<code>src</code>はフォールバックで、<code>srcset</code>と<code>sizes</code>を理解できないブラウザーでも、今までと同じように画像を読み込むためのものなんだ。次!</p>
454
455<pre><code>srcset="large.jpg 1024w,
456        medium.jpg 640w,
457        small.jpg 320w"
458</code></pre>
459
460<p>こいつもほとんど説明いらないよね。<code>srcset</code>は、利用可能な画像のURLをカンマ区切りのリストで受け取る。それぞれの画像の幅は<code>w</code>ディスクリプターで指定する。もし画像を1024 × 768で「ウェブ用に保存」したなら、その画像は<code>srcset</code>内で<code>1024w</code>と指定すればいい。簡単。</p>
461
462<figure>
463    <img alt="「中くらいの穴にはこれ」から「中くらいのブロック」に貼り替える豆男"
464        src="./img/declarative/half.png"
465        srcset="./img/declarative/full.png 2236w,
466                ./img/declarative/half.png 1118w,
467                ./img/declarative/quarter.png 559w,
468                ./img/declarative/8th.png 280w">
469</figure>
470
471<p>指定してるのは幅だけ、ってとこに注意。なんで高さも指定しないのかって?&ensp;このレイアウトでの画像は幅で制御されてる。その幅はCSSで明示されてるけど、高さは指定されてない。実際のレスポンシブ画像のほとんども幅によって決まるので、仕様では幅だけを扱うことによってシンプルさを保とうとしてるんだ。</p>
472
473<p>将来的には、ファイルの高さも<code>h</code>ディスクリプターで指定できたほうがいい理由が<a href="https://github.com/ResponsiveImagesCG/picture-element/issues/85">いくつか</a>&ensp;<a href="https://github.com/ResponsiveImagesCG/picture-element/issues/86">あるけど</a>(個人的にも、それは素晴らしいことだと思う)、今のところはまだ。</p>
474
475<p>そして注意しておきたいのは、<code>srcset</code>の中のソースに、<code>1x</code>/<code>2x</code>といった解像度ディスクリプターを<code>w</code>ディスクリプターの<em>かわり</em>に指定することも<em>できる</em>けど、<code>1x</code>/<code>2x</code>と<code>w</code>は<em>混ぜて使わないこと</em>。こいつらを同じ<code>srcset</code>の中で使っちゃダメ。ゼッタイ。</p>
476
477<figure>
478    <img alt="「2x」と「640w」の貼り紙を一緒にしたばかりに雷に打たれる豆男"
479        src="./img/lightning/half.png"
480        srcset="./img/lightning/full.png 2237w,
481                ./img/lightning/half.png 1119w,
482                ./img/lightning/quarter.png 560w,
483                ./img/lightning/8th.png 280w">
484</figure>
485
486<p>オーケー、これが<code>srcset</code>と<code>w</code>。</p>
487
488<p>あとブラウザーがソースを選ぶために必要なのは、レイアウトの中で画像がどんなサイズで描画されるかだけ。そのためには<code>sizes</code>がある。さっきの例を見てみよう。</p>
489
490<pre><code>sizes="(min-width: 36em) 33.3vw,
491       100vw"
492</code></pre>
493
494<p>フォーマットはこう。</p>
495
496<pre><code>sizes="[メディア・クエリ] [長さ], [メディア・クエリ] [長さ] ..."
497</code></pre>
498
499<p>このようにメディア・クエリと長さを組み合わせる。ブラウザーは、マッチするものが見つかるまでメディア・クエリを見ていく。もし見つかれば、そのメディア・クエリとペアになった長さを、ソースを取ってくるパズルの最後のピース&#x2015;&#x2015;描画される画像の幅、またはビューポートに対する相対的な幅として使う。</p>
500
501<p>「なんだって?」と、君は言うかもしれない。「メディア・クエリ?&ensp;メディア・クエリはまずいって言ってなかったっけ?」</p>
502
503<p>僕が言ったのは、メディア・クエリをソースを選ぶメカニズムとして使うのはまずい、ってことなんだ。ここでやってるのはそれとは違う。ブラウザーがそのページのCSSで知ることになるブレイクポイントについて、ほんのちょっとだけ先回りして教えてあげてるんだ(このほんのちょっとの時間が<a href="http://andydavies.me/blog/2013/10/22/how-the-browser-pre-loader-makes-pages-load-faster/">すごく重要!</a>)。最初の例では、レイアウトのたった1つのブレイクポイント(36em)のために、いくつものクエリが無駄になってたのを覚えてるかな?&ensp;60em、20em、10em&#x2015;&#x2015;ってのがとっちらかってたよね!&ensp;その点、<code>sizes</code>のブレイクポイントは、そのページのブレイクポイントをそのまま反映したものになるはず。そしてそれぞれのメディア・クエリに続く長さが、そのメディア・クエリがマッチしたときの画像ã
503®å¹…を指定するんだ。</p>
504
505<p>というわけで、ブラウザーは必要な情報をすべて手に入れた。のろまで、なまけもので、間違ってばかりの僕ら人間が<a href="#part-1">パート1</a>でやるはめになったような計算は、あとはブラウザーやってくれる。その間に僕らは、くつろいでグリンピースを食べはじめられる。神の意図されたように。</p>
506
507<p>さらに!&ensp;メディア・クエリの例では1xと2xの画面しかカバーできなかったのを覚えてるかな?&ensp;こっちのマークアップなら<em>どんな</em><code>device-pixel-ratio</code>でも対応できる。もうどの解像度をサポートするのが適当かと迷う必要はない。たとえ2016年に4.8625xのスマートウォッチが登場したとしても、<code>srcset</code>と<code>sizes</code>ならカバーできる。</p>
508
509<p>まだある!&ensp;この解決策はブラウザーに選択の幅をもたらす。ソースと結びついたメディア・クエリは真か偽かのいずれかの結果になり、もし真なら、ブラウザーはそのソースを読み込まなきゃ<em>いけない</em>。でも<code>sizes</code>と<code>srcset</code>はそこまで頑固じゃない。仕様では、通信が遅かったり高くついたりするとき、小さいソースを読み込むオプションが認められている。</p>
510
511<p>「どうやらすべてうまくいくように思えるね」と君は言い、ゆっくりとうなずきながら、条件分岐的アプローチよりも宣言的アプローチのほうに利点がある、と納得しはじめる。「でもちょっと待って……長さってなに?」</p>
512
513<p><a href="http://www.w3.org/TR/css3-values/#lengths">長さはあらゆる種類が考えられるよ</a>!&ensp;絶対値(<code>99px</code>や<code>16em</code>)でも相対値(例に出てきた<code>33.3vw</code>とか)でも。ただ実際のレイアウトでは、ここでの例<em>とは違って</em>、絶対値と相対値が組み合わされてることがたくさんあると思う。そこで、<a href="http://caniuse.com/calc">意外にもけっこうサポートされてる</a> <a href="http://dev.w3.org/csswg/css-values/#calc-notation"><code>calc()</code>関数</a>の登場。<a href="http://ericportis.com/assets/2014-03-24-srcset-sizes/wolves/wolfroll.html">例の3カラムのレイアウトに12emのサイドバーを追加するとしよう</a>。それには<code>sizes</code>属性をこう調整すればいい。</p>
514
515<pre><code>sizes="(min-width: 36em) calc(.333 * (100vw - 12em)),
516       100vw"
517</code></pre>
518
519<p>できあがり!</p>
520
521<p>「わかったわかった」君は思慮深くそう言い、あごをさすりながら、新しい知識がどっと流れ込んできたことにひどく疲れて(でも同時にわくわくして)いる。「けれども、まだひとつ残ってる&#x2015;&#x2015;そこにぶら下がってる<code>100vw</code>はなんだ?&ensp;メディア・クエリを書き忘れたのか?」</p>
522
523<p>仕様の言葉を借りて言うと、メディア・クエリとペアになっていない長さは「デフォルトの長さ」だ。もしマッチするメディア・クエリがなかったとき、この長さが使われる。つまり、巨大な、ページ全体にまたがる幅のバナー画像なら、マークアップはこんなふうにシンプルになる。</p>
524
525<pre><code>&lt;img src="small.jpg"
526     srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w"
527     sizes="100vw"
528     alt="A rad wolf" /&gt;
529</code></pre>
530
531<p>カンタン、カンタン。</p>
532
533<figure class="full">
534    <img alt="空っぽのグリンピースの缶"
535        src="./img/empty-can/half.png"
536        srcset="./img/empty-can/full.png 4108w,
537                ./img/empty-can/half.png 2054w,
538                ./img/empty-can/quarter.png 1027w,
539                ./img/empty-can/8th.png 514w,
540                ./img/empty-can/16th.png 257w">
541</figure>
542
543</section>
544
545<footer class="footnotes" id="footnotes">
546    <ol>
547        <li id="fn-1">少なくとも<a href="http://tabatkins.github.io/specs/respimg/#variable-size">伸び縮みする</a>
547画像の場合は。<a href="#fnref-1">↩</a></li>
548        <li id="fn-2">そして君も(そう、そこの君も!)<a href="https://www.indiegogo.com/projects/picture-element-implementation-in-blink">この状況をもっと良くすることができる</a>!<a href="#fnref-2">↩</a></li>
549    </ol>
550</footer>
551
552</main>
553
554<footer role="contentinfo">
555    <p class="credit">このコンテンツは<a href="http://ericportis.com/posts/2014/srcset-sizes/">Srcset and sizes — ericportis.com</a>(2014年3月24日公開)の日本語訳です。本文中の各種技術仕様やその実装についての記述はオリジナル版公開時のものであり、現時点のものとは異なる場合があります。すべてのテキストとイラストレーションは<a rel="license" href="http://creativecommons.org/licenses/by/3.0/">クリエイティブ・コモンズ表示3.0ライセンス</a>のもとに提供されています。</p>
556    <table class="colophon">
557        <tbody>
558            <tr>
559                <th>著者</th>
560                <td><a href="http://ericportis.com/">エリック・ポーティス(Eric Portis)</a></td>
561            </tr>
562            <tr>
563                <th>訳者</th>
564                <td><a href="http://terkel.jp/">鈴木丈(Takeru Suzuki)</a></td>
565            </tr>
566            <tr>
567                <th>公開日</th>
568                <td><time datetime="2014-09-07">2014年9月8日</time></td>
569            </tr>
570            <tr>
571                <th>更新履歴</th>
572                <td><a href="https://github.com/terkel/srcset-sizes/commits/gh-pages">Commits · terkel/srcset-sizes · GitHub</a></td>
573            </tr>
574        </tbody>
575    </table>
576</footer>
577
578</body>
579</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.