Hacker News new | past | comments | ask | show | jobs | submit login
The Clown Car Technique for Responsive Images (github.com/estelle)
181 points by joshuacc on April 21, 2013 | hide | past | favorite | 32 comments



The 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/

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.


I 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.


I 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

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/


JPEG/GIF/PNG all have interlaces, why not download the first scan for smaller image, and full scan for original images?


Wow, 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?


I just learned it from my other question on Stackoverflow not long ago

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.


Half an interlaced image is still twice as big as an image at half resolution.


Interlacing usually happens in two-dimensions in image formats, if I understand it correctly (ie it first sends one pixel out of each 2x2 block).

The only thing is I think that is one of the actual pixels, rather than an average. In an ideal world you could send the average color of each 2x2 block, then send the 2nd, 3rd, and 4th pixels and use that data to reconstruct the 1st pixel.

Or is that how it works already?


I 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/

This could be a problem; I'd like to see expanded browser support.


If 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.


Oh Dear Lord Picture Element Needs To Be Baked Into Browsers Soon


Yes.

> 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.


> 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).


Surely this can be solved by embedding the SVG in a data: URI?


Or 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.


That 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)


Why? 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.


including 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 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.


*She


[deleted]


This 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.


This 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).


Nifty, 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!


This 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.



I've read through the article and can't determine what the downsides of this technique. Lack of browser support?


As far as I can tell, yes exactly that. Needs testing and the CSP issue as well.


It really breaks user experience though. So probably not the best way.


In which way does it break user experience. Would like to know so I can try to address that and figure out a work around.


Right 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).


Thanks. Will look into that next week


I thought this article was going to be about how the republicans ran the 2012 presidential campaign.


I suspect javascript based lazy image loading is superior?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: