Responsive design in UNICOM Intelligence web surveys
Abstract
Responsive web design is a technique of creating web pages that has been gaining traction in the web design community. The term Responsive Design was coined by Ethan Marcotte, but the concepts for a flexible grid layout and the standard browser features used to create responsive designs have been around for quite a while. Responsive design is a strategy for offering suggestions for viewing content to the maximum number of technologies possible. The point is not to design the one and only way every user will access your content, but rather to suggest the best way to experience your content while allowing all users to consume it regardless of the devices, browsers, or assistive technologies they are using. This paper will serve as a quick tutorial on responsive design and will include examples of its use in UNICOM Intelligence layout templates. It is assumed the reader is familiar with HTML, CSS, JavaScript, and UNICOM Intelligence layout template tags.
Client configurations unlimited
Devices come in sizes ranging from 320px to over 2400px in width. Users come with various preferences and physical limitations. Some users turn off JavaScript while other users view the web in unmaximized browser windows. Furthermore, there is nothing preventing a user from changing the browser size after the page has downloaded. Web content is viewable on such a wide range of screen and resolution sizes that having separate sub-sites or server-side redirects for every possibility is infeasible. What is required is an intelligent, adaptive, client-based solution that allows servers to serve content rather than make decisions for rendering on any number of clients.
Responsive design is flexible design
Responsive design aims to provide a scalable experience using streamlined HTML, CSS that uses relative sizing, and media queries while leveraging the capabilities of the browser to re-render pages without needing to perform another full page request from the server.
Streamlined HTML
Streamlined HTML infers a structure that adds information about the content, not about the styling. For instance, the italics tag <i> is purely a styling tag and adds no information about the content but the emphasis <em> tag informs the user that emphasis should be placed on the contents of the tag. By default, most browsers render the emphasis tag with italics. Using CSS allows this behavior to be overwritten (it could be made RED and BOLD instead). The classic example of an improperly used set of tags is the Table tr, and td tags that are commonly used for layout rather than to inform the user that the contents of the table should be understood as tabular data.
Relative sizing
Relative sizing allows the user to resize fonts without breaking the design. Most browsers come with the default text size set to 16px. Some users increase the font for more comfortable reading. The most compelling reason for developers to use relative sizing is to make the markup maintainable. When switching between devices sizes, setting the font-size proportionally will make things much easier to re-size. It is the difference between resetting one font-size versus an entire collection of font-sizes for each different screen. Furthermore, images should be scaled to fit the shrinking or expanding zones. Image width and height can be set to percentages or background images can be clipped (revealed or covered) depending on the size of the containing element.
Metatags for small smart devices
To keep browsers on some smaller, smart devices from shrinking the content to fit the width of the device, add the following metatag:
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
This sets the width of the viewport to the device width, sets the zoom to 1 (so the browser will not shrink to fit), and prevents the user from pinch zooming. You might or might not want to include that last setting depending on the content you plan to deliver. Using these tags will not interfere with the user experience on larger devices.
Media queries
Media query is a W3 CSS3 standard that has been supported in Mozilla browsers since Firefox 3.6 and Opera 9.5. Webkit browsers (Android, and iOS) have always supported media queries. Apple suggests using media queries as the way to target iOS devices. Unfortunately, Microsoft Internet Explorer 8 and under does not support media queries. You can however make your design degrade gracefully for these browsers.
Media queries allow you to query the browser regarding its resolution, device height and width, device aspect ratio, browser height and width, and other properties that might be important to your design. For more information, see
Media queries let you tailor the experience of your page at a very granular level based on browser's current properties and the device your page is being viewed upon.
In the following example, the link element queries the browser width to see if it is between 320px and 460px.
<link type=”text/css” rel=”stylesheet”
media=”screen and (min-width :320px) and (max-width : 460px)”
href=”small.css”/>
In this way, link elements can be strung together to target different browser width ranges. Link elements are ignored when the browser width is outside the link element range. For example, when a browser is sized to 480px wide, and the following link elements exist in the HTML document head, the browser will ignore each link element except the mid.css link:
<link type=”text/css” rel=”stylesheet”
media=”screen and (min-width :320px) and (max-width : 460px)”
href=”small.css”/>
<link type=”text/css” rel=”stylesheet”
media=”screen and (min-width :461px) and (max-width : 1200px)”
href=”mid.css”/>
<link type=”text/css” rel=”stylesheet”
media=”screen and (min-width :1201px)”
href=”large.css”/>
Depending on how concerned you are about performance, you could also combine all of the rules in these separate stylesheets into one stylesheet by performing the media query within the CSS file. For example, you could change the preceding example so that is could be performed in a single CSS file; the result might look this:
@media screen and (min-width :320px) and (max-width : 460px) {
...rules for small here
}
@media screen and (min-width :461px) and (max-width : 1200px) {
...rules for mid here
}
@media screen and (min-width :1201px) {
...rules for large here
}
The JavaScript alternative
Media queries are not possible with Microsoft Internet Explorer 8 and earlier. Many designers consider this a case for simple degradation (Internet Explorer users will have a different experience). Users might have to do more scrolling when their browser windows are sized down. However, if it is important to ensure Internet Explorer users have the same experience when resizing their browser windows, you could do one of two things.
▪Do not follow responsive design and make everyone scroll around when browser windows are small (no additional work is required).
▪Use JavaScript.
When using JavaScript instead of media queries, you can swap class names on the body tag when the browser size is within the desired ranges. You could recreate the single CSS file with the media queries shown earlier; instead of using the @media... instruction to section off the CSS file, you could use class names as follows:
/*General*****************************************/
.branding, .mainContent, .nav {padding:0;margin:0;border:none}
.mainContent{}
.nav{direction:rtl;}
/*large format************************************/
.large {font-size:110%}
.large .branding {background-color:#333;color:#fff;position:relative;height:100%;float:left;display:inline;width:10em}
.large .nav {text-align:center}
/*mid format**************************************/
.mid .branding {background-color:#999;position:relative;height:100%;float:left;display:inline;width:10em}
.mid .nav {text-align:center}
/*small format************************************/
.small {font-size:90%;position:relative;}
.small .branding {background-color:#eee;position:relative;height:1.5;display:block;text-align:center}
.small .mainContent {position:absolute;top:1.5em;left:0;right:0;bottom:1.5em;display:block;overflow:auto}
.small .nav {background-color:#eee;position:absolute;bottom:0;left:0;width:100%;height:1.5em;display:block;}
.small .nav input {background-color:#fff;border:none;width:32%;margin:0;padding:0;}
In order to prevent browsers that do support media queries from attempting to download the non-media query CSS, you should perform a feature check in JavaScript to determine if the browser supports media queries. If media queries are not supported, you can programmatically add a link element to the head that points to the non-media query CSS.
if (!window.matchMedia) {
var lnk = document.createElement("link");
lnk.rel = "stylesheet";
lnk.type = "text/css";
lnk.href = "noMedQ.css";
document.getElementsByTagName("head")[0].appendChild(lnk);
}
You can also add an
eventListener to the window object that fires on resize and will change the body class name depending on the browser dimensions (or any other setting you can check with JavaScript). For a complete example, see
Appendix.
if (window.addEventListener) {
window.addEventListener("resize", resizeHandler, false);
}
//Now the IE model
else if (window.attachEvent) {
window.attachEvent("onresize", resizeHandler);
}
When JavaScript is selected for browsers that do not support media queries, you will likely be left with a subset of users that do not have JavaScript enabled. This will force a fall back to the default stylesheet. These users will expect a degraded experience, just be sure that all the functionality on your page is available when JavaScript is turned off. The user experience should be functional when JavaScript is disabled. You are not expected to provide the more responsive features when JavaScript is disabled. For example, if you have an AJAX date picker (like dojo’s dijit.form.DateTextBox), ensure the page degrades to a basic text box for entering a date (you might want to ensure any max and min values are present in the question text).
UNICOM Intelligence-specific issues
When you are working in UNICOM Intelligence templates, you must use mrRef tags in order to reference the external resources.
Instead of:
<link type=”text/css” rel=”stylesheet”
media=”screen and (min-width :320px) and (max-width : 460px)”
href=”small.css”/>
use:
<mrRef RefType=”link”
type=”text/css” rel=”stylesheet”
media=”screen and (min-width :320px) and (max-width : 460px)”
href=”small.css”/>
Things become interesting when you try to programmatically add the non-media query CSS. UNICOM Intelligence does not have a tag that inserts the imageCache URL text. You might need to add an invisible image from the image cache, give it a specific ID, and then use JavaScript to parse the image cache URL out of the img src attribute.
<mrRef RefType=”img” id=”blankGif” class="branding-element" src=" default.htm_files/images/blank.gif" />
Is delivered to the browser as:
<img id=”blankGif” class="branding-element"
src="http://SERVERNAME/SPSSMR/ImageCache/ImageCache.aspx?Project=RESPONSIVEDEFAULT&File=en-US/default.htm_files/images/blank.gif" />
You might want to write the JavaScript as:
//Get the ImageCacheURL from the blank.gif file
var ImageCacheURL = document.getElementById(“blankGif”).getAttribute(“src”)
.replace(/\/images\/blank\.gif/g, ‘’);
var lnk = document.createElement("link");
lnk.rel = "stylesheet";
lnk.type = "text/css";
lnk.href = ImageCacheURL + "noMedQ.css";
document.getElementsByTagName("head")[0].appendChild(lnk);
Conclusion
This white paper demonstrates the standard use of media queries that will help you tailor the experience of your UNICOM Intelligence web surveys to more devices with a greater amount of flexibility. It also demonstrates how to fake media queries in older browsers using JavaScript and CSS class names and touched on graceful degradation for users on older browsers who have turned off JavaScript. Finally it discusses specific UNICOM Intelligence layout template implementation considerations.
Appendix
The following items contain HTML markup, CSS, and JavaScript required to make a responsive UNICOM Intelligence web survey layout template that will function in nearly all browsers.
Main HTML page
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
<title>Untitled Document</title>
<style type="text/css">
html, body {width:100%;height:100%;margin:0;padding:0;overflow:auto}
.branding, .mainContent, .nav {padding:0;margin:0;border:none}
.nav{direction:rtl;}
</style>
<mrRef RefType="link" rel="stylesheet" type="text/css"
media=" screen and (min-width :320px) and (max-width : 460px)"
href="default.htm_files/large.css" />
<mrRef RefType="link" rel="stylesheet" type="text/css"
media="screen and (min-width: 461px) and (max-width: 1200px)"
href="default.htm_files/mid.css" />
<mrRef RefType="link" rel="stylesheet" type="text/css"
media="screen and (min-width: 1201px)"
href="default.htm_files/small.css" />
</head>
<body class="large-doofer">
<div class="branding">
Branding Bar
<mrRef RefType="img" id="blankGif" class="branding-element" src="default.htm_files/images/blank.gif"/>
</div>
<div class="mainContent">
<mrData>Questions here</mrData>
Main content here
</div>
<div class="nav">
<input type="button" value="Next"/>
<input type="button" value="Stop"/>
<input type="button" value="Previous"/>
</div>
</body>
<script>
(function() {
//if the browser does not support media queries add an event listener for window resize:
var parent = document.getElementById("parent");
if (!window.matchMedia) {
//This is the function we'll perform EVERY time the window is resized
var resizeHandler = function() {
var bod = document.body;
var clientWidth = bod.clientWidth;
var curClass = "";
/*check the current class name of the body element
-- be sure not to overwrite any class names that aren't associated
with the responsive widths */
if (bod.className != null) {
curClass = bod.className.replace(/\ssmall\s/g, '')
.replace(/\smid\s/g, '')
.replace(/\slarge\s/g, '');
}
if (clientWidth <= 460) {
curClass += " small ";
}
else if (clientWidth > 460 && clientWidth <= 1200) {
curClass += " mid ";
}
else {
curClass += " large ";
}
bod.className = curClass;
}
//Set the initial class name for the body:
resizeHandler();
//add the css link element to the head
var ImageCacheURL = document.getElementById("blankGif").getAttribute("src")
.replace(/\/images\/blank\.gif/g, '');
var lnk = document.createElement("link");
lnk.rel = "stylesheet";
lnk.type = "text/css";
lnk.href = ImageCacheURL + "noMedQ.css";
document.getElementsByTagName("head")[0].appendChild(lnk);
//now check the event api Standards First
if (window.addEventListener) {
window.addEventListener("resize", resizeHandler, false);
}
//Now the IE model
else if (window.attachEvent) {
window.attachEvent("onresize", resizeHandler);
}
}
})();
</script>
</html>
Media query CSS files
The following CSS files are referenced by the media queries.
large.css
body {font-size:110%}
.branding {background-color:#333;color:#fff;position:relative;height:100%;float:left;display:inline;
width:10em}
.nav {text-align:center}
mid.css
.branding {background-color:#999;position:relative;height:100%;float:left;display:inline;width:10em}
.nav {text-align:center}
small.css
body {font-size:90%;position:relative;}
.branding {background-color:#eee;position:relative;height:1.5;display:block;text-align:center}
.mainContent {position:absolute;top:1.5em;left:0;right:0;bottom:1.5em;display:block;overflow:auto}
.nav {background-color:#eee;position:absolute;bottom:0;left:0;width:100%;height:1.5em;display:block;}
.nav input {background-color:#fff;border:none;width:32%;margin:0;padding:0;}
Non-media query CSS file
@charset "utf-8";
/*General*****************************************/
.branding, .mainContent, .nav {padding:0;margin:0;border:none}
.mainContent{}
.nav{direction:rtl;}
/*large format************************************/
.large {font-size:110%}
.large .branding {background-color:#333;color:#fff;position:relative;height:100%;float:left;display:inline;width:10em}
.large .nav {text-align:center}
/*mid format**************************************/
.mid .branding {background-color:#999;position:relative;height:100%;float:left;display:inline;width:10em}
.mid .nav {text-align:center}
/*small format************************************/
.small {font-size:90%;position:relative;}
.small .branding {background-color:#eee;position:relative;height:1.5;display:block;text-align:center}
.small .mainContent {position:absolute;top:1.5em;left:0;right:0;bottom:1.5em;display:block;overflow:auto}
.small .nav {background-color:#eee;position:absolute;bottom:0;left:0;width:100%;height:1.5em;display:block;}
.small .nav input {background-color:#fff;border:none;width:32%;margin:0;padding:0;}
See