5 ms·
The Clown Car Technique for Responsive Images
- WiseWeasel 14y agoI love how this isolates the complexity of responsive image serving from the CSS. I wonder if a good practice might be to have a single images.svg file with all your site's responsive images included as ID'd groups, like: <g id="logo"> <image id="1x" xlink:href="logo_low_rez.png" /> <image id="2x" xlink:href="logo_high_rez.png" /> </g> <g id="promo"> <image id="1x" xlink:href="promo_low_rez.png" /> <image id="2x" xlink:href="promo_high_rez.png" /> </g> Then, you could render the content as such: <img src="images.svg#logo" /> <img src="images.svg#promo" /> I'll have to play with this, but it looks like a promising idea. Here's hoping browser compatibility is decent. For some reason, the first 'foreground' svg example doesn't seem to render an image for me in Chrome or Firefox, despite supposed support for the latter: http://estelle.github.io/clowncar/ http://estelle.github.io/clowncar/ This could be a problem; I'd like to see expanded browser support.
- neilk 14y agoIf you compiled data about every image on the site in one file, and then loaded that file with every request, you could just use regular CSS and media queries.
- deleted 14y ago[deleted]
- kevingadd 14y agoThis kind of SVG image isn't really an atlas in any form. The images don't share any sort of coordinate space or even coexist in the same file. It's more like a URL lookup table that happens to point to images and be keyed by the size of the viewport.
- benjoffe 14y ago> In the second, the raster images are background image. Only the required image is downloaded. The author neglects to point out that every image will waste a http request downloading the svg file so this is going to give poorer performance than having the logic in your css (perhaps he considered it too obvious).
- instakill 14y ago*She
- duskwuff 14y agoSurely this can be solved by embedding the SVG in a data: URI?
- neilk 14y agoOr embedding it directly into the HTML - almost any browser that can show SVG can also handle it as markup. But, the benefit of this technique (as far as I can tell) is decoupling, and any kind of embedding re-couples the data. Maybe in an acceptable way, if you can do it at a deploy step. It depends on what the use case is.
- michaelbuckbee 14y agoThat would reduce the number of HTTP requests to one (but would also have the side effect of pulling in ALL of the different sized files)
- mistercow 14y agoWhy? It's not including the images in the data URI, just the SVG. That should act identically to downloading the SVG as a separate file (minus the extra HTTP request), unless I'm unaware of some very dumb quirk.
- estelleweyl 14y agoincluding the data uri for the svg only makes sense. to include the data uri for all the images would be the same weight as downloading all the images plus about 10%. The method at this link: http://estelle.github.io/clowncar/bgonly.html http://estelle.github.io/clowncar/bgonly.html only does two http requests, the svg and the image used. We can bring that down to 1 by using data URI for the svg logic only.
- estelleweyl 14y agoThe clown car technique -- used for foreground images in your HTML documents, works best when the SVG contains only background images . If you use <image>, all the images in the SVG will be downloaded. Yes, the SVG does "waste" a single HTTP request -- you get two http requests: one for the SVG file and one for the image it downloads that matches the media queries within the SVG. However, you can use a data URI within your HTML to eliminiate the call to the SVG file. An example of this (in CSS) is here: http://jsfiddle.net/estelle/ZHrb2/ http://jsfiddle.net/estelle/ZHrb2/ The reason I called it Clown Car technique was because we're stuffing a whole bunch of images into a tiny little file. I am looking into this technique not just to solve the <picture> RWD image issue, but also as a way to manage images. We currently separate content (html) from presentation (css) from behaviour (js). I like the idea of managing my assets separately as well. Thinking this helps along those lines.
- sbouafif 14y agoI like the idea of separating the content from the presentation and the behaviour. But I'd really like to automate this. Is there a way in SVG to concatenate strings? (I never really used SVG and can't find something on this in Google) . Using JS I generally use the data attribute in html to set the image name and add _small, _big, _huge depending on the window size. The JS script will automatically set the right image. It's great but doen't work if there's no JS support.
- jeffehobbs 14y agoOh Dear Lord Picture Element Needs To Be Baked Into Browsers Soon
- dminor 14y agoYes. > We can work with the browser vendors to get this CSP lifted. No, let's work with the browser vendors to implement something more sensible than stuffing background image media queries into a god damn svg.
- marshallford 14y agoI've read through the article and can't determine what the downsides of this technique. Lack of browser support?
- lbotos 14y agoAs far as I can tell, yes exactly that. Needs testing and the CSP issue as well.
- DigitalSea 14y agoI agree as a developer wholeheartedly we need a better way of adding in multiple versions of an image for the plethora of resolutions and pixel density's out there, but this technique feels a little hacky to me. I am a big advocate of SVG (I use SVG extensively for icons and logos especially) but cramming media queries and image tags within to save a few bytes at the added cost of complexity and browser quirks to debug doesn't feel like it's worth it. The only solid fix for responsive imagery is a HTML5 tag that allows you to set breakpoints for different sizes. The proposed "picture" tag which is similar to that of the video tag does what we want, but we most likely won't see any action on this tag until 2014, possibly 2015 if this W3 bug ticket is any indication: https://www.w3.org/Bugs/Public/show_bug.cgi?id=18384 https://www.w3.org/Bugs/Public/show_bug.cgi?id=18384 This jQuery script adds in the functionality for using the proposed tag now though, I can't speak for how well it works, but it looks promising: http://jquerypicture.com/ http://jquerypicture.com/
- est 14y agoJPEG/GIF/PNG all have interlaces, why not download the first scan for smaller image, and full scan for original images?
- dclowd9901 14y agoWow, this is a pretty novel approach; is this something that's been talked about or are you just one of those really clever people I keep hearing about?
- est 14y agoI just learned it from my other question on Stackoverflow not long ago http://stackoverflow.com/questions/15674880/ http://stackoverflow.com/questions/15674880/ It's a cool hack which you can serve low-res, monochrome jpeg in the first scan, and gradually to full-res, full-color jpeg.
- WiseWeasel 14y agoHalf an interlaced image is still twice as big as an image at half resolution.
- polemic 14y agoNifty, although I personally think that you might as well just use CSS and save the HTTP request. Of course, if you are going to use SVG, by all means provide Vector Graphics where you can!
- mildweed 14y agoBetter yet: Intention.js. https://news.ycombinator.com/item?id=5587504 https://news.ycombinator.com/item?id=5587504
- ck2 14y agoI suspect javascript based lazy image loading is superior?
- aceperry 14y agoI thought this article was going to be about how the republicans ran the 2012 presidential campaign.
- rplnt 14y agoIt really breaks user experience though. So probably not the best way.
- estelleweyl 14y agoIn which way does it break user experience. Would like to know so I can try to address that and figure out a work around.
- rplnt 14y agoRight click -> save image/send image/etc; For some reason I haven't had those options (although they are present on normal svg) and I think it would only download the svg anyways (with the actual content left online).
- estelleweyl 14y agoThanks. Will look into that next week
- hallman76 14y agoThis reminds me of Shadow DOM. Seems like you could use this technique to implement rich widgets like video players, social sharing buttons, or ad units.
- lazyjones 14y agoThis is too hacky and too complex. It creates another level of cruft where we already have too many of those. Serving images according to pixel densities should be handled completely on the server side. This can be done based on HTTP headers and in border cases with a cookie denoting increased pixel density (i.e. N phyiscal pixels are 1 "HTML" pixel in width/height attributes), which can be set using JS. Ideally, we'd have a HTTP request header for this (Accept-*). For now, you can still get good results with higher resolution images where maximum detail is desired (browsers scale images down nicely nowdays and users actually appreciate being able to save higher-resolution versions) and lower/normal where loading times are important (i.e. everywhere else).