- From: Kornel Lesiński <kornel@geekhood.net>
- Date: Fri, 01 Jun 2012 00:33:16 -0500
- To: whatwg <whatwg@whatwg.org>
- Cc: "public-respimg@w3.org" <public-respimg@w3.org>
Here's a bit of a kitchen sink solution with ideas that floated around. • I've used media queries for the art-directed use-cases, because: viewport size descriptors of srcset are confusing, limited (e.g. you can't have separate image only for print), and there must be an option to always predictably select image in conjunction with same `@media` in CSS (to adapt size of other page elements to the picture). • Browser-controlled resolution adaptation is good, so I've kept `1x`/`2x` descriptors of `srcset` (covers performance/dpi, not art-directed cases) • I've specified (hopefully intuitive) interaction between MQs and resolution selection to support more cases. • Improved alternative text — allows structured fallback, avoids duplication. • Minimized verbosity. `picture` → `pic`, `srcset` → `src`. 2x image can be embedded with the same number of characters as 1x `<img>`. • Default resolution can be controlled with CSS `image-resolution`. • Allowed both attribute microsyntax and nested `<source>`/`<img>` elements. The former for brevity in common cases, and the latter for extensibility, `width`/`height` attributes to avoid reflows and fallback for HMTL4 UAs without repetition. • I could not figure out powerful and clean syntax for breakpoint macros/uri templates, so I've left that out. Hopefully it can be added later. ##The `<pic>` element in examples: <pic src="image.jpg 1x">alt text</pic> Same as `<img src="image.jpg" alt="alt text">`. The `1x` means 1:1 scale of image to CSS pixels. <pic src="small.jpg (max-width:320px), medium.jpg (max-width:768px), large.jpg">alt text</pic> Selects image to embed based on width of the viewport. <pic src="portrait.jpg (orientation:portrait), landscape.jpg">alt text</pic> Selects image based on orientation of the device. <pic src="whitebg.jpg 2x print, blackbg.jpg 1x">alt text</pic> Embeds high-res image with white background when the page is printed, and a regular-res black image otherwise. <pic src="image.jpg">alt text</pic> Embeds image at 192dpi (default scaling is 2x, possible to override with CSS). Same as `<pic src="image.jpg 2x">alt text</pic>` or `<img src="100x100px" width="50" height="50" alt="alt text">`. <pic src="image1.jpg 1x, image2.jpg 2x">alt text</pic> Embeds image at either 96dpi or 192dpi, depending on capabilities and preferences of the user agent (UA can pick any alternative). Same as `<pic src="image2.jpg 2x, image1.jpg 1x">alt text</pic>` and `<pic src="image2.jpg, image1.jpg 1x">alt text</pic>`. <pic src="small.jpg 0.5x, medium.jpg 1x, large.jpg 2x" style="width:100%">alt text</pic> Selects image based on display resolution/zoom, and optionally width of the container (if UA has layout information available when image is [pre]loaded). Unlike version with `min`/`max-width` media query, UA is allowed to pick any image and dynamically change the image (e.g. prefer cached image or download low-res first, replace with high-res when network is idle). ##(optional?) extended syntax: <pic src="a (mq), b 3x">alt text</pic> is same as: <pic> <source src="a" media="(mq)"> <source src="b" resolution="3x""> alt text </pic> (I'm not sure if `<source>` should allow microsyntax in `src` `<source src="b 3x">` instead of `resolution="3x"`) The `<source>` element allows `width`/`height` to be specified for each alternative: <pic> <source src="large.jpg" media="(min-width:1024px)" width="1024" height"="300"> <source src="medium.jpg" media="(min-width:768px)" width="768" height="200"> <img src="small.jpg" width="320" height="100"> alt text </pic> An `<img>` element can be used in place of any `<source>`. `width`/`height` defines size to display selected image at, but does not take part in selection of alternatives. The common syntax for use with JS polyfills is expected to be: <pic src="…"><noscript><img src="…" alt="…"></noscript></pic> ##In formal terms The `<pic>` element requires closing tag. The content is interpreted as a fallback for UAs that don't support `<pic>` or don't display the image (fallback includes text in <img alt> inside <pic>). The `src` attribute contains comma-separated list of alternative images: src="alternative, alternative, …" and each alternative consists of space-separated: url [resolution] [media] The `resolution` and `media` are optional. Resolution defaults to the value of CSS `image-resolution` property, and UA stylesheet should include: pic {image-resolution:2dppx} pic img {image-resolution:1dppx} i.e. the default resolution is `2x` for `<pic>` and `1x` for `<img>` unless author overrides the defaults with CSS. Media query defaults to `all`. If there are commas or backslashes in the URL they must be escaped with `\`. Alternatives can be specified using `<source>` and `<img>` elements in addition to `<pic src>` attribute. Alternatives from `<pic src>` are evaluated first. The algorithm for finding these elements: 1. For each child element of `<pic>` 1. if the child element is `<source>` or `<img>` include it as an alternative 2. if the child element is `<noscript>` and scripting is disabled, include all `<source>` and `<img>` children of the `<noscript>` as alternatives e.g. <pic> <source> <!-- yes --> <noscript><img></noscript> <!-- maybe --> <video><source></video> <!-- no --> </pic> The `<source>` element has following attributes: * `media` — same as `media` part in `<pic src>` * `resolution` — same as `resolution` part in `<pic src>` * `src` — single URL without escaping or microsyntax * `width` and `height` — analogous to `<img width/height>` for each alternative image The `<img>` element in `<pic>` is equivalent of `<source src="… 1x" media="all">`. The resolution is interpreted as a property of the image. It describes ratio of image pixels to CSS pixels for image's intrinsic size, like the CSS `image-resolution` property. It acts as a hint for image selection, but not as strictly as a media query. User-agent is free to use 2x images on 2x ("Retina") displays, but may opt not to if network speed/cost or memory limitations prohibit this. The user-agent may also opt to use a 2x image on a regular 1x display if it the page is zoomed in, when printing, etc. Authors are encouraged to always use resolution descriptors instead of `device-pixel-ratio` media query to allow UAs optimize selection of image resolution. Matching of media queries in `<pic>` must be consistent with matching of `@media` in CSS and `matchMedia` JS API, i.e. UA is not allowed to ignore or fake values in media queries to pick different image alternative (unless it does it consistently for the whole page at the same time). <pic src="image.jpg (min-width:500px)"></pic> In the above example no image is shown (equivalent of transparent image with intrinsic size 0x0) if the viewport is narrower than 500px. Algorithm for selection of the alternative: 1. For each alternative in order 1. if media query does not match, ignore the alternative 2. if the media query matches 1. pick all alternatives with media query identical to the one that matched 2. ignore all other alternatives 2. If there are no alternatives left, use transparent image with intrinsic size 0x0 3. Select any image among picked alternatives This algorithm may be re-evaluated between any event loop runs. For purpose of this algorithm media queries are "identical" if they parse to the same sequence of tokens, ignoring insignificant whitespace. The default/implied `all` values are identical to explicitly specified "`all`". ---- Generally the first alternative (in `src` left to right, nested `<source>`/`<img>` in source order) that has media query that matches wins. If there's more than one alternative with an identical media query, UA can choose among them, e.g. select best fit resolution or file format. Note that resolution is not part of media query. `<pic src="img2 2x, img1 1x">` is same as `<pic src="img2 2x all, img1 1x all">`, and since both alternatives have implied media query `all` that matches, UA can choose among them. <pic src="imageA (min-width:500px), imageB 1x (min-width:300px), imageC (min-width:800px), imageD 2x (min-width: 300px)"> If `(min-width:500px)` matches, then imageA must be used regardless of screen density or UA preference (since it's first to match and there are no other alternatives with such media query). If `(min-width:500px)` doesn't match, but `(min-width:300px)` matches, then UA may choose between imageB and imageD (both have the same query that matched). imageC will never be used (because imageA will always match earlier and it has a different media query). <pic src="portraitHD.jpg 2x (orientation:portrait), portrait.jpg 1x (orientation:portrait), landscapeHD.jpg 2x, landscape.jpg 1x">alt text</pic> UA can choose resolution of portrait or landscapa version of the image. Same as: <pic src="portraitHD.jpg (orientation:portrait), landscapeHD.jpg, portrait.jpg 1x (orientation:portrait), landscape.jpg 1x">alt text</pic> -- regards, Kornel Lesiński
Received on Friday, 1 June 2012 05:33:47 UTC