How do we deal with images in HTML?
A re-recording of a talk I did recently at Standards Next, discussing the problem we have with <img> in HTML and responsive designs, ways that is can be tackled, and the future of how we may solve it.
I apologise for the constant “errr"-ing, it’s been three weeks since I gave the talk and I was quite tired when I recorded this last night - I didn’t notice how bad it was until today. I may well re-record it at the weekend to trim off some of the gaps and stumbles. Hopefully you’ll find it useful, but you may be interested in the Vimeo page itself where I link to specific topics in the video description, which allows you to skip sections that may not interest you.
Entry Information
- Posted:
- Thu, 22nd Mar 2012 at 16:03 UTC
- Filed under:
- Tags:
Comments
skip to comment formWhat would you think about this adaptive img solution using current elements: https://github.com/adamdbradley/foresight.js
It's a neat solution, and I quite like it - it could be appropriate for some use cases.
It does have a couple of issues though, that would stop me using it:
The main issue for me is it relies on JS being enabled for desktops to have usable images (I don't think mobile sized images on desktops is acceptable for real-world use - which is exactly why the Boston Globe method got taken offline).
It requires custom HTML being authored - this isn't such problem to be honest, although a neater syntax is explored in http://24ways.org/2011/adaptive-images-for-responsive-designs-again where the attributes are placed on the noscript element itself. You could then simply add a new image tag in JS instead of modifying one written in the HTML.
The obvious implementation of your "Future solution" seems to me to be something like:
.imgJoeBloggs { background:url(joebloggs-small.jpg); width:100px; height:75px; border:1px solid black; }
@media screen and (min-width:437px) { .imgJoeBloggs { background:url(joebloggs-medium.jpg); width:200px; height:150px; } }
@media screen and (min-width:800px) { .imgJoeBloggs { background:url(joebloggs-large.jpg); width:400px; height:300px; } }
@media screen and (min-width:1000px) { .imgJoeBloggs { background:url(joebloggs-extra-large.jpg); width:500px; height:375px; } }
@media screen and (min-width:1200px) { .imgJoeBloggs { background:url(joebloggs-massive.jpg); width:600px; height:450px; } }
The html is not a problem, since no content author writes the final html by hand, that is all content (wether it contains html or not) passes through some cms/template-engine/build-step, that can rewrite images tags as needed.
Also weather the images are pre-generated or generated by some php-script is just an implementation detail. Matt says: That misses the point; CSS doesn’t have an issue, it’s content images in HTML that do - what you have suggested is not a solution for this.
Just noticed that your comment form had dropped html tags (instead of encoding them properly). So I think you missed my point This and some style tags was missing:
{div class="imgjoebloggs" role=img aria-label="A photo of Joe Bloggs"}{/div}
Like the bit at the end about needing a one-stop solution for @media querying across HTML/CSS/JS, and agree it's probably best done in like you describe. Like your suggestion of named 'presets', which would each have their own @media-like matching rules to narrow down which applies on the device in use.
Obviously you'd then need two mechanisms to access the result of this test(ing), for CSS and JS respectively..
For CSS, this could be as simple as a pseudo-selector of some kind, or even an extension to @media queries so that a particular 'named' media 'preset' (e.g. 'smartphone', 'tablet', etc) could be matched by the @media {..} block, rather than a test like min-width. Both of these could even be available, so you can either target for a single CSS rule, or an entire @media { .. } block of rules.
From the JS point of view, probably a new API connected to/part of the DOM in some way would probably work. Again, perhaps something as simple as a method which returns your 'named preset' from which has been matched according to your stated @media rules.
Interested to see where this stuff goes..
..and some code to back things up, why not .. pick a random name for it: 'mediaAlias' (disclaimer: pie in the sky??)
…
if (document.mediaAlias == 'tablet') { .. } else { .. }
@media screen and (alias: mobile) { … }
::media-alias(mobile) img { max-width: 100%; } /* a bridge too far? */
Anyone think of a better name than media 'alias'?
..and some code to back things up, why not .. pick a random name for it: 'mediaAlias' (disclaimer: pie in the sky??)
<head>
<!– using meta tags? –>
<meta name="mediaalias:mobile" content="min-width: 300px" />
<meta name="mediaalias:tablet" content="min-width: 600px, min-device-pixel-ratio: 1.5" />
…
<!– or a new element altogether –>
<media alias="mobile" query="min-width: 300px" />
<media alias="tablet" query="min-width: 600px, min-device-pixel-ratio: 1.5" />
</head>
<script>if (document.mediaAlias == 'tablet') { .. } else { .. }</script>
<style>
@media screen and (alias: mobile) { … }
::media-alias(mobile) img { max-width: 100%; } /* a bridge too far? */
</style>
Anyone think of a better name than media 'alias'?
FFS! Decode the HTML character references above and you'll catch my drift
Aha, a gist maybe in order: https://gist.github.com/2663318
Updated the gist .. realised that I'd been silly - there could be more than one matched alias in JS world, so needs to be an array rather than a single value, hence 'mediaAliases'