Blog

Outrunning the Bear: the Problem with Responsive Images

I’m all in favour of responsive design for one reason more than anything else: I hate zooming in on squinty text on my phone. Most sites have a small enough body font combined with a long enough measure that even when zoomed in on the content column, I have to turn my 480*800 pixel screen to landscape just to be able to read it. Responsive design neatly solves the problem of the vast number of devices and resolutions which are used to consume the modern Web (if you need to get up to date on it, I can heartily recommend Ethan Marcotte‘s book: Responsive Web Design).

The attention of the Web community has now turned to the scaling of images, and how to serve up bandwidth-optimised versions of each image, appropriate to the scale and context at which they’ll be displayed. Heads have been scratched and solutions have been proposed, but for better or worse, they’re all hacks to some degree. Most (if not all) of these techniques are formulated under the assumption that they’ll be implemented by designers and front-end developers who understand the nuances of the markup they’re writing. How much markup is written by people who don’t know or care about responsive design, or generated by a CMS?

I can only speak from my own experience, but to me there’s little to no value to a client in a static HTML brochure site any more. Producing static HTML puts the client at the mercy of the designer when they need to make changes, and producing a WordPress theme (for example) is scarcely more labour-intensive than a static design of the same number of pages as WP templates. So here we have the case where the client may be adding content to their new responsive site, and this is where we run into the problem with the raft of responsive image techniques currently available: they all require specific changes (some more semantic than others) to the format of the markup – none of them are a transparent solution that can be dropped into place and work with a simple <img> element, such as those inserted in Content Management Systems by people who don’t write HTML.

I’ve done a lot of thinking myself on the subject. I don’t pretend to be able to solve problems that our best and brightest have to date failed to solve, but I’ve come to a somewhat surprising conclusion: I don’t care about responsive images, at least not for the moment. There’s an old joke that goes something like this:

Two campers are walking through the forest when they encounter a grizzly bear, which rears up on its hind legs and lets out a terrifying roar. Both campers are frozen in their tracks. The first camper whispers, “I’m glad I wore my running shoes today.”

“It doesn’t matter what kind of shoes you’re wearing, you’re not gonna outrun that bear,” replies the second.

“I don’t have to outrun the bear,” the first camper replies, “I just have to outrun you.”

We’ve all been trying to come up with more and more elaborate ways to outrun the bear, when by dint of adapting to screen size and orientation, our responsive designs will easily outpace the more pedestrian fixed-width sites that currently make up the vast majority of a user’s experience. (I’m aware of the irony that this site is not, at time of writing, responsive. I’m working on it.)

Posted in HTML | Tagged , , | Leave a comment

Load JQuery from Google’s CDN with local fallback in WordPress

The advantages of loading scripts from Google’s CDN are fairly obvious – for a common script such as jQuery, we’re on to a better-than-even chance that the user will already have the script in their browser’s cache from other sites, reducing the total download weight of your site. Even if they don’t, the file will be downloaded from their nearest Google CDN server, which will still be faster than downloading it from your site because it will be downloading in parallel from a different host.

Including jQuery in WordPress the Right Way™

A fairly common technique in WordPress is to include jQuery in the footer with wp_enqueue_script(), like so:

<?php
function rd_include_jquery() {
    wp_deregister_script('jquery');
    wp_register_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js'), false, false, true;
    wp_enqueue_script('jquery');
}
add_action('wp_enqueue_scripts', 'rd_include_jquery');
?>

But what happens on the rare occasions where Google’s CDN is down or unreachable? Maybe they’re having technical problems, or you’re working offline, or any number of things which could get between your site and Google’s CDN. HTML5 Boilerplate has a great workaround for this, which immediately follows the jQuery load with the following:

<script type="text/javascript">window.jQuery || document.write('<script src="js/libs/jquery-1.5.1.min.js">\x3C/script>')</script>

Because this method relies on writing the script element directly to the page after the jQuery call, it would seem to be totally incompatible with wp_enqueue_script. Don’t worry, you don’t have to revert to manually writing out script calls in your header or footer. Here’s what we’re going to do:

Including jQuery in WordPress the Right Way™ (the Turbocharged, Bulletproof Local Fallback Edition)

First, we need to solve the problem of determining if Google’s CDN is accessible, which we’ll do with wp_remote_head(). Assuming that’s available, we’ll cache the HTTP response using the WP Transients API to avoid having to make the same request every time a page is loaded – the right value for the transient’s $expiration value will depend on the traffic of the site, but for the sake of demonstration let’s set it to 5 minutes.

function rd_bulletproof_jquery() {
$url = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
wp_deregister_script('jquery');
if (get_transient('google_jquery') == true) {	    
	wp_register_script('jquery', $url, array(), null, true);
} 
else {
	$resp = wp_remote_head($url);
	if (!is_wp_error($resp) && 200 == $resp['response']['code']) {
		set_transient('google_jquery', true, 60 * 5);
		wp_register_script('jquery', $url, array(), null, true);
	} 
	else {
		set_transient('google_jquery', false, 60 * 5);
		$url = get_bloginfo('wpurl') . '/wp-includes/js/jquery/jquery.js';
		wp_register_script('jquery', $url, array(), '1.7.1', true);
	}
}
wp_enqueue_script('jquery');
}
add_action('wp_enqueue_scripts', 'rd_bulletproof_jquery');

Credits: based on the work of Christopher Davis.

Posted in WordPress | Tagged , , , , | 3 Comments

An Open Letter to Trent Reznor

So, Trent. Iunderstand you’ve allowed one of those interchangeable X Factor automatons to cover Hurt. Do you remember what you said back in 2004, when Led Zeppelin licensed Rock and Roll for a Cadillac ad? Let me refresh your memory:

“How much money does Led fucking Zeppelin need? Do they realize (or care) that when you hear their track now, you visualize a shitty car whizzing by? Do they understand the significance of what their music once held for people — or is it really all about how many units you can sell and commerce at any cost?”

Wise words, Trent. Wise words.

Posted in thoughts | Tagged , , | Leave a comment

Setting up the Perfect Web Development Environment, Part 2

Setting up a Portable Project

In Part 1 of this guide, we covered how to set up a portable development environment with the basic set of software tools (a web stack, an IDE and a good text editor). Continuing on, we’ll create a project and make it portable. The instructions given are specific to Netbeans because that’s what we set up in Part 1, but can be easily adapted to your IDE of choice. Once again, you’ll need to follow the first part of this guide on both desktop and laptop.

Continue reading

Posted in code | Tagged , , , , | 2 Comments

Yarrr this be talk like a pirate day. while ( timbers.length > 0 && owner === ‘me’ ) { shiver() }

Chris Heilmann on Twitter

Posted on by Chris | Leave a comment

Setting up the Perfect Web Development Environment, Part 1

Inspired by Elliot Jay Stocks’ recent posts on his iMac plus Air setup, I thought I’d document how to set up a seamless development environment between desktop and laptop. If you intend to set up a similar environment, you’ll need to perform these steps identically on both machines. Part 2 of this series will deal with the basics of setting up a portable project, and Part 3 will cover setting up advanced tools and source control.

Continue reading

Posted in code | Tagged , , , , , | 2 Comments

Adaptive Content (with a dash of jQuery)

Aral Balkan posted the following snippet on Twitter just now:

<span>u</span><span class="hideIf320">ser e</span><span class="capIf320">x</span><span class="hideIf320">perience</span>

followed by the explanation:

Continue reading

Posted in code | Tagged , , | 4 Comments

So, you think you know how to support your product?

You should probably take a look at this.

 

Posted in marketing | Leave a comment

Your Client Does Not Know More than You

I read an article on Six Revisions today on the subject of a designer’s perceived arrogance versus the client’s better knowledge of their business. It could have been a good article; it had some very valid points, but it was completely spoiled by setting up the most egregious straw man it’s ever been my misfortune to read.

Continue reading

Posted in design | Tagged , , | 1 Comment

April Fool’s Day, 2011: best of the web

A collection of some of the best April Fool’s Day pranks I’ve seen this year.

 

Posted in Uncategorized | Tagged | Leave a comment