HTML is an inherently fluid medium. Text and containers expand horizontally and vertically to use the available space. That fluidity made complex designs more difficult, so by the turn of the millennium, many sites adopted a fixed-width based on popular screen sizes.
The process remained viable as screen sizes kept increasing from 800×600 to 1024×768 and beyond. However, the rise of smartphones and the iPhone launch in 2007 reversed that trend. Today, more than half of users access web pages on a smaller mobile device.
Note: Technically, smartphones often have a higher resolution than many monitors, but individual pixels become invisible. An iPhone 11 Max translates its 2688 x 1242 hardware resolution to a more practical 896 × 414 logical resolution. Each logical pixel maps to a grid of 3×3 real pixels, which enables smoother fonts and increased image detail.
The initial workaround was two sites: one for desktop and one for mobile, often with user agent sniffing to redirect as necessary. This rapidly became impractical as the variety of devices grew exponentially.
Finally, the term Responsive Web Design (RWD) was devised by Ethan Marcotte in 2010. The technique allowed the same site to work on any device regardless of screen size or viewport dimensions.
How Does RWD Work?
There’s no single RWD approach or technology.
First, you must determine how a site design will react to differently sized displays. This is a challenge, and many of the first RWD sites took an existing desktop layout and removed sections as screen dimensions reduced.
A better technique was mobile first. It started with a linear mobile view, which worked on all devices then rearranged or adapted content as more space and supported browser features became available. More recently, many sites have adopted simpler layouts, where the mobile and desktop experience is mostly similar.
A typical example of RWD in action is the hamburger menu. Those on smaller screens can click an icon to view navigation links, while those with larger screens may see all the options in a horizontal list.
The following sections provide a number of technical implementation options.
viewport Meta Tag
Regardless of any RWD technique, the following tag must be set in your HTML
<meta name="viewport" content="width=device-width,initial-scale=1">
width=device-width setting ensures mobile browsers scale logical CSS pixels to the width of the screen. Without this, the browser will presume it’s rendering a desktop site and scale it accordingly so it can be panned and zoomed.
Media queries were the primary basis of the first RWD sites. They allow CSS to target specific ranges of viewport dimension. For example:
/* styles applied to all views */ p font-size: 1rem; /* styles applied to viewports with a width between 900px and 1200px */ @media (min-width: 900px) and (max-width: 1200px) p font-size: 1.5rem;
Media queries are still used, although less explicit options are now available.
<picture> element uses media query syntax to control which image is displayed from a choice of
<source> options. This is typically used for art direction in order to display a suitable image for device viewport. For example:
<picture> <!-- image shown when viewport width is greater than the height --> <source media="(min-aspect-ratio:1/1)" alt="landscape" /> <!-- default image --> <img src="http://www.sitepoint.com/portrait.jpg" alt="portrait" /> </picture>
CSS Viewport Units
vh CSS units represent 1% of the viewport’s width and height respectively.
vmin is 1% of the smallest dimension, and
vmax is 1% of the largest dimension.
These permit RWD flexibility, especially when used in conjunction with
calc. For example:
/* font size increases with viewport width */ p font-size: 1rem + 0.5vw;
CSS multi-column layouts provide a way to create multiple text columns as the dimensions of a container increase. For example:
/* columns must be a minimum width of 12rem with a gap of 2rem between each */ .container columns: 12rem auto; column-gap: 2rem;
CSS Flexbox and Grid
CSS Flexbox and CSS Grid provide modern techniques which lay out child elements depending on their content and the space available. The primary difference:
- Flexbox is used for one-dimensional layouts. Elements can wrap (or not) to the next line as necessary so columns may not line up.
- Grid is for two-dimensional layouts, usually with identifiable rows and columns.
Either can be used to create an intrinsic layout (a term devised by Jen Simmons). In essence, elements are sized according to the viewport dimensions without the need for media queries. For example:
/* Child elements will be at least 20rem and fill the row. Displays smaller than 20rem will have elements sized to 1fr (100% of the available width). A 1rem gap will always surround elements. */ .grid-container display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); grid-gap: 1rem;
// get viewport width and height const vw = window.innerWidth, vh = window.innerHeight;
Similarly, the dimensions of an individual element can be examined with offsetWidth and offsetHeight, although the getBoundingClientRect() method can return more information including fractions of a pixel:
const element = document.getElementById('myelement'), rect = element.getBoundingClientRect(), ew = rect.width, eh = rect.height;
Window and element dimensions can change as a device is rotated or the browser window is resized. The
matchMedia API can parse CSS media queries and trigger change events:
// media query const mql = window.matchMedia('(min-width: 600px)'); // initial check mqTest(mql); // call mqTest when media query changes mql.addListener(mqTest); // media query testing function function mqTest(e) if (e.matches) console.log('viewport is at least 600px width'); else console.log('viewport is less than 600px width');
The RWD technologies above all offer good browser support. The most recent option — CSS Grid — is supported by almost 95% of browsers in use today. However, it’s still necessary to test your site across a range of devices, resolutions, and browsers…
How to Test Responsive Web Design Cross-Browser Compatibility