Chapter 4. Selecting Responsive Design or Another Mobile Experience

The control which designers know in the print medium, and often desire in the web medium, is simply a function of the limitation of the printed page. We should embrace the fact that the web doesn’t have the same constraints, and design for this flexibility. But first, we must accept the ebb and flow of things.

— John Allsopp

One of the places where embracing uncertainty matters most and is most readily apparent to developers and designers is deciding how to handle the full depth of devices and screen resolutions out there. Users expect to be able get to your content and data with any device they’ve got in their hands. How you satisfy that multiscreen requirement is a major question facing any project these days. Balancing the desire for beautiful designs, world-class usability, top performance, and the maintainability of your platform are all factors that are going to come into play.

I stole the above quote. Well, I didn’t steal it so much as copy its use as the lead-in to some writing about responsive web design (RWD). It’s a few sentences that capture the very heart of the Web that I want—a flexible, universal medium. That sort of thinking embraces the Web in ways that I completely endorse. It’s also 14 years old.

So, where did I crib it from? It’s the quote that introduces the article that introduced RWD to the world.

That article appeared on May 25, 2010, when Ethan Marcotte published the directly named “Responsive Web Design” on A List Apart. In the article, he outlined the conceptual and technical framework of RWD, namely using fluid layout grids and CSS3 media queries to create layouts that could adapt and respond to the characteristics of the device or user agent—stretching and shrinking to present layouts that worked on a variety of screen sizes without prior knowledge of the device characteristics.

Around this time, projects like jQTouch, jQuery Mobile, and Sencha Touch were coming online and providing tools to produce mobile-specific sites. The ability to serve content for small screens with one codebase was an attractive alternative to creating a mobile site at m.example.com with a new, mobile-specific codebase.

The article made quite a stir. It was an elegant solution that leveraged just CSS, which made it accessible to the full frontend development spectrum—from hybrid designer/developers (with little or no JavaScript) all the way to full stack developers. People were rightly excited by the concept, as even at that point, the question of how to handle mobile devices was a hot topic.

As you’ll see in the next section, one year later, RWD’s place in the web development and design landscape was solidified beyond reproach.

In this chapter, I’ll share what I’ve learned about RWD over the past few years and will share lessons from the Web at large in order to give you the proper perspective to make the decisions on how to architect your site or application. It will focus on the place for responsive design techniques in the uncertain Web toolbox, examining use cases where it absolutely makes sense, where it doesn’t, and where you might have to flip a coin to decide which way to go. You will also learn some techniques to leverage on both sides of the responsive/mobile site divide.

Boston Globe’s RWD Redesign

When my local paper, The Boston Globe, relaunched its site BostonGlobe.com in September of 2011, it signaled the arrival of RWD as a viable technique for web design and development at the highest level. Up until that point, the excitement for the techniques hadn’t really been matched by a site that proved the effectiveness of RWD at scale. The site, designed with the help of the Filament Group and design agency Upstatement, was a polished, cleanly implemented site that worked well on everything from the desktop to a brand new iPad to an old Apple Newton, according to Mat Marquis.

In Figure 4-1, you can see the site in action. On the left, you see a desktop view. On the right, you see the small-screen view.

BostonGlobe.com in desktop and small-screen views
Figure 4-1. BostonGlobe.com in desktop and small-screen views

It made quite a splash. In web development circles, it was basically the only topic for a couple of days, and even several years later, the project remains a landmark, constantly referenced when the evolution of RWD is discussed. The folks involved have widely shared their experience and expertise in blog posts, conference talks, and interviews, further cementing the influence of the project. Even now, both the Filament Group and Upstatement still feature the project prominently on their sites.

Of course, it being a website (and therefore on the Web), everyone else also joined in the discussion, sharing their opinions of the technique, the specific implementation, and the visual design.

Really? RWD for Every Site?

One reaction in particular was actually the origin of this book. If you’re a comic book guy like me, you can imagine the bat that crashes through the window in the classic Batman origin story giving him the idea to “become a bat.” This was like that, except about websites and not at all scary (see Figure 4-2). On Twitter and in real life, people stated, without hesitation, that one day everything would be responsive.

A dramatic re-creation of the origin of this book
Figure 4-2. A dramatic re-creation of the origin of this book

Unless you jumped into this book starting from this chapter (if so, welcome!), then you know how skeptical I was toward the idea that one day everything would become responsive. Even then, I was wary of anything that seemed like a magical solution, and seeing several normally sober voices proclaim that responsive is “the one true way,” clarified something that had been floating around in my head for a decade—that there’s no “one true way.” There’s only the best way for the project you’re currently on. The next project might need the same tools or approach. It might not.

Which isn’t to say that I’m down on RWD in general. I’m not. I’m a fan of RWD and have built several sites, including three of my own, with it. RWD is a clever solution to a big problem, and because the core concept is so simple, it allows for lots of room to experiment. But, ask yourself, do you think there’s any one-size-fits-all solution? The reality is that nothing is a one-size-fits-all solution for the Web. The Web wasn’t built that way. For my part, even in 2011, I’d already done enough small-screen development to recognize situations where responsive techniques were going to fall short of the requirements I was looking to meet.

For a specific example, a project I was working on at the time used a force-directed layout to display the relationships between potentially many dozens of users. Even before we built it, it didn’t take a soothsayer to figure out that it was going to be difficult to interact with on a small screen. For one thing, at certain resolutions, even if the visualization scaled, the text was so small as to be a form of torture. Additionally, to accommodate dozens of elements on the screen, the nodes themselves had to be pretty small, so interacting with each node was going to be a problem for the user on smaller screen devices.

Figure 4-3 shows the difficulty of interacting with one of the nodes with a finger (and not a particularly fat one, if I do say so myself). This photo is taken on a large-screen phone, the Galaxy Note II, which measures 5.95 inches (151.1 mm) × 3.17 inches (80.5 mm). Even on the Note, the text is difficult to read in Portrait mode.

A comparison of the author’s thumb and a single node in a force-directed graph
Figure 4-3. A comparison of the author’s thumb and a single node in a force-directed graph

The years since the launch of The Boston Globe site have only cemented this opinion. Considering the amount of work I’ve done with data grids and on other complex applications, it’s been made clear to me that there’s a case to be made for completely different interfaces, depending on design goals, application requirements, and on the class of device the user is using. There are many situations where a dedicated mobile site or some hybrid approach is by far the best choice if you have the skills and resources to execute one. For example, financial sites might have widely different use cases for mobile and desktop users. With complicated financial data, mobile users are often solely consumers of data—often in the form of reports, simple approval workflows, or visualizations—and the real work is done on the desktop.

Mobile First, RESS, and the Rest of the Mobile Development Universe

Before we get deeper into the discussion of RWD, let’s take a minute to look at some of the other approaches in this space. As you’ll learn in this section, there are some other concepts in this space like responsive web design with server-side components (RESS) and “mobile first.” None of them really has the same footprint in developers’ minds that RWD does, so it’s worth discussing what they are and how they might play into this discussion. Techniques and concepts from all of these are going to fit well in the toolbox for developing modern, compatible sites—you want as many options as you can get. Whether or not you subscribe to the label is up to you.

Dedicated Mobile Experience

Initially, when mobile browsers were all terrible, and then later when there was only one mobile browser and form factor that mattered to people (the latest iOS Safari running on the latest iPhone), the most common “mobile” solution was to serve a separate experience optimized for mobile devices. This manifested itself as either something so dumbed down that it would run on anything that could access the Web, or something slick, yet designed to work only on the iPhone.

iphone.example.com

As an aside, the prevalence of iPhone-crafted sites created an unfortunate web development pattern. As people started to open up their mobile sites to work with Android (both browsers were based on WebKit, after all) and then general mobile browsers, they kept serving content from URLs like http://bookstore.umanitoba.ca/iPhone/iHome.aspx with iPhone clearly identified in the URL (not to mention the Apple style “iHome” in the filename). There’s no reason a website should expose a target platform in its URL structure.

This is accomplished with some sort of redirection based on the user agent. This can be a simple server or client-side test against the user agent string (“iPhone,” “iPad,” or “Android”), or a more complex query using a service like DeviceAtlas, or a Device Description Repository (DDR) like the Wireless Universal Resource FiLe (WURFL), or OpenDDR, which uses the user agent string and a dedicated database to return information about the device’s characteristics. Microsoft has even built this capability into its .Net MVC framework. The framework can do server-side device detection and then shows the best view based on what type of device it detects.

As you’ll soon see, a more nuanced approach to a dedicated mobile experience that is more flexible in layout (often leveraging RWD techniques) and doesn’t tie itself to any specific device is still very common, especially with the largest sites on the Internet.

Mobile First

Mobile first is exactly what the name implies, designing and developing the mobile experience first and then potentially working on enhancements for the desktop experience. This concept ties closely with the concept of progressive enhancement.

Mobile First is also the title of a book by Luke Wroblewski, one of the people you should be following if you’re interested in this conversation.

Progressive Enhancement

Progressive enhancement is an old stalwart of web development. The basic concept of progressive enhancement is to create a widely compatible baseline solution and then add on features and functionality, depending on available browser features. It differs from mobile first in that progressive enhancement can also be part of a desktop first approach to web development.

RESS

I’m not sure how well this acronym will catch on, but it does come up, so here it is. With REsponsive web design with ServerSide components (RESS), Luke Wroblewski (I told you he was someone to pay attention to) attempts to define a hybrid pattern that leverages the server side to render some elements of a single codebase, depending on the device class.

I don’t like the acronym personally, because to me it immediately evokes CSS preprocessors like Compass, SASS, and LESS rather than RWD. This isn’t a fatal flaw, I guess, but for me it just feels off, and I never took to using it. Also, where are the W, D, and C?

His advocacy of hybrid solutions is, however, a useful foil to the folks that seem to have a philosophical aversion to leveraging the server. To my mind, not taking advantage of the server in web development is silly, and he understands this completely. Purity in approach doesn’t win you points with your users. Giving them the best possible experience does.

Microsoft’s .Net MVC is geared toward using this type of approach.

Choosing a Development Path

So, if you’re not going to just make every site responsive, then what are you going to do instead?

You’re going to make the best possible decision for your project.

You’ve got options. The basic spectrum has a fully responsive site (with one codebase) that responds to the device’s capabilities on one end, and then dedicated mobile and desktop experiences with two separate, dedicated codebases on the other. Somewhere in the middle might be a RESS solution. Nothing on the Web is truly black and white. Your site can end up anywhere on that spectrum.

This section is going to focus on preparing you for the choice.

What you do is going to be decided on a few factors. The following sections outline some of the more common factors that will influence your decision.

The Size and Skills of Your Team

If you’re a lone developer who knows nothing about the server beyond installing WordPress or Drupal from a web host’s control panel, then you’re probably going to want to use responsive techniques. Unless you’ve always wanted to learn about PHP and Apache or C# and IIS, then you’re going to be much happier sticking to the tools you already know. On the other hand, if you’re a strong full stack developer or have a larger team with more specialization, then more options open up for you in terms of using the server. Take advantage of them.

The Requirements of Your Site or Application

As we’ve already started to explore, the nature of your site or application is going to be a major determining factor for your approach. On the one hand, if you are building a pure content (text and images) site (as many of the first wave of responsive sites were), then responsive is going to be a good fit. In addition to the existing body of knowledge you can tap into to get tips and tricks, pure text and images lend themselves to RWD because it’s easier to resize boxes than it is to rework interactions. On the other hand, if you’re building a more complicated application, then you may need to create an entirely different approach for small screens.

Your Demographics

As we discussed in Chapter 2, understanding your audience is key to knowing what to build.

For example, learning that your audience is increasingly visiting your site on small-screen mobile devices might mean you create a mobile-first design and then use RWD or progressive enhancement to enhance the experience of desktop or other large-screen users.

Alternatively, if you find you’re doing well with immersive desktop experiences, you may want to ramp up the experience on large screens and provide a mightily scaled-down version on a dedicated mobile site.

Your Budget

If you’ve got a budget, you’ve got even more options. I’m not talking about bringing in consultants or simply paying your own employees to solve more complex tasks. You can do that, but the more interesting benefit is that you can leverage solutions from software as a service (SAAS) providers, or content delivery specialists can make some thorny problems go away. Without endorsing any specific solution, a survey of some of these companies gives you a sense of what they’re offering. Akamai has a white paper entitled “How To Deliver Fast, Engaging Responsive Web Design Sites”, which, not coincidentally, includes a section entitled “Optimize Responsive Web Design Sites with Akamai.” Strangeloop Networks Mobile Optimizer product promises to “Accelerate your mobile Web performance by up to 350% automatically.” I can’t tell you whether or not these or any similar services are going to be good for your site or application. I can’t know what problems you’re trying to solve. What I can tell you is that when I’ve had the occasion to use services like these, I’ve had some success, and that these services are all pay to play. You have to have at least some money to get on board.

Now that you’ve got a sense of what the deciding factors are and what the general landscape looks like, it’s time to take a look at the drawbacks and benefits of the two ends of the spectrum, RWD and dedicated mobile experiences.

Benefits of RWD

The elevator pitch for RWD sounds like alchemy: take one codebase and handle every device and browser under the sun. With careful development, it actually does a pretty good job of delivering on that promise. The following list outlines some specific benefits of RWD.

Simplified server side

With a well-crafted responsive design, careful image usage, and an eye toward performance, you can serve one set of files with minimal server-side logic for device-specific issues to all your users.

Easier maintenance

RWD allows you to maintain one codebase for your entire frontend.

Lower overall application complexity

You can submarine this somewhat by getting too tricky on the frontend, trying to serve the perfect experience to too many users (instead of settling for a good solution that requires less effort), but overall, with a simpler server setup and one codebase for your frontend, you’re going to have fewer moving pieces and therefore fewer places where something can go wrong.

One entry point for search engines

If SEO is a thing you worry about, having a single site and set of URLs is easier to manage.

Support for future and unknown devices

By design, RWD ignores specific devices and OSes, so a properly crafted RWD site automatically provides support for current and future devices.

Downsides of RWD

There are some downsides to RWD. They might not be as readily apparent as the benefits, but they can have a detrimental effect on your site’s effectiveness.

Performance

Frontend performance on responsive sites can be a problem. For an example that I’m guilty of myself, loading 5-10 full articles on the home page of a blog might be OK on a fast broadband connection, but it’s a waste of bytes on a mobile network. Add in the typical desktop payload of JavaScript, CSS, and images (which has doubled on average since 2010, by the way) and performance can blow up in a big way. All the HTML, all of those images, all that JavaScript, and all that CSS will be downloaded on all platforms, whether they need it or not. Beyond content that might not be seen because it’s 50 screens down the page on a mobile device, you might have certain functionality for the desktop version of your site, an image carousel or tiled gallery, for example, that might be broken down to a stacked series of images with no interactions on a phone. But yet, you’re still serving all that JavaScript code that has no real benefit for a phone user.

Limited application flexibility

It’s possible to build an application that is both usable and responsive, but it’s also important to recognize that your users might have different needs on a phone versus their needs on a larger device. From my experience with financial services applications, the biggest need on mobile is to be able to view and interact with high-impact, focused events—either to respond to a problem with a specific transaction or to learn about some market event. On the desktop, the need is likely much more broad, offering access to an entire system, which in turn might be linked to other complicated systems. In financial services, the amount of information present on a single screen of a complicated application is overkill for a small screen. And that ignores the overall system complexity where a trader might be set up with three widescreen monitors plastered with data from multiple sources. You can’t interact with any of that data in any meaningful way on mobile unless it’s broken down into smaller, digestible chunks. Trying to shoehorn both of those needs into the same codebase and relying on media queries alone, or media queries and some JavaScript to sort it, isn’t going to serve your users well. This is especially true when you factor in the question of performance (a recurring theme with RWD).

Benefits of a Dedicated Mobile Experience

A dedicated mobile experience might not be the trendiest solution in web design circles right now, but providing a dedicated mobile experience has some serious benefits.

Performance optimized for specific devices

You can serve just the code you need for your mobile solution. That allows you to be as spare as you can be with the code that goes down the wire. The one exception to this is the demand, in the m.example.com pattern at least, to put in a redirect on the home page, which is going to cause a performance hit. That said, unless there’s a hamster driving the server you’re working on, these redirects are going to be measured in tens of milliseconds, which is still going to be faster than the download and parsing time of some of the images and JavaScript that would be needed for the desktop and ignored on mobile.

Heightened application flexibility

You’ve got a clean slate, so you can design a solution that works for your mobile-specific requirements without worrying about bytes (in the form of CSS, content, or images) that might be hitching a ride solely for the desktop.

Downsides of a Dedicated Mobile Experience

A dedicated mobile experience brings its own list of issues.

More complexity on the server side

With a dedicated mobile experience or even with a hybrid solution like RESS, once you step away from a pure RWD solution, you’re going to be adding complexity on the server side in the form of redirects, DNS, and site setup or server-side scripting code (in PHP, C#, Ruby, Python, etc.).

Tougher maintenance

Unless you’ve got a large organization with separate teams for desktop and mobile views, you’re going to have to manage more than one frontend codebase. If you’ve got a single pool of developers to maintain both codebases, it’s simply harder to make sure they can all move between the two codebases efficiently. You can mitigate this with solid code standards and development best practices, but it’s still something you have to manage.

Not as good for search engines

With multiple URLs, you’ve increased the complexity of your relationship with search engines. As you’ll see in the section on redirects, you can manage it; you just need to know that you need to do it and how to do it.

If there’s one thing I hate, it’s clicking on an article link on Twitter on my phone and getting redirected to the mobile front page of the target site. Don’t do that. If you do separate solutions, you need to make sure the bridge between the two is seamless. More on this later in the chapter.

You can miss detection of new and unknown devices

With the growing number of companies creating solid-to-great smartphones, there’s a real danger in missing out, for at least some time, on the opportunity to serve your best content to a new device that can readily handle it.

Detection schemes that use the user agent string can be spoofed

At the end of the day, the user agent string is a malleable property of the browser. Users and browser vendors can both monkey with the user agent string in ways that you might not be prepared for if you’re serving specific code for specific browsers and devices.

The User Agent String Can and Will Be Spoofed

There’s a long history of user agent strings being spoofed in order to fool detection schemes. Because of the early popularity of Netscape Navigator and browser sniffing that blocked really terrible versions of Internet Explorer, almost every browser (Opera being an exception) identifies itself as “Mozilla.” For a modern example, the Android browser, in addition to identifying itself as “Android,” also identifies itself as both “Safari” and “Chrome.”

That’s the generic take on this technology spectrum. Let’s take a quick look at some specifics.

If Facebook Jumped Off a Bridge, Would You Jump Off a Bridge, Too? Or: What Do the Biggest Sites in the United States Do?

So now that you know the fundamentals, let’s take a look at an interesting data set. For a slightly different perspective, Table 4-1 lists the top 10 sites in the United States, according to Alexa. I hit each of those with a Samsung Galaxy Note II or a Chrome with a spoofed iPhone 4 user agent string, typing in the main site URL and then recording the results. I wanted to see what sites with practically unlimited budgets do to solve these issues. The takeaway from this little experiment was that the largest sites on the Internet uniformly redirect to a mobile-optimized subdomain or serve a fully mobile-optimized site. The one slight exception was Wikipedia, which serves a single global gateway page, only to redirect to a mobile-optimized subdomain for article pages.

This survey, therefore, shows clear results that go against the trend you might expect if you follow the web development sites, blogs, and Twitter accounts where RWD remains a hot topic.

Table 4-1. How the Alexa Top 10 Handles a Mobile Device
Original domain Final domain Result

google.com

google.com

At first glance, it might appear to be the same site. It’s not. The downloaded source of the site generated when using a desktop device was 117KB on 2014-1-4. With a spoofed iPhone 4 user agent string, it was 10KB.

facebook.com

m.facebook.com

Mobile-optimized site

youtube.com

m.youtube.com

Mobile-optimized site

yahoo.com

m.yahoo.com

Mobile-optimized site

amazon.com

amazon.com

Mobile-optimized site. Same top-level domain (TLD), but a different path and markup than the desktop view.

ebay.com

m.ebay.com

Mobile-optimized site

wikipedia.org

wikipedia.org

Identical to desktop. Article pages are mobile-optimized, (e.g., http://en.m.wikipedia.org/wiki/Responsive_web_design).

linkedin.com

touch.www.linkedin.com

Mobile-optimized site

twitter.com

mobile.twitter.com

Mobile-optimized site

bing.com

www.bing.com

Mobile-optimized site. Same TLD, same path, but different source. Oddly, on January 4, 2014, the spoofed iPhone 4 user agent string generated a slightly larger HTML file (44KB versus 48KB)

So, although none of these sites are infallible, it’s instructive to see that people who can do anything are almost all choosing to do a dedicated mobile site. This doesn’t mean that you should do the same simply because that’s what the Facebooks of the world are doing, but it’s what they do, and we can learn from their decisions.

For a slightly different perspective, Table 4-2 shows the top 10 sites in the Alexa news category and how they handle a mobile device. There are more RWD techniques here, but it’s interesting (and also slightly confusing) to note that the best responsive site (from the BBC) performs a server redirect before serving a responsive site.

Even where the fit seems to be better, then, people with larger budgets are opting to do a dedicated mobile experience. There are two excellent examples of RWD here, one of which, The Guardian, is apparently going all in with RWD.

Table 4-2. How the Alexa top 10 news sites handle a mobile device
Original domain Final domain Result

news.yahoo.com

news.yahoo.com

Mobile-optimized site with RWD techniques. Shows different content based on the user agent. Different source. Desktop is 294KB. Mobile is 189KB.

huffingtonpost.com

m.huffpost.com/us/

Mobile-optimized site.

cnn.com

www.cnn.com

Mobile-optimized site.

reddit.com

reddit.com

Identical to desktop. The Reddit home page is somehwat fluid, so it “works” in different sizes. It breaks with very small screens. i.reddit.com exists, but isn’t automatically redirected.

bbc.co.uk/news

m.bbc.co.uk/news

Redirects to an excellent responsive site.

weather.com/

m.weather.com/

A slick mobile web app.

nytimes.com

mobile.nytimes.com

As of January 19, 2014, this is a mobile-optimized site, even though the Times just released a redesign.

news.google.com

news.google.com

Mobile-optimized site.

theguardian.com

theguardian.com

As of January 4, 2014, a responsive site which states proudly: “You’re viewing an alpha release of the Guardian’s responsive website.”

forbes.com

forbes.com

Mobile-optimized site.

Beyond this look at the very top, there was recently a survey that indicated that up to 1/8 of the top 10,000 sites were responsive. This list included sites like starbucks.com, harvard.edu, time.com, and worldwildlife.org. So, although the sites at the very top are going for a mobile-optimized solution, there are some very large, important sites going for the full RWD solutions.

Choose the Architecture That Makes Sense for Your Project

If there’s not a one-size-fits-all approach to this, then what are you supposed to do? How do you choose which direction to go? This section lists some common guidelines for making this decision. This is a spectrum, so think of these rough guidelines as notable points on the wavelength of the responsive versus mobile site spectrum. There’s not just blue and green. Teal is in there somewhere. Your solution might be the teal of web development.

Frontend developers and small teams

If you’re doing a content site or simple application and are a frontend developer on a small team or are a team of one and are more focused on frontend technologies, then you want to go with RWD. Properly implemented, a responsive site can provide a great experience for a vast number of users, and the entire experience can be controlled on the frontend.

Content sites

If you’re serving mostly text and image content, look to RWD, no matter what your skill set or team size. You can look to augment RWD with server-side solutions (particularly related to images and other media), but the techniques for responsive design are well established for this kind of content, so there’s no reason not to go in that direction. If you pay careful attention to image sizes and limit the JavaScript payload, in order to keep things speedy, you can provide a great content experience across devices.

Applications

If you’re building anything but the most basic application, look to doing a dedicated mobile experience. Form entry, visualizations, and interaction patterns might all benefit from optimization for large and small screens. You may be able to do a fully RWD application, but don’t force the technique into your application if it doesn’t make sense for your end users.

Big teams and big budgets

If you’ve got a large, skilled team, look for every opportunity to leverage the server. Whether that’s with a dedicated mobile experience, or a responsive site aided and abetted by the server, there are going to be many opportunities to pass work back to the server and save your users bytes, connections, and processing time in the browser. Personally, this is where I’m happiest. Yes, I’m a frontend engineer, but I’ve been very fortunate over the years to work with some excellent engineers working on the server side. I can’t count the number of times I’ve outlined a problem we typically have on the frontend, begun to talk through the potentially crazy lone-wolf approach (“Well, we could use JavaScript to…”), and been stopped by a super-smart backend engineer telling me, “No way dude, we can handle that edge-case and just serve you the good stuff.” I love that conversation. I don’t need to be the smartest guy in the room or do the most on the frontend just to prove that I can, so when someone comes up with a better solution that takes some of the heavy lifting off the client, I applaud that and get out of the way.

This is also what the biggest sites on the Web are doing, so you don’t have to take my word for it.

Again, this is a spectrum, so there’s no reason to do strictly one thing or the other. You need to take the options available to you, weigh them against the site or application you’re building, and make your decision based on that. As with anything that people are passionate about, people can get a little tribal when it comes to the polar ends of this discussion. Don’t fall in love with any solution, and you’ll be better for it. If you want to have a fully responsive solution but still use your CDN’s content negotiation to provide images optimized for the individual user agent, then go ahead and do that. You don’t win points for architectural purity. You win points with fast, effective sites that work in a wide range of devices. You want the best balance between compatibility, design, and functionality.

All that being said, I will urge you to always err on the side of your users when weighing the benefits of all of these approaches. You can’t always do the best thing for your users. I know this. I’m guilty of going for the easy solution on more than one occasion in order to just get something out the door. I’m also guilty of falling in love with development patterns without fully thinking through the effect on end users (or willfully ignoring it for convenience). With the goal of broad compatibility in mind, however, you need to guard against both of those impulses.

The rest of the chapter will look at some specific technical details and best practices related to redirects, device detection, responsive breakpoints, and server-side feature and capability detection. In addition to what’s found here, there are also responsive and mobile components covered in Chapters 5, 6, and 7.

Redirects Should Resolve Logically

If you have a dedicated mobile experience that mirrors one-to-one the content on your desktop site, and you automatically redirect based on browser characteristics, then you should ensure that the page the user redirects to contains the expected content. If you redirect the user to your mobile home page, you’ve completely failed.

If for some reason the content doesn’t exist in mobile form, don’t redirect. Serve them the expected content.

It’s hard to get people to click on links to your site. There are entire industries built around the art of getting people to follow links and read articles. (“Your Friend Clicked on a Link on Facebook, You’ll Never Believe What Happened Next.”) Celebrate the fact that the users are interested in what you’re doing. Don’t punish them for doing it on their phones.

The easiest way to deal with this is to just ensure that the path and associated content are identical on both the desktop domain and the mobile domain. For an example of this that’s clear to see, look at Table 4-3 to see the way Twitter handles URLs. This is a perfectly clean solution. They simple insert “mobile” as a subdomain, and everything else maps one-to-one.

Huffington Post also handles this well, although they handle it in a slightly different way (Table 4-4). On the desktop, the URLs contain search engine friendly keywords based on the title of the article and the article ID, a seven-digit string. On mobile, the URL only contains the seven digit article ID, creating a slightly shorter URL, which is both fewer bytes and easier to type on a mobile device.

Table 4-4. Huffington Post’s mobile and desktop URLs

They can get away with this duplicate content (two separate URLs serving the exact same content) on the search engine front by using a canonical link relation. Canonical links define a preferred URL for similar content, so it’s good to define one on your mobile site in order to ensure that the Googles and Bings of the world are looking at the correct page for search engine ranking.

Show ‘Em What You Got

If, for some reason, you can’t serve mobile-optimized content, then serve the desktop content. Your users clicked on a link expecting some sort of payoff. It might be a bummer to serve them a full desktop experience, but it’s much worse to confuse and frustrate them with a balmy redirect.

The canonical relation is straightforward syntax-wise. As the following snippet pulled from my blog shows, it’s just the relation attribute with a property of “canonical” and then the URL of the resources that should be treated as the resource of record:

<link rel="canonical"
href="http://htmlcssjavascript.com/web/it-well-do-it-live/">

How to accomplish the redirect itself is a two-part effort. First, you need to understand how to do the redirect, and then you need to serve different content. I won’t try to show you how to serve separate templates because there are many platforms and technologies you could be using and a lesson for one might not be at all useful for another. I will, however, talk about how to do the redirect.

Redirect Options

As I mentioned, there are a few different ways you can do this redirect: a simple redirect (mobile or not mobile), or one based on device characteristics using a web service or Device Description Repository (DDR).

Simple Redirection

The basic pattern for a simple redirect is illustrated in the following code samples. In these, you’ll do a simple redirect based on the user agent string. It’s a simple redirect, in that it’s either a mobile user agent or it’s not, and it redirects (or doesn’t) accordingly. The regular expression is from detectmobilebrowsers.com, an open source project that parses major (and not so major) mobile user agent strings to create a pretty comprehensive regular expression to detect a mobile device. There are versions for pretty much every programming language. This example is in JavaScript, which is as close to a lingua franca as the Web has today, but the logic will be the same, no matter what language you’re using on the server side.

There are two things happening. First, you set a click event handler to manually move the user over to the mobile site. It uses window.sessionStorage to set a flag indicating the user’s choice of the mobile site. Following that is the redirect code. It starts with an if…else block, which is where our tests are executed. The first case tests against the sessionStorage variable to quickly short circuit further logic if there’s a match. If there’s no match, we go into an else block where there are two variables, primaryMobileRegex and secondaryMobileRegex, which represent two different regular expressions. The first regular expression tests for the most obvious and most popular mobile devices in the hope that these likelier use cases will resolve true without having to evaluate the much larger secondary test. The second, larger test offers broader coverage, but only if the first test fails. If there’s no value in sessionStorage, then you test against the regular expressions, redirecting to the mobile option that either of them are matching.

Also, notice the link element with the “alternate” rel attribute and associated media query. This is a hint indicating the presence of mobile-optimized content. Coupling this pattern with a rel="canonical" link element is the full pattern preferred by Google when creating an alternate mobile experience:

<!DOCTYPE html>
<html class="no-js">
  <head>
    <title>Mobile Detection</title>
    <link rel="alternate"
      media="only screen and (max-width: 640px)"
      href="ch04-02-mobile.html" >
  </head>
  <body>
    <h1>Desktop!</h1>
    <p><a href="ch04-02-mobile.html"
          id="switch">Go to the mobile version</a>
    </p>
    <script>
      document.getElementById( "switch" ).addEventListener(
      "click" ,
      function(){
        sessionStorage.setItem( "view" , "mobile" );
        window.location = this.href;
      });
      (function( UAString,url ){
        if ( sessionStorage.getItem( "view" ) == "desktop") {
          return
        } else if ( sessionStorage.getItem( "view" )
                    == "mobile" ) {
          window.location=url;
        } else {
        var primaryMobileRegex = /(android|bb\d+|meego).
          +mobile|avantgo|bada\/
          |blackberry|blazer|compal|elaine|fennec|hiptop|
          iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|
          mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)
          ?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|
          symbian|treo|up\.(browser|link)|vodafone|wap|windows
          (ce|phone)|xda|xiino/i;
        var secondaryMobileRegex = /1207|6310|6590|3gso|4thp|
          50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|
          al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te
          |us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)
          |bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm
          \-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)
          |dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49
          |ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc
          |fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad
          |un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp(i|ip)|hs
          \-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)
          |i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|
          iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|
          kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-
          [a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01
          |21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|
          de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|
          n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|
          on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1
          |p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl
          (ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07
          |12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro
          (ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)
          |sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)
          |sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h
          \-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)
          |tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-
          |m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg
          |te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61
          |70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)
          |wmlb|wonu|x700|yas\-|your|zeto|zte\
          -/i;
          if( primaryMobileRegex.test( UAString ) ||
            secondaryMobileRegex.test( UAString.substr( 0,4 ))){
              window.location=url;
          }
        }
      })( navigator.userAgent ||
       navigator.vendor ||
       window.opera,'ch04-02-mobile.html' );
    </script>
  </body>
</html>

In case you’re curious, the argument to the detection function is built up by testing three possible variations on the user agent string or equivalent. navigator.userAgent is by far the most common. So common, in fact, I don’t even know the specific situations where navigator.userAgent would fail and fall back to navigator.vendor or the Opera specific window.opera. All I know is they’re there for whatever arcane situations demand them, and that’s good enough for me.

The mobile landing page is simpler. All it has is a click event handler set on the link to return to the desktop experience, setting a “desktop” flag with sessionStorage.setItem:

<!DOCTYPE html>
<html class="no-js">
  <head>
    <title>Mobile Landing Device</title>
  <link rel="canonical" href="ch04-02.html" >
  </head>
  <body>
    <h1>You've Got a Mobile Device</h1>
    <p><a href="ch04-02.html"
          id="switch">Go to the desktop version</a>
    </p>
    <script>
      document.getElementById( "switch" )
        .addEventListener( "click" ,
          function(){
            sessionStorage.setItem( "view" , "desktop" );
            window.location = this.href;
      });
    </script>
  </body>
</html>

Web Storage

If you’re not familiar with the web storage specification and want to use it, keep in mind that sessionStorage only lasts for the current session. If you want to save user preference for a longer time in the browser, you can use localStorage, which is for longer-term storage. It has the same API as sessionStorage. It just lasts longer.

If you’re using these, you should take a look at the web storage polyfills on the Modernizr site.

You could alternatively just use cookies for this. This would be especially helpful if you’re doing a server-side redirect because the server would have the same access to cookies that the browser would. I prefer the web storage interface, but the ability to share state easily across the browser and server is valuable.

Options for More Complicated Queries

If you want to do more complicated queries based on deeper device characteristics, there are a few options, none of which are perfect. There are some cloud-based solutions like DeviceAtlas that are going to be easier to implement, but come at a cost. On the other end, there’s the OpenDDR project, which is free and open source, but isn’t nearly as easy to use as a cloud-based solution (especially if you’re not using C# or Java, the two sample implementations that ship with the project).

That said, if you’ve got the money for a paid service, or the time and the patience for the OpenDDR project, they are useful because they allow you to query for device characteristics (much in the way media queries work) and not just query against the user agent string. A sample of the data available in the OpenDDR can be seen in the following XML snippet. It shows the information recorded on the Samsung Galaxy S4. As you can see, it gives information about both the physical characteristics (screen size, touchscreen), software (browser and OS) and browser capabilities, including core JavaScript capabilities and the ability to inline images (a common performance technique):

<device id="SPH-L720" parentId="genericSamsung">
  <property name="model" value="SPH-L720"/>
  <property name="marketing_name" value="Galaxy S4"/>
  <property name="displayWidth" value="1080"/>
  <property name="displayHeight" value="1920"/>
  <property name="mobile_browser" value="Android WebKit"/>
  <property name="mobile_browser_version" value="4.0"/>
  <property name="device_os" value="Android"/>
  <property name="device_os_version" value="4.2.2"/>
  <property name="inputDevices" value="touchscreen"/>
  <property name="dual_orientation" value="true"/>
  <property name="ajax_support_javascript" value="true"/>
  <property name="ajax_support_getelementbyid" value="true"/>
  <property name="ajax_support_inner_html" value="true"/>
  <property name="ajax_manipulate_dom" value="true"/>
  <property name="ajax_manipulate_css" value="true"/>
  <property name="ajax_support_events" value="true"/>
  <property name="ajax_support_event_listener" value="true"/>
  <property name="image_inlining" value="true"/>
  <property name="from" value="oddr"/>
</device>

For my money (or, more often, my client’s money), I think the simple redirect is going to be good enough when coupled with responsive techniques—with one exception. Getting access to the device pixels per inch from services like DeviceAtlas when working with an image-heavy site, and the task of being able to properly load images to match the device capabilities would be useful. There are browser-based solutions to this issue, which you’ll learn about in Chapter 6, but this is great information to have.

Always Offer an Escape from the Mobile Version

As I previously described, I hate being on a mobile device and being redirected to the mobile home page of the site instead of content specified in the navigated link. One way that this can be somewhat mitigated is by offering easy access to the full site via a link or button on the home page. If I can get to the desktop site, I can usually find the content one way or another (browse or search, if it’s not content directly on the home page). If I’m redirected to the home page, and there’s no easy way to request the desktop site, then that’s just about the worst thing possible.

The Trifecta of Mobile User Antagonism

Actually, redirecting to the home page, adding an interstitial imploring me to download an Android or iOS app when I get there, and not offering a link to the desktop site would be the worst thing possible.

Alternatively, if you have an application with a dedicated mobile experience that handles the most common use cases, keep in mind the occasional emergency where someone on his phone might need to access a feature only available on the desktop, even if it means working through a desktop interface with fat fingers.

So, if you have a dedicated mobile experience, you need to offer a way to cross over to the desktop version. You’ve already seen this in action in the previous section. But from a design perspective, a simple link, like this one provided by the BBC (Figure 4-4) is probably sufficient. Just make sure it’s clearly labeled.

Make It Count

Even though you’ve already seen this in the previous example, it’s worth stressing—you must ensure that, once a user crosses over to the desktop site, you keep her on the desktop site. Whatever redirection scheme you use must be able to be overridden by the user’s actions for the length of her session. If she chooses the desktop site, don’t randomly redirect her back to the mobile site halfway through her site journey.

Additionally, offer the ability to move back to the mobile site via an equivalent link. Especially in the case of an application with different feature sets on mobile and desktop, the ability to cross back and forth is vital.

Switching from mobile to the desktop on the BBC site
Figure 4-4. Switching from mobile to the desktop on the BBC site

An excellent example of how to handle this hybrid approach, providing an optimized mobile experience where possible and seamlessly falling back to the desktop experience where it’s not, can be seen with the mobile site from Heritage Auctions, “the world’s third largest auctioneer” (Figure 4-5). The majority of the common tasks, such as searching for and browsing auction items, are served through a dedicated mobile interface. Less common tasks (in this case, working with their want list feature) are passed back to the desktop display.

Creating a want list with Heritage Auctions
Figure 4-5. Creating a want list with Heritage Auctions

It might not be perfect, as in this case where landscape mode was required, but you’re always assured of getting the task done.

Be Fluid and Design for Your Design

If you look at many responsive sites, you will see breakpoints set to “standard” measurements (320px, 480px, 768px, 1024px, 1280px). These are all defined around typical CSS pixel sizes for popular devices: iPhones (portrait and landscape), iPads (portrait and landscape), and large-screen desktops. This is OK, but you could potentially save yourself some time and proof yourself against unknown devices by making decisions based on the requirements of your particular site. You can let the design itself dictate the breakpoints. For a simplified example, if you’re publishing a typical blog with two columns (one large for articles and one smaller for ads and sidebar links), and you have fluid grids that take up a percentage of the screen, then you may have just one major breakpoint for the entire site. This might be the point where the sidebar disappears altogether or floats below the main content. Although that breakpoint might be the width of an iPad in portrait mode (768 pixels), it might not be. With this concept, coupled with the use of relative units and the max-width and min-width CSS properties to keep things from going crazy, you should be all set with the majority of screen sizes, known and unknown.

This simplified example shows a sketch of how this might look. The HTML is straightforward. Although it uses all HTML5 sectioning elements (<header>, <main>, article, <aside>, and <footer>) and assigns WAI-ARIA roles to them, if you swapped out the tag names for ids (<div id="header">), then this markup would look like a typical blog layout from 10 years ago:

<!DOCTYPE html>
<html class="no-js">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,
        initial-scale=1">
    <link href="responsive.css" rel="stylesheet"
      type="text/css">
    <script
      src="../_assets/js/vendor/modernizr-2.6.3.min.js">
    </script>
  </head>
  <body>
    <div class="container">
      <header role="banner">
        <h1>Responsive Header!</h1>
      </header>
      <main id="content" class="group" role="main">
        <article>
          <h1>Syndication</h1>
          <p>Eu actually fugiat flexitarian Odd Future single
          origin coffee. Next level ugh actually pour-over,
          farm-to-table artisan McSweeney's magna polaroid tofu.
          Locavore dreamcatcher Shoreditch skateboard. Tumblr
          placeat commodo, Marfa DIY typewriter master cleanse
          tote bag food truck Neutra Austin mumblecore
          accusamus. Est ennui drinking vinegar
          </p>
        </article>
        <aside>
          <a href="http://hipsteripsum.me/">Text generated with
          Hipster Ipsum. Which is so old it's now ironic.</a>
        </aside>
     </main>
     <footer role="contentinfo"><small>How are you?</small>
    </footer>
    </div>
  </body>
</html>

The CSS is where the magic happens. In this example, the containing div is set to 100% of the body, with a max-width of 75ems, which maps to 1200px at a default font size of 16px. There’s more on the use of ems in the next section, On Relative Units. The main element is set to use the new flexbox (“flexible box”) display mode with its corresponding flex-direction property set to row. This combination ensures that the article and aside will fit side by side in a row, with each filling the available space. In practice, you would add this test to your Modernizr build and use the Modernizr.flexbox Boolean or the .flexbox class on the html element to provide fallbacks for browsers that don’t yet support flexbox. Here I’m just assuming you’ve got a newer web browser in order to run this demo.

The header element has a background image set to have a background-size of 100%. This ensures that the background will scale as the page size increases or decreases.

Following that, there’s a single media query set at 40em (640px at the standard default font size) that changes the flex-direction property to column, which pushes the article and aside elements into a single column, better suited to smaller screens. It also swaps out the large header image for one that works better at smaller resolutions:

@charset "utf-8";
.container {
  margin: auto;
  width: 100%;
  max-width: 80em;
}
main {
  display: flex;
  flex-direction: row;
}
article {
  border: 1px solid #06C;
  width: 70%;
  padding: 1em;
}
aside {
  border: 1px solid #060;
  width: 30%;
  padding: 1em;
}
header h1 {
  line-height: 2em;
  margin: 0;
  text-shadow: 1px 1px 3px #888;
}
header {
  padding: .2em 1em;
  background-image: url(responsive-header.jpg);
  background-size: 100%;
  background-repeat: no-repeat;
  background-color: #2492b4;
  height: 32.1875em;
  color: #fff;
  background-position: top;
}

/*
Major breakpoint
*/
@media all and (max-width: 40em) {
  main {
    flex-direction: column;
  }
  article {
    width: 100%;
  }
  aside {
    width: 100%;
  }
  header {
    border: 1px solid #000;
    text-align: center;
    background-color: #0d9c2b;
  }
}

Although you could stop there and have a perfectly usable site, you can add some small touches to the CSS that will improve the layout across the device spectrum without too much effort. To do that, you can tweak the design of the header element using minor breakpoints.

Feel Free to Abuse Minor Breakpoints

The following CSS sample shows how this can be accomplished. For starters, in the first four zones, you’ll adjust the height of the header to better match the shrinking width of the header image better. At the smaller sizes, the background image itself is swapped out for one more suited to a vertical layout.

With all of these, I started with standard dimensions, but tweaked as necessary, depending on the way it looked. So although you will see certain em measurements that match common dimensions, there are others that are chosen simply because the design needed a tweak at that level. Based on a default 16-pixel font size, 46 ems equals 736 pixels, and 32 ems equals 512 pixels:

/*
Minor breakpoints
*/
@media all and (min-width: 64em) and (max-width: 72em) {
  header {
    height: 30em;
  }
}

@media all and (min-width: 46em) and (max-width: 64em) {
  header {
    height: 24em;
  }
}

@media all and (min-width: 40em) and (max-width: 46em) {
  header {
    height: 18em;
  }
}

@media all and (min-width: 32em) and (max-width: 40em) {
  header {
    background-image: url(responsive-header-thin.jpg);
    height: 42em;
    background-position: center;
    padding: .1em .5em;
  }
}

@media all and (max-width: 32em) {
  header {
    background-image: url(responsive-header-super-thin.jpg);
    height: 24em;
    background-size: auto;
    padding: .1em .2em;
    background-position: bottom;
  }
  header h1 {
    font-size: 1em;
  }
}

Using Brad Frost’s fun, if scary, tool ish, you can see that the layout flows and functions pretty well across a wide range of resolutions, not just popular device widths (Figure 4-6).

The output from Brad Frost’s ish
Figure 4-6. The output from Brad Frost’s ish

This is a simplified example, but recognizing that you don’t have to go all-in at popular device widths and instead can work within the confines of your design is important. Your design and the requirements of your site should be the driving factors of the breakpoints you choose.

On Relative Units

Relative units are your friends. ems, which you probably already know about, as well as rems, vhs, and vws are all going to help you create fluid solutions. If you’re not familiar, here’s a quick summary:

em
An em is equivalent to the height of the current font. They were very popular for a brief period for all measurements on a page when the default “text increase” behavior in browsers was to simply increase the size of the text without adjusting the size of the boxes. This em-based measurement system was great as it made for layouts that would smoothly increase when the text was increased. There were certain difficulties in this approach because of the fact that the em measurement can change, depending on the size of the font in that section of the document, but they weren’t insurmountable. When the default behavior changed to zooming the entire page, they fell out of favor once again, and pixels reigned supreme. The pendulum has begun to swing back toward ems, as they can bring some benefit in responsive designs. Setting breakpoints in ems, for example, allows a zoomed-in interface to react to breakpoints even when the underlying pixel measurements haven’t changed.
rem
A rem is a “root em,” the em value of the font defined on the root element. This brings all of the benefit of using ems without the complexity that changing font sizes can bring.
vh
A vh is equal to 1% of the viewport height.
vw
A vw is equal to 1% of the viewport width. These units allow for viewport relative layouts. If the viewport changes (say in the change from portrait to landscape on a tablet), these units will scale proportionally.

Because of the use of relative units, rems, the breakpoints in the previous example are triggered, even though the underlying screen size (in this case, 1600 pixels) never changes (Figure 4-7).

Showing breakpoints triggered when the page is zoomed
Figure 4-7. Showing breakpoints triggered when the page is zoomed

There’s more to these techniques than is presented here, of course, and the implementation details will change based on your specific needs. That said, the idea of being as fluid as you can be with your layout, of letting the design dictate your breakpoints, and for using minor breakpoints to fine-tune your layout, if needed, are all going to serve you well going forward.

“Accepting the Ebb and Flow of Things”

With an open mind and a full toolbox of techniques, your options for managing the full device spectrum are about as limitless as the number of devices. By taking advantage of the server where possible and focusing on the needs of your application throughout the design process, you can provide a solid experience for everyone hitting your site, no matter what the size or shape of the device they’re carrying.

Get The Uncertain Web now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.