Media Queries

One element of CSS that is becoming more and more important to understand is media queries. The idea is that by evaluating certain traits of the visitors device (screen size, orientation, resolution, etc) you can then customize your CSS accordingly. So in theory, you would build a single site, that would respond intelligently (Responsive Web Design) depending on the visitor, rather than having a ‘full’ site, a ‘mobile’ site, and redirects between them.

The general syntax is that within your <style> code, you have:

@media (parameter_to_test:value){ here is the CSS for this particular scenario }

Here is a recent example I made to demonstrate the concept:

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-icon" href="data:image/png;base64,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"/>
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Media</title>
<style>
html,body{width:100%;height:100%;margin:0;padding:0;background-color:#f00}
@media screen and (max-device-width: 320px) and (orientation:portrait) {
body { background-color:#FFF; }
}
@media screen and (max-device-width: 320px) and (orientation:landscape) {
body { background-color:#000; }
}
</style>
</head>
<body>
<span style="color:#000">Portrait</span><span style="color:#FFF">Landscape</span>
</body>
</html>

Because this was particular inquiry was actual regarding iPhone orientation changes, you’ll see I have some of the apple- header data (I discuss this further in the Web App post). I like to include that in mobile projects because I find most benefit from being installed to the Home Screen.

If you take this code and view it in your browser (or click here), you’ll get a big red screen because the CSS outside of the media queries has background-color:#f00 but if you view in on an iPhone (which has a width of 320px [see that value in the media queries?]) you’ll have a white background in portrait, and a black background in landscape [note those items in the queries as well].

Update: I realize I didn’t fully dive in to the different parameters one can evaluate. Tonight I was asked how to determine if a device was a) typical non-tablet device b) high resolution non-table device c) tablet.

For an ideal solution one would also consider high resolution tablets (iPad 3) but the concept is still sound:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Media2</title>
<style>
body, html {margin:0;padding:0;height:100%;width:100%; background-color:#000000;}
@media (max-width: 767px) { body {background-color:#0000FF;} }
@media (max-device-width: 320px) and (-webkit-min-device-pixel-ratio: 2) { body {background-color:#00FF00;} }
@media (min-width: 768px) { body {background-color:#FF0000;} }
</style>
</head>
<body>
</body>
</html>

So the page is just a 100% wide, 100% high block, with background color black (#000000). Then the media queries are applied:

1) If the device is 767 pixels wide, or smaller, the background is made blue (#0000FF)

2) If the device is 320 pixels wide, or smaller, AND has a pixel ratio of 2 (which the retina devices have), the background is made green (#00FF00)

3) If the device is 768 pixels wide, or larger, the background is made red (#FF0000)

Notice the order as well, if I had test 2 be the first line, it would succeed, making the screen green, if that was followed by test 1, it would also succeed, changing the color again, now to blue.

Obviously these CSS changes are trivial, but it illustrates how a single page can adapt to the device on which it’s being used (click here to try your device):
Media Queries

For the sake of brevity, I try to place all of the style elements that are NOT impacted by media queries (or default values for those that are, such as the red in the first example, or black in the second) outside of the queries. I have seen pages that have nothing outside of the queries, and then just have the full set inside each query, but I try to avoid repetition (you can also load external CSS files using queries, but the syntax is a little different):

<link rel="stylesheet" media="screen and (min-device-width: 800px)" href="example.css" />

You can also replicate some of these behaviors with javascript, for instance, testing window.innerWidth along with window.orientation, then re-writing some CSS values like so:

document.styleSheets[0].cssRules[0].style.backgroundColor='#0000FF";

Here are some examples of responsive web design. According to Google, nearly 80% of it’s top ad buying companies have not designed their site for mobile devices. Is your site mobile optimized? What interesting examples of media queries have you seen?

Web Apps

So web apps are pretty awesome. Of course they have some limitations like access to device hardware (camera), and they can take a little extra time to load depending on how they’re built, but overall, the time it takes to put together a convincing prototype web app is small and the results can be impressive. And then there are tools to wrap these builds in enough native code that it can really become a native app: PhoneGap, Appcelerator, etc

I’ve been in a few prototype coding competitions recently, and have found myself adopting web app solutions more and more. I also receive a lot of questions about this at work, and find myself pointing people to the same resources over and over, so I thought a post here might benefit someone else. Please do find a number of helpful links throughout the post.

The gist of it (and I should preface that I’m biased towards iOS, but many of these elements port to Android just fine) is that you want to take a web page and modify it sufficiently so that it mimics a native application experience. This entails things like: removing the browser elements, adding an icon, adding a launch/splash screen, handling orientation changes, and so on.

Let’s jump into it…here is some of the header from a typical app I build:

<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="apple-touch-icon" sizes="57x57" href="icon/icon57.png" />
<link rel="apple-touch-icon" sizes="72x72" href="icon/icon72.png" />
<link rel="apple-touch-icon" sizes="114x114" href="icon/icon114.png" />
<link rel="apple-touch-icon" sizes="144x144" href="icon/icon144.png" />
<link rel="apple-touch-startup-image" media="screen and (max-device-width: 320px)" href="images/iphone_splash.png"/>
<link rel="apple-touch-startup-image" media="(max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2)" href="images/iphone_splash_hires.png" />
<link rel="apple-touch-startup-image" href="icon/ipad_landscape.png" media="screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation:landscape)" />
<link rel="apple-touch-startup-image" href="icon/ipad_portrait.png" media="screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation:portrait)" />
<link rel="apple-touch-startup-image" href="icon/ipad_landscape_hires.png" media="screen and (min-device-width: 481px) and (max-device-width: 1536px) and (orientation:landscape) and (-webkit-device-pixel-ratio: 2)" />
<link rel="apple-touch-startup-image" href="icon/ipad_portrait_hires.png" media="screen and (min-device-width: 481px) and (max-device-width: 1536px) and (orientation:portrait) and (-webkit-device-pixel-ratio: 2)" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />

Going line by line: “viewport” tells the device how wide the viewable area should be…it’s important because an iPhone is 320 pixels wide (or 640 points in a retina display) but if you don’t explicitly set the viewport, it acts as if it’s 960 pixels wide (so if your content is 320, you’re getting a zoomed out version).

The “apple-touch-icon” links are icons for: iphone, ipad, iphone retina, ipad retina.
icon sizes

In my sample I made unique icons for each just to highlight that they were different, but really, I’d build one at 144×144, then scale it down and save it accordingly…unless I had some graphical element that fell apart in the smaller icons, then I’d tweak those versions accordingly. Here are some metrics around icon images: HIG

The “apple-touch-startup-image” links are for the splash screen. This is the image that pops up while the app loads. There are some intricacies around this, mostly with iPad. iPhone is straightforward: portrait, 320×460 for iPhone, 640×920 (don’t forget the media portion) for iPhone retina…but iPad is a little odd in that they accept a landscape version as well as portrait, but the images it accepts must always be taller than they are wide, so when you’re making the landscape images, you need to rotate the CONTENT, not the image. Not a big deal, but a critical distinction to make.

apple-mobile-web-app-capable” tells the phone that this page can be installed as an application (using the icon and splash screens we’ve defined)

apple-mobile-web-app-status-bar-style” can set the status bar style. There are a few options (default, black, black transparent) but I usually omit it if I want the default, or go with black if the style of the app is dark.

The stage is set, but we have some steps to get through before showing real content, so in order to let the user know we’re working on it, I like to start my apps with a little loader graphic that is then replaced when the real load is complete:

<body>
<img src="loader_graphic.gif"/>
</body>

So now the framework is there, but there are a few more subtle details before you get to the content. First, in order for anyone to see the icon and startup image, they have to install it. A user does this by tapping the arrow at the bottom of safari (on an iPhone, it’s at the top on iPad), and then ‘Add to Home Screen.’ So you’ll want to keep an eye out for users that can do so, and give them some guidance (more or less politely depending on the purpose…I’ve had builds where if it was not installed, you would only see an animation of how to do so):

installation guidance screen

But often you’ll just see a little tooltip box appear near the arrow as a gentle reminder. So how do we determine when do do any of this? We need to know it’s an eligible device, and that it’s not already installed. For the first portion of that I do the following:

var ipad=navigator.userAgent.match('iPad')?true:false;
var iphone=(navigator.userAgent.match('iPhone')||navigator.userAgent.match('iPod'))?true:false;

So now we know if it’s an iPad, or iPhone (I don’t distinguish between iPhone and iPod here). But is it installed? By testing the navigator.standalone property we can find out.

if((iphone||ipad)&&(!navigator.standalone)){
	//here is where you would handle install instructions like 
	//popping up an image about how to "Add to Home"
	str='please install me by pressing the arrow button at the ';
	str+=ipad?'top':'bottom';
	str+=' of the screen, then selecting \'Add to Homescreen\'';
	alert(str);		
}

So, we’re close, but not quite there because unlike a full computer, your device has an orientation. You’ll want to add a listener for orientationchange to the body, which can be as straightforward as:

<body onorientationchange="updateOrientation();">

in conjunction with a function like this:

function updateOrientation(){
	switch (window.orientation) {
	//while some things will be handled by the phone itself,
	//you may need to change some things manually (for instance,
	//you may have two elements stacked on top of each other,
	//and you'd like them to sit side by side in landscape mode
        case 0:
        alert ('Orientation: Portrait');
        break;
        case 90:
	alert ('Orientation: Landscape');
        break;
        case -90:
        alert ('Orientation: Landscape');
        break;
	case 180:
        alert ('Orientation: Portait');
        break;
    }
}

Obviously javascript is one approach, but some things can be handled with CSS Media Queries, so that’s a powerful tool to understand as well.

One detail about the various versions of iOS, is that CSS’ position:fixed isn’t supported before 5.0, so if I used that (and I do), I want to test for that as well:

if(iphone||ipad) { 
	if(/OS [2-4]_\d(_\d)? like Mac OS X/i.test(navigator.userAgent)) {  
        	alert('This is designed for iOS 5 and above, please update your device for proper functionality'); 
   	} else if(/CPU like Mac OS X/i.test(navigator.userAgent)) {
        	alert('This is designed for iOS 5 and above, please update your device for proper functionality');
    	} else {
		//iOS5+
	}
}

Okay. So the last piece is user interface. If you’re trying to mimic a native app, you’ll probably use elements like a navigation bar at the top, or tabs at the bottom, etc. Here is how I set up a starting point:

#nav {
width:100%;
height:40px;
position:fixed;
top:0;
text-align:center;
background-color:#29abe2;
color:#FFF;
font-size:150%;
padding-top:5px;
border-bottom:thin solid #444444; display:block;
font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
}
#main{ width:100%; margin-top:45px; }
#footer {
width:100%;
height:44px;
position:fixed;
bottom:0;
left:0;
text-align:center;
color:#FFF;
font-size:150%;
margin-top:5px;
border-top:thin solid #444444; 
background:#000000;
}

And when I’m ready to show the app (it’s installed, etc), I just:

document.body.innerHTML='<div id="nav"></div><div id="main"></div><div id="footer"></div>';

And then fill in my content to the main div (I have a function for each view that changes the .innerHTML, and that are linked to tabs that I build in the footer).

So if you’d like to give it a try, visit www.robotwoods.com/dev/web_app_demo from your mobile device. It should work in Android too, the way to install there is to bookmark it, then go to your bookmarks, and long press it, it’ll then give you some sort of Home Screen option. I also put the files in a zip here

Oh, you’ll see in the actual app that the footer has a gradient, I use this site for that: http://www.colorzilla.com/gradient-editor/ I think subtle gradients add a bit of warmth to a UI that may look dull with solid color blocks (see the icons as an example).

And, to minimize the size of your project (which enables faster download), you may want to minify your javascript. I think there are a variety of options for this, I usually just go with: http://jscompress.com/

Lastly, once everything is running as you like it, there’s one more way to improve performance (particularly in those applications that do not require a network connection, for instance, calling a web service for data): cache manifest

By crafting a particular file that outlines all of the files used in your project, the device will (with some limitations) store those files locally, so that it will run even when disconnected from the network. And, as the files are local, it loads much faster as well.

I have covered a number of the important areas of a web app, but there is plenty of other areas and approaches to learn about. What other tips and tricks do you use when building web apps?