Context-aware design - The Responsive Web (2015)

The Responsive Web (2015)

Appendix A. Context-aware design

This appendix covers

· Introducing context awareness in web design

· Level-four media queries

· Using JavaScript for context awareness

This book provides an introduction to the concept of responsive web design. Hopefully after reading it you’ll understand how to design and develop responsive websites. As has been mentioned, responsive web design means providing your users with a layout that adapts to their needs. Responsive web design illustrates a primitive form of context-aware computing.

What if, instead of resizing the design to adapt to the user’s device, you could also format parts of the site based on factors like location, time of day, the user’s history on the site, or the user’s activity level. Theoretically, all of this data is accessible to the design of a page and could be used to greatly enhance the user’s experience.

By implementing some forms of context awareness in websites, you could streamline the interface options. For example, you could use context awareness to make assumptions about why a visitor is visiting the page, such as for a user who often visits a site for specific reasons. Perhaps you run a site that provides weather information. In this case, knowing the user’s location would give you the opportunity to serve them the weather in their area.

I recently discussed this topic with a colleague who runs a website for a creamery. He told me that he used IP address and time of day to serve content that was immediately relevant to the user. If it was spring or summer, the website would promote ice cream. If you were on an IP address close to the creamery itself, it would show you how close the creamery is.

While this practice holds a lot of potential for web design, context awareness has long been a practice in native application development.

A.1. Context awareness in applications

In native apps, specifically in mobile devices, context awareness is common. When the iPhone first launched, it solved a common problem in smartphone use through a little insight into context awareness. Prior to the iPhone, smartphones suffered from not knowing how a user was using the phone. If you had the phone to your head, sometimes the screen would remain on. This was solved by the inclusion of a proximity sensor in the iPhone, which would disable the screen as you raised it to your face. With this minor element of context awareness, the utility and battery life of the phone was greatly increased.

In apps like Yelp and Foursquare, where geographic location can play an important part in what the application does, context awareness is fundamental to how the app works. In iOS development the Core Location framework gives the application locational awareness to native applications. By using location data, applications can automatically serve location-specific content. In the case of apps like Yelp, this data can be the locations of nearby restaurants or shops.

In addition to offering GPS-based location management in iOS, the iPhone 5S introduced a new co-processor, the M7. The M7 offers iOS applications the ability to track motion-related activity by combining information from the accelerometer, gyroscope, and compass. This information is available through the Core Motion framework. In an iOS 7 application, developers can access whether the user is standing still, walking, running, or driving. By giving developers access to the user’s activity, a design can prioritize around that activity.

By accessing the user’s active state, you can augment the UI to make buttons and images bigger if the user is walking, or to disable distracting features while the user is driving. A walking user might not be able to focus as closely as when they are still, so it might be in your application’s best interests to increase the size of interface elements. If the user is sitting still, the user will be able to interact more precisely, so the user interface could have smaller interface elements, allowing more room for varied content.

In the near future, as wearable technology increases in popularity, it’s not hard to imagine an application using a more detailed set of sensors and levels of contextual interaction. Say, for example, that a user is wearing a device that features a heart-rate monitor. If the user has an elevated heart rate, an application could route incoming unimportant phone calls directly to voicemail until the operating system observes the user’s pulse returning to normal.

While context awareness might be helpful in application development, what about its utility on the web? In design, we often develop based on strict guidelines, serving a single design for all of our visitors. In simple brochure sites, or web apps with a single use, this approach might work just fine, but sometimes there’s a huge benefit to using varied content in contextually relevant ways. What if you could expand the context awareness of responsive design and its principles into an awareness of where a user is and what they’re doing?

A.2. Context awareness on the web

Web designers and developers might not have access to something as powerful as Apple’s M7 co-processor in the browser, but there are things a developer can to do improve a user’s experience based on contextual factors, such as time of day or geographic location.

One of the best examples I can think of is a website promoting beverages. The beverages people drink might change dramatically through the day. For example, in the morning you might want to promote a cup of coffee with a banner on your page, as in figure A.1.

Figure A.1. A banner advertising hot coffee, an ideal morning beverage

On a page, you need an h1 tag and some CSS to style it (this code can be found in the source code directory for appendix A, in folder A1.1):

This morning banner is great for anyone visiting your website in the early morning, but if you’re anything like me, having a cup of coffee in the evening is a terrible idea. What if your shop sells beer? That might be the perfect drink to end a long day of grinding code, so after 6 pm you could recommend a nice cold beer. For anyone visiting between those times, you could offer something more generic, like a diet soda.

In order to do this, you need to follow a few steps. First you need to access what time it is for the user of the site, and then set a few contextual breakpoints. Much like breakpoints in responsive web design, contextual breakpoints are identified points at which augmenting a site’s design makes sense. While responsive design deals strictly with site layout and screen width, contextual breakpoints could involve any factor that might change how a person uses part of a site.

A.2.1. Contextual breakpoints

With responsive web design, you change the layout of the page based on screen widths, called breakpoints. In contextual design, we can use this term, breakpoints, to discuss the places where we change context.

In order to achieve context awareness, you need to first establish some breakpoints to adjust context around. In the beverage example, you offer hot coffee in the morning, but you might also want to promote beer or diet soda at different times of the day. We’ve identified one factor that needs to change (the beverage being served), and one context to change it against (the time of day). The context that instigates the change will serve as our contextual breakpoint, so we can identify “6 pm” as a contextual breakpoint—that’s when we change from soda to beer.

In order to better understand this, table A.1 shows when the message will change and what it will change to. You can see that there are specific times when the message changes: 4 am, 12 pm, and 6 pm. These can serve as contextual breakpoints.

Table A.1. Beverage messages at different times of day

Time

Message

4 am–12 pm

“We have hot coffee!”

12 pm–6 pm

“We have diet soda!”

6 pm–4 am

“We have cold beer!”

These time ranges give a good sense of what the context for each of the messages will be, but you also need to identify a key/value pairing so that you can implement these in your page. This will become clear in a minute when you start building some contextual tests.

In order to better interpret these breakpoints, let’s give them some simple strings that you can work with in JavaScript (see table A.2). This works nicely for now, but you could also expand this out to other contextual factors.

Table A.2. Breakpoints with key/value strings

Time [breakpoint key]

Message [module value]

4 am–12 pm (morning)

“We have hot coffee!” (coffee)

12 pm–6 pm (afternoon)

“We have diet soda!” (soda)

6 pm–4 am (evening)

“We have cold beer!” (beer)

Say, for instance, that you have a baseball site. You might want to feature a specific team more prominently to visitors from particular regions. You could use a user’s GPS location to determine if they’re in a region that favors a specific team and serve modules for that team in prominent places on the page. A few of the contextual breakpoints might look like those in table A.3.

Table A.3. Contextual breakpoints for regions and baseball teams

Region

Team

New England

Boston Red Sox

New York State

New York Yankees

Washington DC

Washington Nationals

Missouri

Kansas City Royals

Wisconsin

Wisconsin Brewers

In table A.3 you have regions as contextual breakpoints: New England, New York State, Washington DC, Missouri, and Wisconsin.

What you need now is a way to do things differently based on whether the user meets the restrictions of the contextual breakpoints. Much like with a media query, if a browser’s width is under X, some styles are served; if the width is between X and Y, other styles are served; and if the width is over Y, another set of styles is served. With context awareness, if a user meets condition A, some functions should execute and some assets should be loaded, and if they meet condition B, other functions should execute and other assets should be loaded.

Getting back to the beverage module, now that you have the contextual breakpoints in mind, you’re free to alter your module. You simply need to figure out how. Establishing context is tricky, though. There’s no set object to establish it against. In responsive design there’s a solid value (such as viewport width), but with context awareness you need to establish something more dynamic.

In chapter 8 we discussed Modernizr, a JavaScript library for cross-browser testing. In that chapter we touched on yepnope.js, a tool that will give you everything you need to conditionally load assets. Using yepnope.js, you can load contextual assets based on passing a Boolean value. Inchapter 8 we did this by passing in a Modernizr test, which returns Boolean (true or false) values. In order to use custom context awareness, you need to create your own test.

We discussed the addTest method in chapter 8 as well. One way to create new, custom contextual modules is by adding them to Modernizr. This will give you all the flexibility of having Modernizr style classes available within your site’s CSS, but it comes at a cost: Modernizr prevents the page from loading until all tests are completed. This is important to how Modernizr works, but it may be too cumbersome for what you want to accomplish.

Instead of relying on Modernizr for this, we’ll use yepnope to conditionally load assets related to the context. But first you have to write some functions to test with. In the beverage module, you want to test what time it is for the user, and based on the time, you’ll use yepnope to load in some new assets and then execute a function.

A.2.2. Creating contextual tests

You start by creating a namespace for your contextual tests. On line 7 in the A.2 directory of the appendix A source code, you’ll create a “context” object to use as a namespace for your tests. Within the namespace, you’ll create functions for each of your contextual breakpoints—morning, afternoon, and evening:

<script type="text/javascript">

var context = {

morning: function(x){},

afternoon: function(x){},

evening: function(x){},

};

</script>

Now you can access these functions as context.morning, context.afternoon, and context.evening.

Within each of these, you need to create functions that will return true or false based on what you want to test against. Before you do that, though, you’ll add a helper function to return the current time:

var hours = function(){

var current = new Date();

current = current.getHours();

return current;

}

With this, you can create your tests. You’ll use the generic x parameter and the hours() helper function to pass the time to your contextual tests. In the context object you’ll create simple conditional statements and return them directly in the functions. In the A.3 source code you can see thehours() function, as well as the tests returning Boolean values:

var hours = function(){

var current = new Date();

current = current.getHours();

return current;

}

var context = {

morning: function(x){

return !!(x > 4 && x < 12);

},

afternoon: function(x){

return !!(x >= 12 && x < 18);

},

evening: function(x){

return !!(x >= 18 && x < 24 || x > 0 && x <= 4);

},

};

The double exclamation points in the preceding code will directly return the results of the conditional statement as a Boolean value. With this, you have set your three conditional tests in motion.

Now you need to run a loop to test for each of your contexts and load the conditional assets for the three tests:

for (x in context) {

console.log(context[x](hours()));

}

This code will log the results of each test as true or false. You should get two false and one true when you run this code.

Next you can create your yepnope.js loads for the tests. Yepnope.js will load Java-Script files for morning, afternoon, and evening:

for (x in context) {)

yepnope([{

test: context[x](hours()),

yep: "contexts/" + x + ".js",

complete: function(){

}

}])

}

This code will conditionally load assets. Now you need to run a function to give you some CSS hooks, as in Modernizr. You can use an if statement for this:

if(eval(test)){

var html = document.documentElement;

html.className += "is-" + x;

};

This code will add “is-” to the name of your contextual breakpoint; in the evening, it’ll produce the name “is-evening” and append “is-evening” to the HTML class on your page.

Now you can tie all of this together with some CSS.

A.2.3. Contextual CSS

You have a series of tests that add classes to the HTML object on the page, so now you can use some conditional CSS. The example already has the brown “We have hot coffee” message at the top of the page. Now you can add afternoon and evening messages.

First create three CSS rules for each of the contextual breakpoints—one for is-morning, one for is-afternoon, and one for is-evening:

.is-morning h1#message{

text-align: center;

color:#c18230;

background-color: #4a2b03;

}

.is-evening h1#message{

text-align: center;

color:#4e63cb;

background-color: #152058;

}

.is-afternoon h1#message{

text-align: center;

color:#e04f28;

background-color: #802209;

}

All you’re doing here is changing the color of the backgrounds. If you check out your browser, you’ll see a brown message in the morning, a red message in the afternoon, and a blue message in the evening (see figure A.2). The source code for this demo can be found in the A.5 directory.

Figure A.2. The morning, afternoon, and evening styles applied to the placeholder h1

Here you’ve styled the three messages uniquely for the contextual tests. This styling can be extended throughout the page, and any major assets you want loaded can be brought in contextually with yepnope. For example, change the text of your sample message in the contexts/morning.js file. You can start by creating a global variable called message:

var message;

Then you can set message to the morning coffee message.

In the yepnope complete function, change the contents of the h1 on the page to display the message. Here’s a replace-text function:

var replaceText = function(x){

var module = document.getElementById("message");

module.innerHTML = x;

};

You can also move all the code to the bottom of the page so it executes after the DOM is fully rendered. With this final bit of code, you have a good basic example of how a contextually aware site might work.

A.3. Summary

In this appendix you learned the basics of contextual web design. With contextually aware websites, you can improve the user’s experience by serving site content based on how your users are using the site. This appendix barely scratches the surface of what’s possible with context awareness.

With the concepts in this appendix, you can start introducing context awareness to your websites. You can use contextual breakpoints much like traditional responsive breakpoints. By using the “context” namespace for your tests, you can introduce a series of tests; by using yepnope, you can load conditional assets according to the test results, and then execute some JavaScript once the assets are loaded.

The demo in this appendix is simplistic, but it introduces the concepts you need to start building complex, contextually aware web designs. The depth of sites this enables you to create is nearly limitless. Using information based on a user’s context can deeply enhance a user’s site experience and can lead to new and innovative ways of presenting a site’s user interface.