Let’s get started with responsive web design.
No web developer today should be unfamiliar with the concept of responsive web design (RWD). Since the term was coined by Ethan Marcotte in May of 2010, the concept has been accepted as a best practice, the process has matured, and multiple options and implementations have emerged.
This has helped us refit the web for the devices that our users have today, and positioned it to work just fine no matter what new devices are dreamt up in the future.
However, as hugely successful as RWD has proven to be, it is not without its shortcomings.
Responsive imagery has proven to be one of the more complicated challenges to overcome, though we are finally getting closer to resolving this challenge with native browser implementations of srcset and the picture element.
The video and audio tags solve their media-specific problems by providing for multiple source elements and letting the browsers pick the one it likes best. However, this does come with the price of a lot of extraneous mark-up — even at the times when we know that only one source element is ever going to be used on a given device.
Both of these issues are part of a far larger challenge — the challenge of content and context. The mobile context is a world of potential limitations — including bandwidth, screen-sizes and CPU power. Irrespective of the device your user is using, as developers we should always be endeavouring to send them only the assets that they actually use.
Clearly for each of these examples outlines above, we are sending everything that they might need, and then letting the browser sort it out.
Beyond these large issues, we also have smaller issues like device capabilities, which we have mostly used JavaScript to solve on the front-end, after the entire page has been downloaded. But this puts even more onus on JavaScript, piles on more code for the user to download, and often causes at least some unsettling repaint as the solution is applied to the page.
What is Adaptive Web Design?
This all leads us to what I believe is the next growth phase in web development: Adaptive Web Design (AWD).
This concept has sometimes been called RESS, but regardless of labels, it involves making decisions on the server that determine what should and shouldn’t be sent to the user, so that nothing is sent that will not be used.
A few of the benefits of AWD are:
- Reduced bandwidth – Because you can send something like this for each video on your site:
1 <video src="…"></video>
..instead of something like this:
1 <video> 2 <source src="...mp4" type="video/mp4"> 3 <source src="...webm" type="video/webm"> 4 <object type="application/x-shockwave-flash" data="...swf"> 5 <param name="allowfullscreen" value="true"> 6 <param name="allowscriptaccess" value="always"> 7 <param name="flashvars" value="file=...mp4"> 8 <!--[if IE]><![endif]--> 9 <p>Your browser can't play HTML5 video. <a href="...webm"> Download it</a> instead.</p> 10 </object> 11 </video>
- Context-aware modules – So you can send the “Call Us” module only to call-capable devices, the “Camera” module only to devices with cameras, etc.
- Server speed for rendering – Servers are typically still quite a bit faster than any front-end device, so why not let the server do the hard work, and simply deliver the render-ready content to the device.
- Caching modules on server – And once that hard work is done on the server, cache it there so it doesn’t need to be re-processed for each page load?
- Faster page loads – By building and caching these modules on the server and delivering them with the rest of the page, you avoid the delay and additional HTTP Request that would be required if JavaScript had to determine what is needed and then request it via Ajax.
- Choice of programming language – If it’s in the browser, it’s JavaScript. Your server, however, can use anything, as long as it outputs something the browser can render.
Of course, the concept of device detection is nothing new. It has been happening since the very early days of mobile (typically to redirect the user to a completely different site and/or URL), and it goes back even further, back to the bad old days, where JavaScript was used to browser sniff User-Agent strings to decide how our spaghetti-code would function.
We later learned that feature-detection was a more reliable and scalable approach, but this requires access to the browser, which means it has to happen on the front-end.
So, how can a server identify which device is making the request?
Ironically, we revert back to User-Agent sniffing — but from the server this time — and look at the User-Agent string that comes with the initial request header.
It would look something like this in Chrome’s DevTools:
The AWD server code would look at this, compare it with values in a database, and return information regarding this device.
Easy, right?
Except for that little “values in a database” part…
Note that there is nothing in that User-Agent string that explicitly says “desktop” or anything else even remotely that obvious.
This means that human action is required, in the form of collecting and categorizing User-Agent strings and their correlating device categories. Which is why anyone that follows this path will more than likely want to use some form of service that does all that collection and correlation work for them (more about that shortly).
This seems like a good time to mention a few of the weaknesses of AWD:
- Detection library maintenance – The moment a device detection library is updated, it is out of date, because new devices, and new browsers, and new browser versions, are being launched every day, seemingly every nanosecond…
- Possible delays during server detection – Depending on how your device detection library works, it might cause a slight delay as the server determines your device and begins rendering your pages.
- “Different site” on different devices – Some users could find it unsettling to find some site module or content when viewing on one device, but then can’t find that component on some other device (although this might be avoided by always offering a link to any varying versions of your sites).
So AWD is not necessary for all sites. If your site does not need all this varying content for varying contexts, or doesn’t use a lot of images, or audio, or video, you may be able to get by with just RWD.
And that would be great!
Any well-designed and well-constructed fluid website should work properly across any screen size, and as long as you aren’t clogging the tubes with redundant code to make things work properly, then your users should love you, and will hopefully love surfing your site.
Still here?
If you’re still reading this, then you’re probably still interested. Good. Then let’s get down to business!
Full disclosure is pertinent here, because I work for Netbiscuits, and they do offer a device detection service. However, there are several options out there, and they all differ in what they offer and what they cost, so it is up to you to do a little homework and decide which service or product best fills your needs and your budget.
Regardless of the solution you choose, you will eventually end-up with something like this in your server templates:
1 if (device.type === 'mobile phone') { 2 // insert a module that will only go to mobile phones 3 } else if (device.type === 'tablet') { 4 // insert a module that will only go to tablets 5 } else { 6 // insert a module that will go to all other devices 7 }
Or:
1 if (device.video.format === 'mp4') { 2 // this device supports "mp4" so only send a <video> tag for that codec 3 echo '</video><video src="...mp4" type="video/mp4"></video>'; 4 } else if (device.video.format === 'webm') { 5 // this device does not support "mp4", but does support "webm", so only send a <video> tag for that codec 6 echo '</video<<video src="...webm" type="video/webm"></video>'; 7 }else if (device.video.format === 'swf') { 8 // this device does not support either of the above, but does support "swf", so only send that code 9 echo '<object type="application/x-shockwave-flash" data="...swf">'; 10 echo ' <param name="allowfullscreen" value="true"/>'; 11 echo ' <param name="allowscriptaccess" value="always"/>'; 12 echo ' <param name="flashvars" value="file=...mp4"/>'; 13 echo ' <!--[if IE]><param name="movie" value="...swf"/>< ![endif]--> '; 14 echo '</object>'; 15 } else { 16 // this device is pretty weak, so send the user a link and let them fend for themselves… 17 echo '<p>Your browser can't video. <a href="...webm">Download it</a> instead.</p>'; 18| }
The power you gain and savings you provide to your users depends solely on the service you choose to use and how greatly you take advantage of it.
On the Netbiscuits website, for example, we use our Device Detection service to choose which CSS file we send to the user, which dictates, among other things, whether icons are served as SVG data-URIs, PNG data-URIs, PNG URLs, or PNG URLs served via an IE-only filter to allow for transparency.
We also have access to the device OS, OS version, browser name, and browser version, all planted as data-attributes to the html tag, so we can add device-specific CSS for those pesky devices that just don’t want to behave.
Here are two examples:
And since these values are planted at the server, before anything is delivered to the device, there is no jarring visual experience or repaint required when the correct values are determined by JavaScript on the front-end.
So, whether you need an adaptive web design solution now, or you can make do with just a responsive web design site, hopefully you have a better understanding of AWD and the possibilities that are out there for you and your users.
I’ll be looking at both concepts in more detail in my future blogs and it would be great to hear any questions or ideas you would like me to cover.
Aaron T. Grogg
Aaron has been developing for the web since 1998, starting with simple HTML pages before moving on to full database-driven, interactive sites. While he now focuses mainly on front-end development for the entire web, he still dabbles regularly with WordPress, PHP and MySQL.