1 August 2011
Intermediate
In this second part of this two-part tutorial series, you'll put into practice the theory you learned in Part 1, Using media queries, to deliver different styles to mobile phones, tablets, and desktop computers. You'll learn how to apply basic styles to a sample page and then how to use media queries to override them with styles optimized for different screen widths. Older browsers, including Internet Explorer (IE) 6–8, don't support media queries, so the basic styles need to be attached to the page in the normal way. You also need to add a special <meta> tag to prevent modern mobile devices from rescaling the page and ignoring the media queries. These instructions are not specific to Dreamweaver. The HTML markup and CSS styles can be edited in any text editor.
When using media queries to create a responsive design suitable for a range of different screen sizes, the designer faces a major decision. Which should come first—the desktop design or the mobile one? Because mobile web development has been somewhat of a niche activity until recently, I suspect that most projects begin with the desktop design, and adapting it for mobile comes as an afterthought. However, the advice from many experts is to design for mobile first. By doing so, you ensure that all essential content is accessible to mobile users. You can then use progressive enhancement to improve the presentation on tablets and desktops.
The design for the sample page in this tutorial is adapted from my book Adobe Dreamweaver CS5.5 Studio Techniques: Designing and Developing for Mobile with jQuery, HTML5, and CSS3 (Adobe Press). In the book, the process begins with the desktop design and adapts it for mobile. In this tutorial, I'm taking the opposite approach, designing for mobile phones first and adapting the styles for tablets and desktops.
Of course, it's not always practicable to approach a project this way. The desktop version might already exist. You can see a practical example of adapting a desktop design for mobile devices in my three-part series on HTML5 and CSS3 in Dreamweaver CS5.5.
To keep things simple, the sample files contain a single web page. I won't describe every detail of the style rules, but will concentrate on explaining features that relate to the use of media queries and displaying the page on different size devices.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Tozai Hotel: Dining</title>
<link href="styles/basic.css" rel="stylesheet" type="text/css">
<title> tag, and add the following code:<meta name="viewport" content="width=device-width, initial-scale=1">
Adding the viewport <meta> tag with these settings ensures that smartphones and tablets respect the width settings in media queries. Setting initial-scale to 1 also ensures that the iPhone, iPad, and iPod touch apply width settings correctly in landscape orientation.
Note: The style sheet, basic.css, is attached to the page without a media query. This means that the styles will be applied by all visual browsers, even if they don't understand media queries.
<img src="images/sashimi.jpg" alt="Selection of sashimi" width="400" class="floatright">
The height has also been omitted from the image in the fifth paragraph. Omitting the height allows you to scale down the images on a smaller screen without distortion.
The style sheet, basic.css, is attached without a media query, so the styles will be applied by all browsers. Later, you'll override some styles by adding dedicated style sheets for tablet devices and desktops. But first, let's take a look at the main features of the basic styles.
Open basic.css. The first style rule looks like this:
body {
margin: 0;
padding: 0;
background-color: #EEF2EF;
color: #000;
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
font-size: 100%;
}
This is straightforward. It zeroes the margin and padding on the <body> of the page, and sets the colors for the background and font. It also defines the basic fonts to be used in the page, and sets font-size to 100%. When designing for mobile devices, it's recommended to use percentages for fonts. Setting the base size to 100% ensures that other percentages are correctly interpreted. With this setting, most browsers display text at 16px.
The next style rule controls the wrapper <div>, which encloses all the page content. It looks like this:
#wrapper {
width: 100%;
max-width: 980px;
margin: 0 auto;
background-image: url(../images/basin_bg_phone.jpg);
background-size: contain;
background-repeat: no-repeat;
background-color: #B4C4BA;
}
This sets the width of the wrapper to 100%, but sets the maximum to 980 pixels. The horizontal margins are set to auto. As a result, the page fills the full width of phones and tablets, but becomes a centered, fixed-width design on screens wider than 980 pixels.
The background image is 480 pixels wide, but the CSS3 background-size property has been set to contain. This scales the background image to the largest size needed for both its width and height to fit inside the element without distortion. In effect, it shrinks the image when the viewport is less than 480 pixels wide. On a bigger screen, it expands the image, potentially resulting in pixilation, but a larger version will be served to tablets and desktops using media queries.
The next style rule ( #header h1 ) sets the font size to 225%, which is the equivalent of 36 pixels. The text is centered, but an extra 40 pixels of padding is added to the left to move it away from the Chinese characters on the left of the background image.
The next style rule of interest is for the floatleft and floatright classes, which are applied to the inline images. It looks like this:
.floatleft, .floatright {
width: 95%;
max-width: 400px;
display: block;
margin: auto auto 1.5em;
}
Setting the width of an image in CSS overrides the width in the HTML markup. As a result, on small screens, the images are rescaled to 95% of the width of their parent element. In the sample page, both inline images are 400 pixels wide, so the max-width property prevents them from being displayed larger than their original size. Obviously, if your design has images that are different sizes, you would need to create extra classes to handle them. The images will be floated on larger screens, but the basic rules set the display property to block and the horizontal margins to auto—in effect, centering the images in the page.
The style rules for the navigation menu give the nav unordered list a fixed width and height. Using a fixed width makes it possible to center the menu by setting the horizontal margins to auto. The height is needed to push the following content down the page, because the individual menu items are floated left. There are five items in the menu, so the final one is centered by the following rule:
#nav li:last-child a {
margin-left: 76px;
}
This uses the CSS3 :last-child pseudo-class to add a left margin to the final menu item. The value was calculated by halving the total width of each menu item including horizontal padding and margins (152 pixels).
A single-column layout will be maintained for tablets with a screen width ranging from 481 to 768 pixels (the upper limit is the width of an iPad in portrait mode). However, the navigation menu needs to be resized, and the inline images can be floated left and right so that the text flows around them. A background image will also be added to the sake <div> at the bottom of the page.
481px and the maximum to 768px. The <link> tag for the new style sheet needs to come after the existing one because the new styles will override those in basic.css. The two style sheets should be attached like this:<link href="styles/basic.css" rel="stylesheet" type="text/css">
<link href="styles/tablet.css" rel="stylesheet" type="text/css" media="only screen and (min-width: 481px) and (max-width: 768px)">
#wrapper {
max-width: 700px;
background-image: url(../images/basin_bg_tab.jpg);
}
This sets the maximum width of the wrapper <div> to 700px and substitutes a bigger version of the background image, which is also 700 pixels wide. There's no need to repeat the values inherited from basic.css, so the wrapper still fills the full width of the screen if it's smaller than 700 pixels. If it's wider, the inherited horizontal margins ensure that the <div> is centered.
#header h1 {
font-size: 363%; /* 58px */
padding-left: 0;
padding-top: 10px;
margin-bottom: 0px;
}
/* Main navigation */
#nav {
width: 660px;
height: 45px;
}
#nav li a {
width: 120px;
margin: 0 1px;
padding: 10px 5px;
}
#nav li:last-child a {
margin-left: 1px;
}
This sets the menu width to 660px and reduces the height. There are five menu items, so this creates 132 pixels of space for each one (120 pixels plus 1 pixel of horizontal margin and 5 pixels of horizontal padding on each side). The style in basic.css added a wide left margin to the final menu item to center it. This is no longer necessary, so the :last-child pseudo-class resets the left margin to the same as the other menu items.
/* Inline images */
.floatleft {
float: left;
margin: 3px 12px 3px 0;
}
.floatright {
float: right;
margin: 3px 0 3px 12px;
}
.floatleft, .floatright {
-webkit-box-shadow: 3px 3px 5px rgba(0,0,0,0.3);
-moz-box-shadow: 3px 3px 5px rgba(0,0,0,0.3);
box-shadow: 3px 3px 5px rgba(0,0,0,0.3);
}
The floatleft and floatright classes float the images in the relevant direction and add margins to separate them from the text. The left margin in floatleft is set to zero to keep the image flush with the text. Similarly, the right margin in floatright is set to zero. The final style block adds a drop shadow to the images, using the box-shadow property with the RGBa color format. The first three comma-separated values passed to rgba() set the color (black), and the final value specifies the alpha transparency at 30%.
sake <div> at the bottom of the page with the following rules:/* Background images for individual sections */
#sake {
background-position: 440px bottom;
background-repeat: no-repeat;
background-image: url(../images/sake_tab.jpg);
}
#sake p {
width: 400px;
}
The background-position property has two values, the first of which sets the horizontal position of the image 440 pixels from the left of the <div>. The paragraphs inside the <div> are set to a width of 400 pixels, leaving room for the background image to the side, as Figure 4 shows.
The navigation menu is 660 pixels wide, so you need separate rules for tablets with smaller screens. Rather than create another style sheet, it's more efficient to wrap the additional rules in an @media block and media query within tablet.css. The @media block also needs to make some adjustments to the the styles governing the inline images and font sizes.
@media block and media query:/* Alternate rules for screen widths in the range 481-680 px */
@media only screen and (min-width: 481px) and (max-width: 680px) {
#header h1 {
font-size: 300%; /* 48px */
padding-top: 7px;
}
/* Other rules go here */
}
All the rules that go inside this @media block are applied only to screens between 481 and 680 pixels wide. The first rule uses a slightly smaller font size for the page's main heading and reduces the top padding.
@media block as indicated by the comment in the preceding step.This set of rules changes the width and height of the navigation menu to accommodate two rows of menu items—three in the top row, and two in the bottom one. Giving the items a bottom margin of 2 pixels separates the rows. Because there are fewer items in the second row, the :nth-child() pseudo-class targets the fourth item and gives it a 66-pixel left margin to center the last two items, as shown in Figure 5.
#nav {
width: 396px;
height: 85px;
}
#nav li a {
margin-bottom: 2px;
}
#nav li:nth-child(4) a {
margin-left: 66px;
}
This set of rules changes the width and height of the navigation menu to accommodate two rows of menu items—three in the top row, and two in the bottom one. Giving the items a bottom margin of 2 pixels separates the rows. Because there are fewer items in the second row, the :nth-child() pseudo-class targets the fourth item and gives it a 66-pixel left margin to center the last two items, as shown in Figure 5.
Note: If you're not familiar with the :nth-child() pseudo-class, you can learn about it and other advanced CSS3 selectors in Getting to know your CSS selectors—Part 2.
@media block:.floatleft, .floatright {
float: none;
margin: 10px auto;
}
This overrides the earlier rule in tablet.css that floats the images. However, the width, max-width, and display properties are inherited from basic.css. As a result, inline images are centered in the same way as for the mobile phone layout.
sake <div>. Add the following rules inside the @media block to reposition the background image and resize the paragraphs accordingly:#sake {
background-position: 360px bottom;
}
#sake p {
width: 320px;
}
The completed @media block looks like this:
/* Alternate rules for screen widths in the range 481-680 px */
@media only screen and (min-width: 481px) and (max-width: 680px) {
#header h1 {
font-size: 300%;
padding-top:7px;
}
#nav {
width: 396px;
height: 85px;
}
#nav li a {
margin-bottom: 2px;
}
#nav li:nth-child(4) a {
margin-left: 66px;
}
.floatleft, .floatright {
float: none;
margin: 10px auto;
}
#sake {
background-position:360px bottom;
}
#sake p {
width:320px;
}
}
The styles in tablet.css set the maximum width of the wrapper <div> to 700 pixels. But the media query that attaches the style sheet to the page applies the styles to screens up to 768 pixels wide. To add a subtle design touch for bigger screens, create the following @media block at the bottom of tablet.css:
/* Border for screens wider than 702px */
@media only screen and (min-width: 702px) {
#wrapper {
border-left: #594431 solid 1px;
border-right: #594431 solid 1px;
}
}
This adds a border to the left and right sides of the wrapper <div>.
Creating the styles for the desktop version involves the same process as for tablets. You need to attach a style sheet with a media query targeted at screens wider than 768 pixels, and to override rules in basic.css. You don't need to worry about the styles in tablet.css because browsers that understand media queries will ignore them if the screen is wider than 768 pixels—and browsers that don't understand media queries will ignore tablet.css whatever the screen size.
Because IE 6–8 don't understand media queries, you need to attach the desktop styles to the page twice—once with a media query and the second time with an IE conditional comment.
min-width to 769px, and then wrapped in an IE conditional comment. The new style sheet needs to be attached after the <link> to basic.css. Otherwise, the styles won't be applied correctly. You should now have the following <link> tags in the <head> of the page:<link href="styles/basic.css" rel="stylesheet" type="text/css">
<link href="styles/tablet.css" rel="stylesheet" type="text/css" media="only screen and (min-width: 481px) and (max-width: 768px)">
<link href="styles/desktop.css" rel="stylesheet" type="text/css" media="only screen and (min-width: 769px)">
<!--[if lt IE 9 & !IEMobile]>
<link href="styles/desktop.css" rel="stylesheet" type="text/css">
<![endif]-->
Although you're attaching desktop.css to the page twice, it will be downloaded only once. The IE conditional comment will be ignored by all browsers except IE 6–8.
wrapper <div> and main header:#wrapper {
width: 980px;
background-image: url(../images/basin_bg.jpg);
border-left: #594431 solid 1px;
border-right: #594431 solid 1px;
}
#header h1 {
font-size: 413%; /* 66px */
padding-top: 0.25em;
padding-bottom: 0.25em;
}
The desktop layout uses a fixed-width design 980 pixels wide. These rules substitute a larger background image and increase the size of the main heading. The border properties are the same as used in the last @media block in tablet.css, but they need to be repeated here for larger screens to apply them.
/* Navigation menu */
#nav {
width: auto;
height: 45px;
margin: 0 auto 15px 35px;
}
#nav li a {
width: 160px;
padding: 10px;
margin: 0 1px;
}
#nav li:last-child a {
margin-left: 1px;
}
The :last-child pseudo-class removes the large left margin on the final menu item in the same way as in tablet.css.
content-medium class left and adding a wide left margin to the aside class like this:/* Main content and sidebar */
.content-medium, .aside {
margin: 20px;
}
.content-medium {
float: left;
width: 640px;
margin-top: 5px;
display: inline; /* Fixes double-margin bug in IE 6 & 7 */
}
.aside {
margin-left: 720px;
}
As the comment indicates, the display property of the floated column is set to inline. This fixes a bug in IE 6 and 7, which doubles the margin of an element if you float it to the same side as the margin. Fortunately, this has no effect on other browsers.
/* Inline images */
.floatleft {
float: left;
margin: 3px 12px 3px 0;
}
.floatright {
float: right;
margin: 3px 0 3px 12px;
}
/* Drop shadows */
.floatleft, .floatright, .content-medium, .aside {
-webkit-box-shadow: 3px 3px 5px rgba(0,0,0,0.3);
-moz-box-shadow: 3px 3px 5px rgba(0,0,0,0.3);
box-shadow: 3px 3px 5px rgba(0,0,0,0.3);
}
I could have added this style rule to basic.css to add a drop shadow to these elements on all devices. However, in my tests, drop shadows don't always look good on mobile screens.
sake <div>. Because the <div> has been converted into a sidebar, the image used for tablet.css is no longer appropriate. Add the following style block to desktop.css:/* Background images for individual sections */
#sake {
background-image: url(../images/sake.jpg);
background-repeat: no-repeat;
background-position: bottom;
padding-bottom: 140px;
}
This positions a different image at the bottom of the sidebar and adds a large amount of bottom padding to make room for it.
With these changes, the page should now look like Figure 6 in a desktop browser.
Although media queries are an effective way of serving the same HTML markup to different devices with styles suited to their screen width, you need to bear in mind that browsers normally download all stylesheets even if the screen width falls outside the range specified by a media query. This is so that the browser can respond immediately if the dimensions of the viewport are changed. Research by Greg Rewis reveals that, bizarrely, this happens even if there's no way the styles could be applied. For example, an iPad will download a style sheet even if the maximum width is set to 700 pixels.
Because of this, you might want to consider combining all the style rules in a single style sheet and wrapping those intended for specific screen widths in @media blocks like this:
/* Basic rules for all devices */
body {
margin: 0;
padding: 0;
. . .
}
/* More basic rules */
/* Rules for tablets */
@media only screen and (min-width: 481px) and (max-width: 768px) {
#wrapper {
max-width: 700px;
background-image: url(../images/basin_bg_tab.jpg);
}
}
/* Alternate rules for screen widths in the range 481-680 px */
@media only screen and (min-width: 481px) and (max-width: 680px) {
/* Alternate rules */
}
/* Border for screens wider than 702px */
@media only screen and (min-width: 702px) {
#wrapper {
border-left: #594431 solid 1px;
border-right: #594431 solid 1px;
}
}
/* Rules for desktops */
@media only screen and (min-width: 769px) {
#wrapper {
width: 980px;
background-image: url(../images/basin_bg.jpg);
}
/* More rules */
}
You can see this approach in action in dining-combined.html and combined.css in the sample files. The page displays in exactly the same way in phones, tablets, and desktops. You still need to attach desktop.css in an IE conditional comment for IE6–8.
Combining the style rules in a single file reduces the number of server requests, so should result in a marginally faster experience on a mobile device. The downside is that it results in a much longer style sheet, which can be more difficult to maintain.
This two-part tutorial series has covered the theory and practice of responsive web design with media queries, which allow you to serve styles optimized for different devices depending on their characteristics. Media queries are supported by all modern browsers and mobile devices. They're not supported by IE 6–8, but you can easily get around this limitation by creating basic styles that are used by all browsers, and using media queries to serve specific styles to more modern browsers. You can also use an IE conditional comment to attach a dedicated style sheet for older version of IE.
You should find the following resources helpful in learning more about media queries and designing for mobile:
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.
Tutorials and samples |
Dreamweaver user forum |
More |
| 04/23/2012 | Resolution/Compatibility/liquid layout |
|---|---|
| 04/20/2012 | using local/testing server with cs5 inserting images look fine in the split screen but do not show |
| 04/18/2012 | Ap Div help |
| 04/23/2012 | Updating |
Dreamweaver Cookbook |
More |