Notes from the Responsive Design trenches
Lately a lot of companies have been asking for websites built along the principles of ‘Responsive Design’. I had to give up on building a responsive website in early 2012 due to lack of time, but in January 2013 I got another chance. (Side-note: both websites are on intranets, so I cannot show them to you.)
Responsive Design is designing a website in such a way that it rearranges itself to look good both on large screens (typically desktop-PCs) and small screens (typically mobile phones).
The text below is first and foremost a memo to self, but it can also be used as an addition to the ultimate Responsive Design primer, the A List Apart article by Ethan Marcotte that started it all. I will explain Responsive Design in a bit more detail below, but if you really want to know what it is about I suggest you read the A List Apart piece.
Although Responsive Design is pretty straightforward to anybody who has done even the most trivial things with Cascading Style Sheets, it is typically used in a wider context that can make things complicated. Hence the need for this intermediate level article.
This is going to be a longish piece, so I am going to present a bullet-point abstract first:
- Mobile is getting more and more popular.
- Current website designs do not work well on mobile devices.
- Responsive Design lets your website switch between designs.
- Use CSS media-queries to switch between lay-outs for narrow/wide browsers.
- Assume wide browser means desktop, and narrow browser means mobile.
- Assume mobile is the default (this is called: mobile first).
- Build your desktop/wide design on top of your mobile/narrow design.
- Assume Internet Explorer is the second default.
- Content order matters.
- Mobile browsers actually render pages differently.
- Landscape and portrait orientation differ in rendering.
- Tablets are a third way.
Currently 15% of all visits to websites are made on mobile devices. Clients have decided that this is important. (When in the past a far greater percentage of visitors used different web browsers from what clients used, these numbers were not given much weight. I suspect clients own mobile phones. This would explain the sudden rush to design for 15% of the market.)
Reponsive Design is a type of web design that allows for different viewing experiences in different web browsing contexts. The design responds as it were to the context it is viewed in. Typically this means creating different designs for both mobile phone browsers and desktop PC browsers, which in turn means that I as a front-end web developer get more money to implement these multiple designs.
Responsive Design is an offshoot of Liquid Design, which tried to cater to variations in display size before mobile had any traction.
So you have got a mobile design, implemented using one stylesheet, and you’ve got a desktop design implemented as changes to this stylesheet (the ‘why’ of this will be explained later on). How do you cascade the two stylesheets in such a way that the desktop device knows which stylesheet to load and the mobile device knows which stylesheet to ignore?
CSS 2 lets you load stylesheets based on the media you are experiencing a website on, using so called ‘media styles’. There is a media style for ‘handheld’, but that is barely supported as far as I can tell. CSS 3 extends media types by ‘media queries’, which let you ask questions of the browser such as ‘how wide is your viewport?’, ‘are you in colour or monochrome?’ and ‘what is your orientation, portrait or landscape?’
A media type looks like:
<link rel="stylesheet" type="text/css" media="screen" href="main.css">
And a media type with a media query looks like:
<link rel="stylesheet" type="text/css" media="screen and (min-width: 481px)" href="desktop.css">
(Note that ‘min-width’ here means ‘current width is greater than’.)
Media queries can also be used inside stylesheets, but that seemed to invite confusion. I’d only do it that way if I were using a CSS-extension such as SASS.
Sniffing mobile devices
There are undoubtedly many ways to sniff out which browser you are using on which device, but the Responsive Design way is to use media queries to find out the current width of the viewport.
So that’s it. You don’t find out what kind of device you are using, instead you find out how wide the part of your web browser is that shows you a web page. Designs using two or three columns are defined in the ‘desktop’ stylesheet, designs using one or two columns in the mobile stylesheet.
Your default stylesheet, the one that only uses media styles but not media queries, should be the one that caters exclusively to the lowest common denominator. Typically this means that this stylesheet caters to mobile devices.
The reasoning behind this is that not every platform or every browser may support media queries. If these platforms are mobile, they will still get a reasonable web page lay-out to work with. (If they are desktop, they get the same reasonable web page lay-out, but the user may have to make the browser window narrower to keep the text legible.)
A practical consequence is that you will probably want to build the mobile style first. That way you can focus on one style, and can later build the second style (typically: desktop) on top of the first.
Making the mobile design the default design is called ‘mobile first’.
A second ‘default’ would be to make sure from the start everything works well in Microsoft Internet Explorer. Responsive Design seems to go hand in hand with using grid systems and HTML5/CSS3, and the latter are not well-supported by common versions (6, 7 and 8) of this most popular of web browsers. Going full hog with Responsive Design means little if this causes you to ignore the majority of your visitors.
There is an even deeper default than assuming you will be viewing content on either a broken browser or a narrow browser, and that is the assumption that your browser doesn’t support CSS at all, or in a very limited way.
This is an old assumption, from a long time before Responsive Design, and still valid.
Your webpage should be viewable even if all the visitor’s browser has to work with is the raw HTML. Your unstyled HTML should be laid out in such a fashion that the most important content comes first. Typically this will be the content that the visitor came to the web page for, the content unique to the page.
This is called ‘content first source order’.
There is unfortunately no one way of determining what content is the most important and I am not even sure this can be determined before a site has gone live (unless you know the content beforehand and have a very good reason to assume it won’t change during the page’s lifetime). This means you will have to make an educated guess.
If you are running a website that relies heavily on ad generated revenue, you are not going to be very happy with Responsive Design, as most of your ads will be relegated to a position on the page that will hardly ever be viewed. I am sure there are more people working on ‘solving’ this ‘problem’ right now than there are flees on a dog.
Mobile browser, you did it again
There doesn’t seem to be a standard width that counts as the maximum width for mobile or the minimum width for desktop. Some mobile devices have a viewport of 480 pixels wide. That would be a good minimum; if max-width: 480, you can assume mobile.
In the olden days websites were made to fit 800 pixel wide screens, but most screens are much wider these days, with 1024 pixels (minus the browser chrome) being the minimum. This means desktop starts around 960 pixels.
Between 480 pixels and 960 pixels is a pretty wide gap.
I don’t know what the ideal width is to switch between the mobile and the desktop style. Some things for your consideration are:
- A single content column is going to be about 600-700 pixels wide. This is from experience; the ideal content column width mostly seems to have to do with the amount of words you can fit on a single line while still maintaining readability.
- If a visitor makes their web browser window narrower, at some point your site will switch to its mobile theme. From which point on do you want to avoid this to happen?
Mobile devices render webpages to a virtual viewport first, and the width of that virtual viewport is currently known to be somewhere around 900 pixels. They then scale the rendered virtual viewport up or down to fit the real viewport.
This process is meaningful to web developers because mobile devices can be used in two different orientations, landscape and portrait. Text in landscape orientiation looks significantly chunkier than text in portrait orientation.
Personally this does not matter to me; I assume people who use landscape are aware of the effect. Clients and their designers may feel the need though to second guess their visitors—as they do with Print buttons, Back buttons and so on—and request a separate landscape style to be developed.
There are a number of ways to take care of the differences between landscape and portrait. One is to use a second media query for mobile landscape (desktop is typically large enough for orientation not to be a problem) and create a style for that option. This means you are suddenly styling three websites instead of two, which means even more money for you.
A simpler solution is to use the media query, but only change font-size for landscape.
Tablet resolutions are typically large enough to trigger the desktop style sheet, but unfortanetely tablets behave like really large mobile phones. You can trigger the mobile portrait theme if your viewport is narrower than the landscape width of the widest tablet, but that means many desktop users will suddenly get to see your portrait theme too.
If you have implemented your portrait theme to use a smaller font than the landscape theme, this can make your desktop website illegible. (Your desktop browser, unlike your tablet browser, does not work with a scaled up virtual viewport, resulting in tiny text for whoever prefers their browser windows to be taller than they are wide.)
I have yet to find an elegant solution for this.
I have not linked to things like the respond.js and html5.js because you will probably end up using one of the many responsive frameworks that are out there anyway, and these frameworks tend to include those scripts, or come with their own solutions. I myself work a lot with Drupal and WordPress, and both systems have decent responsive base themes available to them. If you also use these platforms, you may wish to check out Zen for Drupal or Twenty Twelve for WordPress.