Saturday, November 19, 2011

CSS3 Media Queries

Need of Media Queries

Gone were those days when designers had the liberty to design or layout a web page for fixed/minimum resolution as most people would just use their desktop for browsing the web. In this mobile/tablet era, we cannot assume that the desktop would be the only user agent. A large number of users today use their “smartphones” or “tablets” for browsing the web and so it becomes crucial that your website looks as good when viewed from such a device.

Many websites today have different version of websites, one each for desktop and mobile. By detecting the user agent when the user visits the website for the first time, it can redirect them to the mobile version if he is browsing the web using his smartphone. But this solution comes with its own headache of maintaining separate presentation layers for separate mediums and fixing bugs in both !!

This is where Media Queries come into picture. They provide an elegant solution to the problem by providing the ability to switch the CSS based on the user agent or device’s width or orientation. In short, they make your web design adaptive and responsive to change.

Wow, that’s new !!

Not really !!. They were very much a part of CSS2 and HTML4 specification where they were limited to ‘print’ and ‘screen’ only (meaning using CSS2, you can only specify different style-sheets for rendering and printing a web page). But with CSS3, more media types are supported and different style-sheets can be applied based on

  • device-width and height
  • viewport-width and height
  • orientation
  • aspect-ratio
  • device aspect-ratio
  • resolution etc..

Without wasting more time, lets see an example. We will create a layout for a widescreen (desktop layout) and using media queries, we will change the layout and color the markup when we resize the browser (to simulate tablet and mobile size)

wideLayout Layout for Wide Screen

tabletLayout Layout for Tablet or Not So Wide Screen

phoneLayout Layout for a Mobile Device

In this lame-example, we have simple created a three-column layout for a widescreen or desktop, and changed it to a two-column layout for a tablet and coloured the sidebar blue (not to show my design skills of course, but to distinguish between the layouts) and then a stacked layout for a mobile device with red coloured div. and All this by simply switching the CSS for the same HTML file. All the code is explained below:

index.html

<!DOCTYPE HTML>
<head>

<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8" />
<link media="only screen and (min-width: 800px)" rel="stylesheet" href="css/desktop.css" />
<link media="only screen and (min-width: 400px) and (max-width: 800px)" rel="stylesheet" href="css/tablet.css" />
<link media="only screen and (max-width: 400px)" rel="stylesheet" href="css/phone.css" />

</head>
<body>

<div id="header"> Header </div>
<div id="sideBar"> Side Bar </div>
<div id="content"> Content </div>
<div id="extra"> Extra </div>

</body>
</html>

desktop.css

div
{
border: 1px solid;
}
body
{
width:1000px;
margin: auto;
}
#sideBar
{
float:left;
width:250px;
height:600px;
}
#content
{
float:left;
width:448px;
height:600px;
}
#extra
{
margin-left:700px;
width:296px;
height:600px;
}

tablet.css

div
{
border: 1px solid;
}
body
{
width:700px;
margin: auto;
}
#sideBar
{
float:left;
width:200px;
height:600px;
background-color:blue;
}
#content
{
margin-left:202px;
height:600px;
}
#extra
{
clear:both;
}

phone.css

div
{
border: 1px solid;
}
body
{
width:350px;
margin: auto;
}
#sideBar
{
height:100px;
}
#content
{
height:100px;
background-color:red;
}
#extra
{
height:100px;
}

This HTML files simple contains 4 Div’s in the body and head contains links to some style-sheets with media queries using link tag, lets see what these queries mean

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

It can be read as include the “desktop.css” file if and only if the user agent has a screen and the minimum-width of the device is 800 pixels. Similarly,

<link rel="stylesheet" href="css/tablet.css" media="only screen and (min-width: 400px) and (max-width: 800px)" />

it says that include the “tablet.css” when the user agent has a screen and its width is between 400 to 800 pixels, something that we think should be suitable for a tablet.

<link rel="stylesheet" href="css/phone.css" media="only screen and (max-width: 400px)" />

On the same lines, in this rule, we ask the browser to use “phone.css” if the width is less than 400 pixels. Note that these rules are mutually exclusive because we want them to be like so. Each rule must evaluate to a boolean value and depending on that value, the CSS file is downloaded to the client machine and is used for rendering the HTML markup.

You can also embed the media-query inline in the CSS as follows:

<style type="text/css">       
@media only screen and (max-width: 400px)
{
#content
{
height:100px;
background-color:red;
}
}
</style>

Orientation

Similarly the CSS for phone.css can be broken down into two parts: phonePortrait.css and phoneLandscape.css by applying the following media queries

<link media="only screen and (max-width=400px) and (orientation=portrait)" rel="stylesheet" href="phonePortrait.css" />
<link media="only screen and (max-width=400px) and (orientation=landscape)" rel="stylesheet" href="phoneLandscape.css" />

Width Vs Device-width

"width" refers to the width of the viewport width (or the browser’s width) whereas the "device-width" refers to the width of the device (for desktop users, it is the dimensions of the monitor used, for mobile users, it is the dimensions of the smartphone used). Common sense says we should use device as the browser size may be less than the dimension of the device (esp on desktop)

The complication comes in case of mobiles, where the likes of iDevices and Androids incorrectly reports the viewport-width and also neglects the orientation of the device while calculating the width. To make things work, Apple introduced a new meta-tag: Viewport which is usually used as follows:

<meta name="viewport" content="width=device-width, initial-scale=1">

This instructs the device to report the viewport width equal to the actual width of the device and also take orientation into account while making that calculation. More details can be read here.

Browser Support

Surprisingly, majority of browsers do support media queries but for those who don’t, a JavaScript workaround can be applied which based on the width of the browser, changes the link’s href value to point to the correct CSS file.

Spec

A lot more can be achieved by media queries, all of which has been laid out in the spec here.

Disclaimer

The HTML & CSS used above in the example are merely for demonstrating the power of Media Queries and hence have been intentionally kept lame.

1 comment:

Harjeet Singh said...

css media queries make the design responsive but not better what we want.we need to use the bootstrap.how to design with css