Responsive imagesのための-webkit-image-set()

AppleWebKit-webkit-image-set()なるものを実装した。

なにかというと、Retina displayやらPCとデバイスピクセル比が違うディスプレイに対して、違う画像を出し分ける、いわゆるResponsive imagesと呼ばれてるやつのための仕組み。

こんな感じで書くらしい。

selector {
  background: -webkit-image-set( url(foo-lowres.png)  1x,
                                 url(foo-highres.png) 2x ) center;

image-set()内には複数の"imagespec"というものが入る。imagespecは<image>(画像、グラデーションでもいい)に続けて、nxという表記で倍率を書いたもの。対応しているブラウザは、高密度なディスプレイには“2x”な画像(foo-highres.png)を、これまでのディスプレイには1xな画像をという風に出し分けることができる。

メディアクエリーとどう違うのか

出し分けるとなるとメディアクエリーとどう違うんだという話になる。この機能を提案したAppleのEdward O'Connorにはこういう考えがあるらしい。

Here are just a few of the problems with the current situation:

  • Bugs due to non-locality: One developer fixes a bug in the selector, but only in the low-resolution case. Another developer changes an image reference to refer to a different icon, but only in the high-resolution case.
  • Both assets may be loaded by the browser, which may degrade performance in a constrained bandwidth environment.
  • Authors can't specify both assets inside a style="" attribute.

メディアクエリーだとセレクタが多重になるので管理性が懸念されること、使わないもう片方の画像が読み込まれてしまう可能性があること、style属性でつかえないこと、この3つがいくつかある問題として取り上げられている。

あと、image-set()で出てきそうな質問にもすでに答えている。

Why a scale factor and not a full-blown media query?

Media queries are a claim about the state of the UA, whereas here we're making a claim about (the relationship between) the image assets themselves. It would be confusing to use similar syntax for such different things. Also, UAs should have the ability to choose between the given variants based on a variety of factors. For instance, a UA could use the lower res asset when a user has zoomed out. No existing media query distinguishes between the page being zoomed-out and being zoomed in. And even if such a media query existed, UAs should be free to choose between variant assets regardless of which media queries happen to match.

MQを使わず2xなんて倍率を使う理由は、MQがUAの性質について何かするという考えのもと作られてるのに対し、こっちは画像自体について言いたいと。なので違う構文のが間違わなくてよいだろうと。あと、UAの性質(デバイスピクセル比とか)だと「どちらか」になってしまうけど、image-set()はたとえば、ズームインしたときは解像度の高いものを選ぶとか、そういう利用も考えられているらしい。

ズームインとかを考えると、たしかにmedia featureとは言いづらいかもね。

The problem of stylesheet verbosity when using media queries isn't limited to image assets. Shouldn't we have a general mechanism for keeping media-specific property values together in rule sets?

In talking with content producers here, we've found that the non-locality of asset references is a real source of Web author pain. I think a focused feature to help with that pain is sensible. That said, we should also explore how to help authors avoid selector repetition and the other pains of @media in general.

image-set()っていう画像だけのやり方じゃなくて、もうちょっと一般的なことにできないのという点については、まずアセットの参照が一箇所にないことがかなり手間ということが分かったので、その解決にフォーカスした機能にしたと。一般化については、セレクタの重複や他にもあるだろうMQの問題について、いま一度どんなことができるか調査すべきだと。

Why not enhance the image() function instead of inventing a new function?

Unlike image(), these image specifiers are unordered. This isn't about fallback. There is no preferred variant. UAs are free to use whichever image it believes would be best. For instance, consider the page zoom example I mentioned earlier. Authors could even use image() and image-set() together to handle more exotic cases, e.g.:

image(image-set(url(foo.png) 1x, url(foo@2x.png) 2x) rtl,
      image-set(url(bar.png) 1x, url(bar@2x.png) 2x) ltr);

css3-imagesで提案されてるimage()を使わないのはどうしてかと。これは、image()がフォールバック目的で、また値の順序が影響するのに対して、image-set()はズームなんかの状態に応じて画像を選べると。

ふむ。

image()でなんとかできないのか

ズームとかそういうのはわかったんだけど、image()とは別というのは、なんだかね。まだ実装もないし、定義を変えてしまえばいいだけのような気もするんだけれど。

というわけでcss3-imagesのEditorのTab先生とちょっと議論している。ただ読む限り、Ted (Edward)はあくまでimage()はフォールバックのためとしておきたいという気持ちが強いようで。Tabがそのあと、image()のリスト中にスラッシュを入れて、それをimage-set()の代わりにしてはどうだという提案をしているけれど、とくに返信もなくという状態。こっちのが好きかなあ。

Retina時代の準備かねえ

実装されたのはさっきだけれど、やっぱり裏にはRetina display対応が絡んでるんだろう。今WebCoreに入れば、Safari 5.2の正式版に反映されてもおかしくないタイミングだし、iOSの次のバージョンにも取り込まれることは間違いない。

LionでHiDPIモードが進んでたのもあるし、OSXでもそのうちRetina display搭載のデバイスが出るんだろう。そこで多分使ってくるんだろうねえ。

そうなると、気になるのがHTML側ではどうするかということ。CSSではimage-set()ができたけど、HTMLにはそれが無いので、The new iPad™なページはXHRで2xな画像に差し替えてるなんてことをしている。

で、さっきのTedのメールに、こんなのが。

What about content images?

First off, this is www-style, so the design of an HTML feature for responsive <img>es is out of scope. :) That said, I can imagine the image-set() microsyntax being used in an attribute like so:

<img alt="A description of foo"
     src=foo-lowres.png
     set="foo-lowres.png 1x, foo-highres.png 2x">

I'll post something to the whatwg thread referencing this proposal.

とまあ、www-styleだからって提案ではないとしときながら、<img src=... set=...>と、属性を追加するかたちで提案している。後方互換性を考えると、srcの拡張は現実的ではないし、ズームイン/アウトのユースケースを考えると別の属性にしかならないだろう。<object>は禁句。

WHATWGになんかポストするとあるけれど、現時点ではとくにそんなメッセージはない。ただ今週あたまにCanvas APIにデバイスピクセル比やら高解像度用のImageDataやらが欲しいという提案をしている。

というわけで、来るんじゃないですかねえ。