demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

Art-Directed Adaptive Images With SVG and JavaScript

mobile / responsive design

Estimated reading time: 4 minutes, 30 seconds

There is a design truism that has been largely avoided in the web development industry to this point: not every image responds well to scaling. I’m not referring here to image quality – a relevant issue, but one that should eventually be addressed by advances such as the srcset attribute – but to aesthetics, particularly the visual relationship of pictures with other elements on the page.

As an example, take a fairly wide-aspect image used as a banner image, particularly one with a strong focal point. The image will work well on a desktop monitor with the browser maximized, but narrowing the window causes the responsive image to look increasingly out-of-balance with page content at smaller sizes:

Typical scaling for a responsive header image

Ideally, we would prefer the image to be dynamically cropped as it scaled down, narrowing to the picture’s central point of interest:

Art-directed scaling for a responsive header image

This focal point could be anywhere in the photograph, and we still want the image to be responsive, meaning that we can’t just use some kind of “sliding door” technique to narrow down what we see on the page.

Current Solutions & Their Drawbacks

It is possible to use and several image files to achieve this, at the cost of swapping multiple image files back and forth over a potentially weak and thin wireless connection. The proposed <picture> element and Scott Jehl’s picturefill solution achieve the same result, at the same expense of bandwidth.

In an ideal world we would have an image format that integrated “dynamic crop marks”, allowing a single source image to adapt to different requirements while preserving its central focus. While we don’t have such a feature yet, we do have ’s viewBox attribute, which comes awfully close.

Bitmap Images In SVG

While it is best known as a vector image format, SVG has supported bitmaps from its inception:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1200 450" xml:space="preserve">
<image overflow="visible" width="1200" height="450" xlink:href="cape-reinga.jpg">
</image>
</svg>

Note that the width and height of the bitmap are set as attributes, and that the same dimensional attributes that would normally be applied to the SVG root element have been removed to make it . This responsive approach must also be followed in the way we embed the SVG file into an page:

<object data="cape.svg" type="image/svg+xml" style="width:100%;height:auto;" id="repsvg"></object>

The <object> tag also has the advantage of bringing with it a fallback solution for older browsers that do not support SVG, such as IE8: simply place an image between the opening and closing tag:

<object data="cape.svg" type="image/svg+xml" style="width:100%;height:auto;" id="repsvg">
<img src="cape-reinga.jpg" alt="Photograph of Cape Reinga, New Zealand" style="width: 100%; height: auto">
</object>

Currently, it’s easiest to make art direction choices in a bitmap editing program such as PhotoShop.

Becoming Your Very Own Art Director

Choosing where to crop the banner image will depend on many factors. For this example, I chose two crop areas, shown in highlight below. Descisions for art-directed crop

Manipulating The viewBox With JavaScript

SVG’s viewBox is a rather complex beast that I’ll address in a separate article: for now, it’s easiest to think of viewBox as the visible area of an SVG document. Unfortunately, we can’t manipulate the viewBox via CSS, but we can do so via JavaScript.

JavaScript can either be placed directly in an SVG file, or influence it from outside. We’ll opt for the second option, as it reduces cross-domain and mobile scripting issues. In the HTML file that includes the SVG document, add the following:

<script>
var a = document.getElementById("repsvg");
a.addEventListener("load",function(){
var svgDoc = a.contentDocument; 
var svg = svgDoc.getElementsByTagName("svg")[0]; 
maxcheck = window.matchMedia("(max-width: 1200px)");
screencheck = window.matchMedia("(max-width: 1000px)");
mobilecheck = window.matchMedia("(max-width: 500px)");
function setSize(){ 
if (maxcheck.matches) { svg.setAttribute("viewBox", "0 0 1200 450"); }
if (screencheck.matches) { svg.setAttribute("viewBox", "400 0 800 450"); }
if (mobilecheck.matches) {  svg.setAttribute("viewBox", "300 100 500 350"); }
}
window.addEventListener('resize', function() { setSize(); }, true); })
</script>

As the SVG document may take a little while to appear on the page, we place an addEventListener on its load event, then work our way inside the document by using contentDocument and getElementsByTagName. As the browser window widens and narrows, the script uses a series of matchMedia checks to set the viewBox to new dimensions that crop the image, with the result you see at the top of this article when you resize the browser window.

Taking The Idea Further

In April, Estelle Weyl proposed an SVG “clown car” technique as a practical, present-day equivalent to <picture> and srcset. The technique I use here might be thought of as a derivation of this idea. Taking it further could involve a hybrid of both sets of code.

As presented, this art-directed image solution has the advantage of employing just one image for multiple art purposes. The disadvantage, of course, is that every device must load the same large image. In this case, that’s not a big deal (the complete banner image is less than 22k in size), but could be a factor with other image choices.

The other issue is that this solution modularizes the art direction into JavaScript, separately from the CSS. In many ways this makes sense, but it does divide the presentation components of a site.

Photograph by Peter Rein-Hodurek, used with permission.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.