• Stars
    star
    876
  • Rank 52,107 (Top 2 %)
  • Language
    HTML
  • License
    MIT License
  • Created over 11 years ago
  • Updated about 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Clown Car Responsive Image Technique

Clown Car Technique for Responsive Images

We can use media queries within SVG to serve up the right image. The beauty of the "Clown Car" technique is that all the logic remains in the SVG file. I've called it the "Clown Car" technique since we are including (or stuffing) many images (clowns) into a single image file (car).

When you mark up your HTML, you simply add a single call to an SVG file.

<img src="awesomefile.svg" alt="responsive image">

Now isn't that code simple?

Unfortunately, due to content security policies (not CSP spec, but general security), FF and WebKit to not allow SVG files imported as <img> to call in raster images or scripts. Therefore, we use the almost as simple <object> tag, which as a non-empty element can provide for a child fallback for IE8 and Android 2.3.

<object data="awesomefile.svg" ></object>

The magic is that SVG supports both media queries and rasterized images.

In our SVG file, using the <image> element, will include the all the images that we may need to serve, and include all the media queries.

Here is the code for one of the SVG files:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="329">
  <title>The Clown Car Technique</title>
    <defs>
    <style>
    image {display: none;}
    #small {display: block}
     @media screen and (min-width: 401px) and (max-width: 700px) {
        #medium {display: block}
        #small {display: none}
    }
      @media screen and (min-width: 701px) and (max-width: 1000px) {
        #big {display: block}
        #small {display: none}
    }
     @media screen and (min-width: 1001px)  {
      #huge {display: block}
      #small {display: none;}
    }
    </style>
  </defs>
  <g>
    <image id="small"  height="329" width="300" xlink:href="images/small.png" />
    <image id="medium" height="329" width="300" xlink:href="images/medium.png" />
    <image id="big"    height="329" width="300" xlink:href="images/big.png" />
    <image id="huge"   height="329" width="300" xlink:href="images/huge.png" />
  </g>
  </svg>

Unfortunately, when this file is used, all 4 PNGs are retrieved from the server. To solve this issue, we can use background images instead:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 329" preserveAspectRatio="xMidYMid meet">
 <title>Clown Car Technique</title>
 <style>
  svg {
    background-size: 100% 100%;
    background-repeat: no-repeat;
  }
 @media screen and (max-width: 400px) {
  svg {background-image: url(images/small.png");}
 }
 @media screen and (min-width: 401px) and (max-width: 700px) {
  svg {background-image: url(images/medium.png);}
 }
 @media screen and (min-width: 701px) and (max-width: 1000px) {
  svg {background-image: url(images/big.png);}
 }
 @media screen and (min-width: 1001px) {
  svg {background-image: url(images/huge.png);}
 }
 </style>
</svg>

This version only downloads the images required, thereby solving the multi-HTTP and waste of bandwidth concerns. However, it seems to trigger more Content Security Policy issues than the previous SVG.

The SVG file has it's own declared size, but when included in HTML, the media query size is based on the proportions of the DOM node in the HTML --. it reflects the space provided to it.

Open the SVG in your browser and resize your browser window. As the window grows and shrinks the image the SVG displays changes. The image size takes up the full screen because it has a background size of 100%. It's when we include the SVG in the <object> of a flexible layout that the magic happens. You'll note that the first time you load the SVG there may be flickers of white as the browser requests the next required PNG.

When you include the SVG in your HTML <img> with a flexible width, such as 70% of viewport, as you grow and shrink the container, the image responds to the changes. The "width" media query in the SVG is based on the element width in which the SVG is contained, not the viewport width.

The foreground <img> version works perfectly in Opera. In Chrome and Safari, I need to open the SVG file first, after which the HTML file containing the foreground SVG image works perfectly. In Firefox, the SVG works. Firefox supports SVG and supports SVG as background image, but blocks the importing of external raster images due to their content security policy (CSP).

The content security policy does make sense: you don't want a file to be pulling in untrustworthy content. SVG technology is supported. It is just being prevented from pulling in external raster image. Firefox prevents it altogether. Safari and Chrome work if the SVG is preloaded. We can work with the browser vendors to get this CSP lifted, at least for same-origin files.

The browsers do all support the media queries with the SVG. They all support SVG as foreground or content images. They all support SVG as background images. The support just isn't all the same.

Responsive SVG for foreground images works. It simply works right out of the box. By using background images within the SVG itself the SVG only requests the file it needs. The raster images are background images. Only the required image is downloaded. The only negative is that it requires 2 http requests: one for the image and one for the SVG. I am currently working on getting SVG as data URI to work. I am not there yet.

Another pro for this technique: similar to how we separate content from presentation from behavior: this method enables us to also separate out images -- all the logic is in the SVG image instead of polluting our CSS or HTML.

The main question is: should we attempt this with <object>, or should we get browser vendors to change their content security policy to enable this technique to work as <img> directly?

Accessibility

Object does not support the alt attribute, which make images more accessible. SVG can be made accessible with the help of the TITLE. So, don't forget the title as alt attribute in your SVG

More Repositories

1

input-masking

Framework agnostic accessible input masking library
HTML
485
star
2

CSS-Workshop

6 hours workshop covering almost everything in CSS2 and CSS3
HTML
115
star
3

html_elements

Template using all the HTML elements
HTML
64
star
4

cssmastery

Front End Masters CSS Mastery Class
HTML
59
star
5

selectors

Select This! CSS Selectors Presentation
HTML
36
star
6

estelle.github.com

Estelle Weyl
CSS
35
star
7

mobileperf

Mobile Performance Workshop
HTML
28
star
8

merry-go-round

ceci n'est pas un carousel
HTML
18
star
9

doyouknowcss

A few things you likely didn't know about CSS
HTML
18
star
10

jsintro

Introduction to Javascript
JavaScript
15
star
11

slides

HTML5 Slide Template
HTML
13
star
12

CSS

CSS workshop 2019
HTML
9
star
13

snow

Snow: CSS3 Animations, transitions, transforms, gradients, etc.
CSS
8
star
14

html5training

HTML5 Training with CSS
JavaScript
8
star
15

CSS-JS-Entity-Calculator

Calculator for converting characters for use in html, css and javascript
7
star
16

mobile

mobile UI Performance
JavaScript
6
star
17

flexbox

Flexbox tutorial
HTML
6
star
18

animation

CSS Transitions and Animations
HTML
5
star
19

StopSOPA

makes your page disappear on January 18, 2012
JavaScript
5
star
20

iphone

native iPhone app look and feel with CSS only
4
star
21

forms

HTML5 Web Forms Presentation
HTML
4
star
22

carousel-carousel

Script for creating simple, accessible carousels
HTML
3
star
23

simplyaccessible

"Simply Accessible Web Performance" Presentation
HTML
3
star
24

mobilecss

CSS Workshop focusing on what you need for mobile
JavaScript
3
star
25

oscon2012

OSCON 2012 Files
JavaScript
3
star
26

CSS3Gradients

Library of CSS3 Gradients
3
star
27

css-questions

CSS Interview Questions
3
star
28

accessu

Talk for accessU 2019
HTML
2
star
29

viewsource

Mobile Web Performance: Slide deck for ViewSource Conference London 2017
HTML
2
star
30

browsers

Web Performance: How the browser gets populate (in French)
HTML
2
star
31

csstdg

2
star
32

HSLA-Color-Converter

HSL/ HSLA / RGB / RGBA / Hex color converter
HTML
2
star
33

10

10 Things You Didn't Know Browsers Could Do
JavaScript
2
star
34

jsframeworks

When to use and not use a JS framework and why
JavaScript
2
star
35

html5mobile

Mobile Training: HTML5, CSS3 & JS APIS
JavaScript
2
star
36

estelle

1
star
37

flashback

HTML
1
star
38

animations

Animations and Transitions in CSS3: Support Files
HTML
1
star
39

a11yperf

Accessibility as Performance, but focused more on a11y.
HTML
1
star
40

begin-svelte-app

Begin app
JavaScript
1
star
41

wtf

CSS: Wonderfully Terrific Features and Weirdly Terrible Fauxpas.
HTML
1
star
42

components

Web Components
CSS
1
star
43

rendering

English Translation of Browsers: populating the page
HTML
1
star
44

cssintro

Cascading Style Sheets: Design Tools to Style Your Web Content
CSS
1
star
45

javascript-questions

JavaScript Interview Questions
1
star
46

html5jsapis

Overview of some basic CSS3 and HTML5 JS APIs
CSS
1
star
47

codelab

CSS Presentation for GTUG Codelab
1
star
48

cssdeepdive

Deep Dive into CSS Selectors, Animation and Flexbox
CSS
1
star