Wednesday, May 29, 2013

Importing Images From External URL into Magento 1.7.02

There are occasions where you might not have access to downloading the images from your current setup into the Magento or it is simply easier to reference the current file path on an external URL. The following snipet will add the ability for you to grab images from an external URL when importing products through a data feed. Rather then setting up the image column within the data feed with /image-name.jpg you can now use the full URL path http://www.domain.com/image-name.jpg as an example.
Download the following file – /app/code/core/Mage/Catalog/Model/Convert/Adapter/Product.php and and code for it is instead of this one:
foreach ($product->getMediaAttributes() as $mediaAttributeCode => $mediaAttribute) {
if (isset($importData[$mediaAttributeCode])) {
$file = trim($importData[$mediaAttributeCode]);
if (!empty($file) && !$mediaGalleryBackendModel->getImage($product, $file)) {
$arrayToMassAdd[] = array(‘file’ => trim($file), ‘mediaAttribute’ => $mediaAttributeCode);
}
}
}
put this one:
foreach ($product->getMediaAttributes() as $mediaAttributeCode => $mediaAttribute) {
if (isset($importData[$mediaAttributeCode])) {
$file = trim($importData[$mediaAttributeCode]);
if (!empty($file) && !$mediaGalleryBackendModel->getImage($product, $file)) {
// Start Of Code To Import Images From Urls
if (preg_match(‘%https?://[a-z0-9\-./]+\.(?:jpe?g|png|gif)%i’, $file)) {
$path_parts = pathinfo($file);
$html_filename = DS . $path_parts['basename'];
$fullpath = Mage::getBaseDir(‘media’) . DS . ‘import’ . $html_filename;
if(!file_exists($fullpath)) {
$ch = curl_init ($file);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$rawdata=curl_exec($ch);
curl_close ($ch);
if(file_exists($fullpath)) {
unlink($fullpath);
}
$fp = fopen($fullpath,’x’);
fwrite($fp, $rawdata);
fclose($fp);
}
$arrayToMassAdd[] = array(‘file’ => trim($html_filename), ‘mediaAttribute’ => $mediaAttributeCode);
}
else
{
$arrayToMassAdd[] = array(‘file’ => trim($file), ‘mediaAttribute’ => $mediaAttributeCode);
}
}
}
}

Monday, May 13, 2013

How To Avoid Duplicate Downloads In Responsive Images

The <picture> element is a new addition to HTML5 that’s being championed by the W3C’s Responsive Images Community Group (RICG). It is intended to provide a declarative, markup-based solution to enable responsive images without the need of JavaScript libraries or complicated server-side detection.
The <picture> element supports a number of different types of fallback content, but the current implementation of these fallbacks is problematic. In this article, we’ll explore how the fallbacks work, how they fail and what can be done about it.

The <picture> Element And Fallback Content

Like <video> and <audio>, <picture> uses <source> elements to provide a set of images that the browser can choose from. The <source> elements may optionally contain type and media attributes to let the browser know the file type and media type of the source, respectively. Given the information in the attributes, the browser should render the first <source> with a supported file type and matching media query. For example:
<picture>
    <source src="landscape.webp" type="image/webp" media="screen and (min-width: 20em) and (orientation: landscape)" />
    <source src="landscape.jpg" type="image/jpg" media="screen and (min-width: 20em) and (orientation: landscape)" />
    <source src="portrait.webp" type="image/webp" media="screen and (max-width: 20em) and (orientation: portrait)" />
    <source src="portrait.jpg" type="image/jpg" media="screen and (max-width: 20em) and (orientation: portrait)" />
</picture>
For situations in which a browser doesn’t know how to deal with <picture> (or <video> or <audio>) or cannot render any of the <source> elements, a developer can include fallback content. This fallback content is often either an image or descriptive text; if the fallback content is an <img>, then a further fallback is provided in the alt attribute (or longdesc), as normal.
<picture>
    <source type="image/webp" src="image.webp" />
    <source type="image/vnd.ms-photo" src="image.jxr" />
    <img src="fallback.jpg" alt="fancy pants">
</picture>
The <picture> element differs from <video> and <audio> in that it also allows srcset. The srcset attribute enables a developer to specify different images based on a device’s pixel density. When creating a responsive image using both <picture> and srcset, we might expect something like the following:
<picture>
    <source srcset="big.jpg 1x, big-2x.jpg 2x, big-3x.jpg 3x" type="image/jpeg" media="(min-width: 40em)" />
    <source srcset="med.jpg 1x, med-2x.jpg 2x, med-3x.jpg 3x" type="image/jpeg" />
    <img src="fallback.jpg" alt="fancy pants" />
</picture>
The idea behind a <picture> example like this is that exactly one image should be downloaded, according to the user’s context:
  • Users with <picture> support and a viewport at least 40 ems wide should get the big image.
  • Users with <picture> support and a viewport narrower than 40 ems should get the med image.
  • Users without <picture> support should get the fallback image.
If the browser chooses to display the big or med source, it can choose an image at an appropriate resolution based on the srcset attribute:
  • A browser on a low-resolution device (such as an iMac) should show the 1x image.
  • A browser on a higher-resolution device (such as an iPhone with a Retina display) should show the 2x image.
  • A browser on a next-generation device with even higher resolution should show the 3x image.
The benefit to the user is that only one image file is downloaded, regardless of feature support, viewport dimensions or screen density.
The <picture> element also has the ability to use non-image fallbacks, which should be great for accessibility: if no image can be displayed or if a user needs a description of an image, then a <p> or <span> or <table> or any other element may be included as a fallback. This allows for more robust and content-appropriate fallbacks than a simple alt attribute.

The Fallback Problem

Right now, the <picture> element is not supported in any shipped browsers. Developers who want to use <picture> can use Scott Jehl’s Picturefill polyfill. Also, Yoav Weiss has created a Chromium-based prototype reference implementation that has partial support for <picture>. This Chromium build not only shows that browser support for <picture> is technically possible, but also enables us to check functionality and behavior against our expectations.
When testing examples like the above in his Chromium build, Yoav spotted a problem: even though <picture> is supported, and even though one of the first two <source> elements was being loaded, the fallback <img> was also loaded. Two images were being downloaded, even though only one was being used.
networkpane1-500
Larger view.
This happens because browsers “look ahead” as HTML is being downloaded and immediately start downloading images. As Yoav explains:
“When the parser encounters an img tag it creates an HTMLImageElement node and adds its attributes to it. When the attributes are added, the node is not aware of its parents, and when an ‘src’ attribute is added, an image download is immediately triggered.”
This kind of “look ahead” parsing works great most of the time because the browser can start downloading images even before it has finished downloading all of the HTML. But in cases where an img element is a child of <picture> (or <video> or <audio>), the browser wouldn’t (currently) care about the parent element: it would just see an img and start downloading. The problem also occurs if we forget about the parent element and just consider an <img> that has both the src and srcset attributes: the parser would download the src image before choosing and downloading a resource from srcset.
<picture>
    <source srcset="big.jpg 1x, big-2x.jpg 2x, big-3x.jpg 3x" media="(min-width: 40em)" />
    <source srcset="med.jpg 1x, med-2x.jpg 2x, med-3x.jpg 3x" />
    <img src="fallback.jpg" alt="fancy pants" />
    <!-- fallback.jpg is *always* downloaded -->
</picture>

<img src="fallback.jpg" srcset="med.jpg 1x, med-2x.jpg 2x, med-3x.jpg 3x" alt="fancy pants" />
<!-- fallback.jpg is *always* downloaded -->

<video>
    <source src="video.mp4" type="video/mp4" />
    <source src="video.webm" type="video/webm" />
    <source src="video.ogv" type="video/ogg" />
    <img src="fallback.jpg" alt="fancy pants" />
    <!-- fallback.jpg is *always* downloaded -->
</video>
In all of these cases, we would have multiple images being downloaded instead of just the one being displayed. But who cares? Well, your users who are downloading extra content and wasting time and money would care, especially the ones with bandwidth caps and slow connections. And maybe you, too, if you’re paying for the bandwidth you serve.

A Potential Solution

This problem needs both short- and long-term solutions.
In the long term, we need to make sure that browser implementations of <picture> (and <video> and <audio>) can overcome this bug. For example, Robin Berjon has suggested that it might be possible to treat the contents of <picture> as inert, like the contents of <template>, and to use the Shadow DOM (see, for example, “HTML5’s New Template Tag: Standardizing Client-Side Templating”). Yoav has suggested using an attribute on <img> to indicate that the browser should wait to download the src.
While changing the way the parser works is technically possible, it would make the implementation more complicated. Changing the parser could also affect JavaScript code and libraries that assume a download has been triggered as soon as a src attribute is added to an <img>. These long-term changes would require cooperation from browser vendors, JavaScript library creators and developers.
In the short term, we need a working solution that avoids wasted bandwidth when experimenting with <picture> and srcset, and when using <video> and <audio> with <img> fallbacks. Because of the difficulty and time involved in updating specifications and browsers, a short-term solution would need to rely on existing tools and browser behaviors.
So, what is currently available to us that solves this in the short term? Our old friends <object> and <embed>, both of which can be used to display images. If you load an image using these tags, it will display properly in the appropriate fallback conditions, but it won’t otherwise be downloaded.
Different browsers behave differently according to whether we use <object>, <embed> or both. To find the best solution, I tested (using a slightly modified version of this gist) in:
  • Android browser 528.5+/4.0/525.20.1 on Android 1.6 (using a virtualized Sony Xperia X10 on BrowserStack)
  • Android browser 533.1/4.0/533.1 on Android 2.3.3 (using a virtualized Samsung Galaxy S II on BrowserStack)
  • Android browser 534.30/4.0/534.30 on Android 4.2 (using a virtualized LG Nexus 4 on BrowserStack)
  • Chrome 25.0.1364.160 on OS X 10.8.2
  • Chromium 25.0.1336.0 (169465) (RICG Build) on OS X 10.8.2
  • Firefox 19.0.2 on OS X 10.8.2
  • Internet Explorer 6.0.3790.1830 on Windows XP (using BrowserStack)
  • Internet Explorer 7.0.5730.13 on Windows XP (using BrowserStack)
  • Internet Explorer 8.0.6001.19222 on Windows 7 (using BrowserStack)
  • Internet Explorer 9.0.8112.16421 on Windows 7 (using BrowserStack)
  • Internet Explorer 10.0.9200.16384 (desktop) on Windows 8 (using BrowserStack)
  • Opera 12.14 build 1738 on OS X 10.8.2
  • Opera Mobile 9.80/2.11.355/12.10 on Android 2.3.7 (using a virtualized Samsung Galaxy Tab 10.1 on Opera Mobile Emulator for Mac)
  • Safari 6.0.2 (8536.26.17) on OS X 10.8.2
  • Safari (Mobile) 536.26/6.0/10B144/8536.25 on iOS 6.1 (10B144) (using an iPhone 4)
  • Safari (Mobile) 536.26/6.0/10B144/8536.25 on iOS 6.1 (10B141) (using an iPad 2)
I ran five tests:
  1. <picture> falls back to <object>
  2. <picture> falls back to <embed>
  3. <picture> falls back to <object>, which falls back to <embed>
  4. <picture> falls back to <object>, which falls back to <img>
  5. <picture> falls back to <img>
I found the following support:
What the user sees

Test 1 Test 2 Test 3 Test 4 Test 5
Android 1.6 fallback image fallback image fallback image fallback image fallback image
Android 2.3 fallback image fallback image fallback image fallback image fallback image
Android 4.2 fallback image fallback image fallback image fallback image fallback image
Chrome 25 fallback image fallback image fallback image fallback image fallback image
Chromium 25 (RICG) picture/source image picture/source image picture/source image picture/source image picture/source image
Firefox 19 fallback image fallback image fallback image fallback image fallback image
IE 6 no image no image no image no image fallback image
IE 7 no image no image no image no image fallback image
IE 8 fallback image no image fallback image fallback image fallback image
IE 9 fallback image fallback image (cropped and scrollable) fallback image fallback image fallback image
IE 10 fallback image fallback image (cropped and scrollable) fallback image fallback image fallback image
Opera 12.1 fallback image fallback image fallback image fallback image fallback image
Opera Mobile 12.1 fallback image fallback image fallback image fallback image fallback image
Safari 6 fallback image fallback image fallback image fallback image fallback image
Safari iOS 6 (iPad) fallback image fallback image fallback image fallback image fallback image
Safari iOS 6 (iPhone) fallback image fallback image fallback image fallback image fallback image
HTTP requests

Test 1 Test 2 Test 3 Test 4 Test 5
Android 1.6 1 GET 1 GET 1 GET 2 GETs 1 GET
Android 2.3 1 GET 1 GET 1 GET 2 GETs 1 GET
Android 4.2 1 GET 1 GET 1 GET 2 GETs 1 GET
Chrome 25 1 GET 1 GET 1 GET 2 GETs 1 GET
Chromium 25 (RICG) 1 GET 1 GET 1 GET 2 GETs 2 GETs
Firefox 19 1 GET 1 GET 2 GETs 2 GETs 1 GET
IE 6 1 GET none 1 GET 1 GET 1 GET
IE 7 1 GET none 1 GET 1 GET 1 GET
IE 8 1 GET none 1 GET 1 GET 1 GET
IE 9 1 HEAD, 1 GET 1 GET 1 HEAD, 1 GET 1 HEAD, 2 GETs 1 GET
IE 10 1 HEAD, 1 GET 1 GET 1 HEAD, 1 GET 1 HEAD, 2 GETs 1 GET
Opera 12.1 1 GET 1 GET 1 GET 2 GETs 1 GET
Opera Mobile 12.1 1 GET 1 GET 1 GET 2 GETs 1 GET
Safari 6 1 GET 1 GET 1 GET 2 GETs 1 GET
Safari iOS 6 (iPad) 1 GET 1 GET 1 GET 2 GETs 1 GET
Safari iOS 6 (iPhone) 1 GET 1 GET 1 GET 2 GETs 1 GET
Image-aware context menu

Test 1 Test 2 Test 3 Test 4 Test 5
Android 1.6 yes yes yes yes yes
Android 2.3 yes yes yes yes yes
Android 4.2 yes yes yes yes yes
Chrome 25 no no no no yes
Chromium 25 (RICG) no no no no no
Firefox 19 yes yes yes yes yes
IE 6 no no no no yes
IE 7 no no no no yes
IE 8 yes no yes yes yes
IE 9 yes yes yes yes yes
IE 10 yes yes yes yes yes
Opera 12.1 yes yes yes yes yes
Opera Mobile 12.1 yes no yes yes yes
Safari 6 no no no no yes
Safari iOS 6 (iPad) no no no no yes
Safari iOS 6 (iPhone) no no no no yes

Making Sure The Content Is Accessible

Although the specifics of how to provide fallback content for <picture> are still being debated (see also this thread), I wanted to test how Apple’s VoiceOver performed with different elements. For these experiments, I checked whether VoiceOver read alt attributes in various places, as well as fallback <span> elements. Unfortunately, I wasn’t able to test using other screen readers or assistive technology, although I’d love to hear about your experiences.
Read by VoiceOver

alt on picture alt on source (picturesource) alt on object (pictureobject) alt on embed (pictureembed) alt on embed (pictureobjectembed)
Chrome 25 no no yes yes no
Chromium 25 (RICG) yes no no no no
Firefox 19 no no yes yes no
Opera 12.1 no no no no no
Safari 6 no no yes yes no
Safari iOS 6 (iPad) no no yes yes no
Safari iOS 6 (iPhone) no no yes yes no
Read by VoiceOver

alt on img (pictureobjectimg) alt on img (pictureimg) span (picturespan) span (pictureobjectspan)
Chrome 25 no yes yes no
Chromium 25 (RICG) no no no no
Firefox 19 no yes yes no
Opera 12.1 no no yes no
Safari 6 no yes yes no
Safari iOS 6 (iPad) no yes yes no
Safari iOS 6 (iPhone) no yes yes no

Bulletproof Syntax

Based on these data, I’ve come up with the following “bulletproof” solution:
<picture alt="fancy pants">
    <!-- loaded by browsers that support picture and that support one of the sources -->
    <source srcset="big.jpg 1x, big-2x.jpg 2x, big-3x.jpg" type="image/jpeg" media="(min-width: 40em)" />
    <source srcset="med.jpg 1x, med-2x.jpg 2x, big-3x.jpg" type="image/jpeg" />

    <!-- loaded by IE 8+, non-IE browsers that don’t support picture, and browsers that support picture but cannot find an appropriate source -->
    <![if gte IE 8]>
    <object data="fallback.jpg" type="image/jpeg"></object>
    <span class="fake-alt">fancy pants</span>
    <![endif]>

    <!-- loaded by IE 6 and 7 -->
    <!--[if lt IE 8]>
    <img src="fallback.jpg" alt="fancy pants" />
    <![endif]-->
</picture>

.fake-alt {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
}
Here we have a <picture> element, two sources to choose from for browsers that support <picture>, a fallback for most other browsers using <object> and a <span> (see note just below), and a separate <img> fallback for IE 7 and below. The empty alt prevents the actual image from being announced to screen readers, and the <span> is hidden using CSS (which is equivalent to HTML5 Boilerplate’s .visuallyhidden class) but still available to screen readers. The <embed> element is not needed.
(Note: The use of the <span> as a fake alt is necessary so that VoiceOver reads the text in Opera. Even though Opera has a relatively small footprint, and even though it’s in the process of being switched to WebKit, I still think it’s worth our consideration. However, if you don’t care about supporting that particular browser, you could get rid of the <span> and use an alt on the <object> instead (even though that isn’t strictly allowed by the specification). This is assuming that the <span> and alt have the same content. If you have a richer fallback element, such as a <table>, using both it and a non-empty alt attribute might be desirable.)
A similar solution should also work with <audio>, although <img> fallbacks for that element are, admittedly, rare. When dealing with <video>, the problem goes away if our fallback image is the same as our poster image. If these may be the same, then the “bulletproof” syntax for <video> would be this:
<video poster="fallback.jpg">
    <!-- loaded by browsers that support video and that support one of the sources -->
    <source src="video.mp4" type="video/mp4" />
    <source src="video.webm" type="video/webm" />
    <source src="video.ogv" type="video/ogg" />

    <!-- loaded by browsers that don't support video, and browsers that support video but cannot find an appropriate source -->
    <img src="fallback.jpg" alt="fancy pants" />
</video>
However, if your <video> needs a separate fallback and poster image, then you might want to consider using the same structure as the <picture> solution above.
Note that <video> and <audio> don’t have alt attributes, and even if you add them, they will be ignored by VoiceOver. For accessible video, you might want to look into the work being done with Web Video Text Tracks (WebVTT).
Unfortunately, extensive testing with <video> and <audio> elements is beyond the scope of this article, so let us know in the comments if you find anything interesting with these.

How Good (Or Bad) Is This Solution?

Let’s get the bad out of the way first, shall we? This solution is hacky. It’s obviously not workable as a real, long-term solution. It is crazy verbose; no one in their right mind wants to code all of this just to put an image on a page.
Also, semantically, we really should use an <img> element to display an image, not an <object>. That’s what <img> is for.
And there are some practical issues:
  • Chrome and Safari won’t show proper context menus for the images, meaning that users won’t be able to open or save them easily.
  • IE 9 and 10 send an extra HEAD request along with the GET request.
  • Using a <span> as a fake alt is pretty sketchy, and although it worked for my tests in VoiceOver, it could potentially cause other accessibility problems.
All that being said, as a short-term solution, it’s not too bad. We get these benefits:
  • A visible image in every browser is tested (<picture> and <source> when supported, and the fallback otherwise).
  • Only one HTTP GET request in every browser is tested (and the extra HEAD request and response in IE are tiny).
  • VoiceOver is supported (and is hopefully supported with other screen readers).
networkpane2-500
Larger view.
The semantics of the solution, while not ideal, are not horrible either: the HTML5 specification states that an <object> “element can represent an external resource, which, depending on the type of the resource, will either be treated as an image, as a nested browsing context, or as an external resource to be processed by a plugin” (emphasis mine).
And although the <span> is not as nice as a real alt attribute, using a visually hidden element for accessibility is not uncommon. Consider, for example, “Skip to content” links that are visibly hidden but available to screen readers.

Next Steps

The best part about this solution, though, is that it highlights how bad the current situation is. This is a real problem, and it deserves a better solution than the monstrosity I’ve proposed.
We need discussion and participation from both developers and browser vendors on this. Getting support from browser makers is crucial; a specification can be written for any old thing, but it doesn’t become real until it is implemented in browsers. Support from developers is needed to make sure that the solution is good enough to get used in the real world. This consensus-based approach is what was used to add the <main> element to the specification recently; Steve Faulkner discusses this process a bit in his excellent interview with HTML5 Doctor.
If you’re interested in helping to solve this problem, please consider joining the discussion:

Sunday, May 12, 2013

How Much Has The Web Really Changed?

Responsive design is about more than just layout; it’s about designing for the Web, which means, mostly, for people with browsers. And that’s just about everything we know about the people who visit our websites: they are probably using a browser. All the rest we just don’t know.
Up until not so long ago, we used to base our designs on some rather general assumptions about screen size and input type. With the rise of devices with various screen sizes and alternative ways to interact, these assumptions have turned out to be unreliable. We need to upgrade the defaults that we use when we start designing our websites.

A Closer Look

People keep saying that the Web has changed. But has it really? Let’s take a look at all of the things that have actually changed.

Screen Sizes

In the 1990s, the Web was 640 pixels wide. In the early 2000s, it grew to 800 pixels. A few years later, we decided it should be 1024 pixels. But five years ago, all of a sudden, something strange happened. A device with a very small screen entered the market. Suddenly, our ideas about the size of the Web did not work anymore. Later on, tablets entered the market. People hold these things however they want. Today, the height of the viewport could be bigger than the width! But is that new? Not really.
Screen sizes, shown in a non-flexible medium. Photo and work by Aram Bartholl.
Screen sizes, shown in a non-flexible medium. (Photo and work: Aram Bartholl)
We never really knew what size the window of our visitors would be. We just assumed it was at least the random pixel width that we felt comfortable with. These numbers were always arbitrary, and there were always people who could not see the entire website. We simply ignored them.

“Everyone Has a Mouse”

We’ve always assumed that everyone uses a mouse. Even though we knew that this was not always true, most designs completely ignored alternative ways of interacting. People who had to use a keyboard, for whatever reason, had a very hard time interacting with our websites.
But because most people did use a mouse, and because back then many designers thought that designing only for the majority was OK, we created websites that were unusable for a lot of people. And this turned out to be a growing number. Many mouseover interactions are completely dysfunctional on a touch device. Because people love these devices, and even managers and designers use them, they are harder to ignore.

“Everyone Has Broadband Internet”

Another thing we always assumed was that everyone had a super-fast Internet connection, at least as fast as our own. And if they didn’t already have it, they’d have it soon. This was again mostly true; speeds were increasing. But today, more and more people use crappy, unreliable 3G connections all the time. If you’ve ever travelled on a train in The Netherlands, you know what I mean. And if you’ve ever had to rely on the mythical “free hotel Wi-Fi,” then you know for sure that the assumption about the ever-increasing speed of our Internet connections is just not true. This is a big change in our thinking; we really should consider these users. This will have a major impact on what our designs look like.

“Everyone’s Computer Gets Faster Every Year”

It used to be true that computers would get faster and faster. If you waited half a year before buying a computer, you would get one that was twice as fast, for the same price. This was true of new desktop computers, but mobile devices have priorities other than processor speed. The most important thing for a phone, for instance, is battery life: you really don’t want to have to charge it after every phone call.
And there’s another trend: instead of creating ever-faster devices, many manufacturers are starting to sell ever-cheaper devices. Many people care about price and battery life more than about processor speed. This is also not new: what happened to your old computers? You probably sold them or gave them away. People keep using old stuff. Not everyone has the same hardware as we designers do.

“All Monitors Are Calibrated”

Well, we always knew this to be untrue, right? Only the monitors of visual professionals are calibrated. Most other monitors don’t display colors accurately, and many monitors are downright crappy. Most mobile phones that I’ve tested have pretty decent screens, until you start using them outside, in the sunshine. If you’re lucky, you can read the content, but you definitely cannot see the subtle gradients in low-contrast designs.
I haven’t even mentioned “modern” black and white screens. These, too, are not new. People have always used crappy monitors, and people with bad eyesight have always visited your websites. It’s just that more and more people are seeing a subpar color palette. Instead of buying a state of the art monitor, buying a cheap monitor and several low-end devices to test your work on might be a better investment.
All of these things are not new. In 2002, John Allsopp wrote the monumental article “A Dao of Web Design.” People such as Jeremy Keith and Roger Johansson have written about all of these facts for years and years. And yet, somehow, we’ve always managed to actively ignore them. But we really can’t anymore. The Web actually did change in the last five years, with new devices, new browsers and many, many cool new features. We need new defaults. The old ways of creating websites just don’t work anymore.
This Is Responsive, the excellent resource about responsive design by Brad Frost.
This Is Responsive, the excellent resource about responsive design by Brad Frost.
In the past few years, we’ve been actively researching new ways to deal with all of these different screen sizes. But apart from responsive design, there are many more challenges in today’s ever-growing pile of devices. We have to find new patterns of interaction: we need interfaces that work on any device. Maybe we have to reconsider that enormous photo carousel on the home page, now that we know that not everyone has a cheap and fast connection. New defaults are emerging, and I’ve collected a few for you here.
The things in this article are not new. Many clever people have written about them in many articles and many books. But these ideas, like all good stories, have to be repeated many times so that people understand and remember them.

New Default: Activate

I initially titled this section “New Default: Touch.” But I came to realize that “touch” has a different meaning for everyone. Some people, like me, think of a single tap when we hear the word. Others think about swiping and complex gestures. That’s why I settled on the heading “New Defaults: Activate.” All devices, no matter what kind of input they offer, let the user activate something in some way.
With a mouse, it’s a click; with a touch device, it’s a tap; on a keyboard, it’s the “Enter” key. There are ways to activate things by voice, and by waving your arms in the air. And many devices offer more than one way to interact. The only thing that all of these devices have in common is the action of activating. Most of them are capable of doing many other things, too, but all of them can activate stuff.
Only recently have we really started thinking about alternative methods of user input. We used to assume that everyone uses a mouse. Hiding content and showing it on mouseover was considered to be a decent design pattern. And it used to work for most people — until all of these wonderful touch devices entered the market. What should a device without a mouse do when content can be revealed only with a mouse? Different devices have different solutions. Let’s look at a simple drop-down menu.
You can find a live example of this navigation pattern right here.
See a live example of this navigation pattern.
When you hover over a menu item, a submenu appears. But apart from hovering over an item, you can also simply click on it to follow the link. Now, what should happen when you tap on the item with a touch device? Should the submenus appear, or should the link activate? Or both? Or should something else happen? On iOS, something else happens. The first time you tap a link like that, the submenu appears; in other words, the hover event fires. You have to tap a second time to actually follow the link. This is confusing, and not many people will tap a second time. On Android, the submenu appears and the link is followed simultaneously. I don’t have to explain to you that this is confusing.
It’s very well possible to think of complex solutions whereby you define different interactions for different input devices. But the better solution, I think, is to make sure that the default interaction, the activate event, just works for everybody. If you really need to, you could choose to enhance this default experience for certain users.
For instance, if you are certain that someone is using a mouse, you could enable some mouseover interactions. Or if you’re sure that someone has fat fingers, you could make small buttons a bit bigger. But only do so in addition to the default activate interaction, and only if there’s no doubt about it, and only if the enhancement would really make things better. Those are quite a few ifs, and some of them, such as the mouse usage, are very hard to detect — especially on devices that offer more than one way to interact, such as a laptop with an optional mouse, touch pad, camera, microphone, keyboard and touchscreen. Give it some serious thought. Do you really need to optimize for a mouse?

New Default: Small Screens

Growing is easy. Most things grow. Babies grow, trees grow, curious minds grow. They don’t grow by themselves, but you don’t need much energy to make things bigger. This is just what things do when they live. While shrinking things is definitely possible, it’s also much harder. You could, for instance, compress a car to a fraction of its original size. A compressed car does have a certain aesthetic appeal to it, but it is definitely not as useful as it was before. The same goes for websites. Shrinking a desktop website does not always result in a pleasant experience on a small screen.
Trees grow on their own, cars are less usefull when they shrink.
Cedro di Versailles by Italian artist Giuseppe Penone clearly shows that things grow. On the other hand, the work Papalote Goliad by American artist John Chamberlain shows that shrinking can be aesthetically appealing but may result in less useful results.
To build a responsive website that works on all kinds of screens, designing for a small screen first is easiest. It forces you to focus on what’s really important: if it doesn’t fit in this small square, it is probably not terribly important. It forces you to think better about hierarchy, about the right order of components on the page.
The same principle that we follow for interactions — whereby we design the activate event first and enhance it later — applies to graphic design. We should start designing the things that we know everyone will see. That’s the content. No matter how big or small a screen is and no matter how minimal the feature set of a browser, it will be able to show letters. Because this is about the only thing we know for certain — since color is absent on most Kindles, most of the latest CSS doesn’t work on old browsers, and layout is of minor importance on small screens — starting with the text is logical.
I wrote an in-depth article about defining breakpoints on the basis of typography, so I won’t repeat every detail here. But the basic idea is that you start by designing the relationship between the different font sizes. Almost everyone, no matter what device they have, will be able to see this. When the typography is done, you would start designing the layout for bigger screens; you can think of this as an enhancement for people with bigger screens. And after that, when the different layouts are done, you could add the paint. And by paint, I mean color, gradients, borders, etc.
I’ve presented this as a very strict way of working; in real life, of course, things are not as rigid. I’m not talking about “activate only” or “small screen only.” When I say to start with typography, I don’t mean that you aren’t allowed to think about paint at the same time. Rather, I’m trying to find the things that all of these different devices, with all of their different screen sizes and all of their different features, have in common. It just seems logical to first design this shared core thoroughly. The strange thing is that this core is often overlooked: Web professionals tend to view their own creations with top-of-the-line devices with up-to-date browsers. They see only the enhancements. The shared core with the basic experience is often invisible.

New Default: Content

The way we designed our websites until recently was by putting a header with the logo and navigation at the top, putting the subnavigation on the left, putting some widgets on the right, and putting the footer at the bottom. When all of that was done, we’d cram the content into the little space that was left in the middle. All of the things we created first — the navigation, the widgets, the footer — they all helped the visitor to leave the page. But the visitor probably wanted to be there! That was weird. It was as if we were not so confident in our own content and tried our best to come up with something else that our guests might like.
But rather than pollute the page with all kinds of links to get people out of there, we should really focus on that thing in the middle. Make sure it works. Make sure it looks good. Make sure it’s readable. Make sure people will understand it and find it useful. Perhaps even delight them with it!
Once you’re done with the content, you can start to ask yourself whether this content needs a header. Or a logo. Or subnavigation. Does it need navigation at all? And does it really need all of those widgets? The answer to that last question is “No.” I’ve never understood what those widgets are for. I have never seen a useful widget. I have never seen a widget that’s better than white space.
A typical news site with more attention for widgets versus the complete focus on the content on Medium.
Compare a typical news website’s attention to widgets with Medium’s complete focus on content.
By starting with the content first, you can come up with some very interesting solutions. For instance, does the logo really need to be at the top of every page? It could very well go in the footer on many websites; such as in digital style guides or on pages for registered users. Many links that we used to put in the subnavigation might work better in relevant spots in the main content.
For instance, the option to add extra luggage to a flight booking might be most effective right there in the overview of the flight, instead of in the middle of a list of links somewhere on the left of the page. And when looking at the hierarchy of a page, does the main navigation look more important than the main content? Most of the time it shouldn’t be, and I usually consider the navigation to be footer content. A simple “skip” link at the top of the page could either take the visitor to the navigation or fetch the navigation and show it at the top of the page.
In this era of responsive Web design, we need many new clever solutions. As we’ve seen here, our old defaults don’t work anymore. We need to reconsider how we work with interaction, how we approach design and how we shape our content. But we need to think about one other very important thing, and that is where our content comes from.

New Default: The API

Luke Wroblewski wrote a fantastic article about designing an application for the command line first, and then enhancing it for different needs. This is not just a nerdy idea, but a very practical idea, too. If you are able to design and develop your own application, you could test the functionality relatively easily before even starting to think about what it will look like on different devices. This requires designers to work with developers to design a feature that at first works only from the command line. If the feature does not work as expected, then you merely have to change the API, rather than also a bunch of visual designs. Once the API works as you want it to, enhancing it for all of the devices and screen sizes that you want to support becomes easier.
Most of the time, you wouldn’t design the entire API of the application that you’re building. Most companies would choose a content management system (CMS) of sorts or a specialized tool to help them achieve what they want to do. I’ve always been amazed that CMSes are so often chosen only by technical people and business people. This causes many problems during the design process.
Developers and business people have different goals than designers. Developers want stuff that is easy to develop on. Business people want stuff that’s cheap. But designers want to make the best and most beautiful things possible. These goals can easily conflict.
I’m not saying that designers alone should choose the system, but they should definitely be a part of the decision-making process. I’m convinced that the selection of CMSes will improve. And I’m convinced that CMS makers will start to improve their products once designers get involved. Right now, all CMSes I know of deliver hostile cruft unless you tweak them extensively.
But it works the other way around, too. If designers are involved in the selection process, they will have a say in the choice of tool and will understand how it works, what’s possible, what’s easy and what’s hard. This will result in designs that are based in part on the tool, not just on imagination. This is an important part of the design process that has not yet been optimized. Right now, the command line and the systems that deliver the content we design for are the domain of the developers, and designers have nothing to do with them. That is a pity. Just as you would want to take advantage of the knowledge of developers in the design process, you would want to take advantage of the knowledge of designers in the development process.

Progressive Enhancement

If you review the sections above, you’ll see that what I’ve described is nothing other than progressive enhancement. You start with the content, then design the content and optimize it for different screen sizes and devices, and after that you can further optimize for very specific features such as mouse usage and fat fingers. Many Web developers build websites according to this principle. They transform the beautiful Photoshop documents that they receive into all of the different layers described above.
This can work out fine if the developer has a good sense of design and a delicate attention to detail. But if they don’t — which is often the case — this can easily result in crappy usability and ugly details. I’m not saying that designers shouldn’t use Photoshop anymore. If that’s your tool, go ahead and use it. But do remember that you’re designing the layers of the Web, not the layers in Photoshop. There’s much more to the Web than a single beautiful image. People will see our creations in innumerable ways. We design for all of these people — remember that. We don’t just design for the CEO with a laptop. We also design for the people on the train and the people with “free hotel Wi-Fi.”

Tools

I’ve mentioned Photoshop a few times because it’s still widely misused for designing websites. One reason we have a hard time with progressive enhancement in the design process is due to a lack of good Web design tools. The tools we use are built to wow; they mostly help you to create the “paint,” not to design the core. Fortunately, more tools are popping up with very specific functions in the design process. These are micro-tools such as the International Measure Slider, which helps you to define breakpoints in your grid; tools such as Gridset, which helps you to create grids for different screen sizes; and excellent tools that help you to define typography. By incorporating these tools into our design workflow, we might start making better stuff.

Conclusion

The Web has always been a weird, borderless, flexible medium. In the last couple of years, we’ve started to realize that designing for this medium is fundamentally different from the design work we’ve done previously. The fixed dimensions and the singular ways of interacting that formed the basis of all types of media that we’ve worked with for centuries just don’t work on the Web. This truly is a unique medium.
We have to find new defaults, new starting points for our design process. I’ve explained some of these new defaults here, but of course there are many more. The way we work with forms, for instance, could probably use a whole series of articles by itself. Some new starting points are well established by now, but I’m sure many more will be invented in the near future. I am curious to hear about new patterns and new defaults that you have discovered and have used successfully in your projects.