Advertisement

Flexible, Mobile-First Layouts with CSS3

by

Some experts are projecting mobile devices to become the dominant medium for web browsing within five years, overtaking browsing on desktop computers. Regardless of how accurate this projection turns out to be, it is clear that formatting websites for mobile-friendly viewing needs to become a staple of web design and development. There are many ways to accomplish this, of course. However, CSS3 provides a fairly rich toolset for mobile-friendly formatting, relying on the client's browser capabilities instead of back-end templating.


Step 1. Think Ahead

There are a few issues that should be thought about before diving right into styling a layout.

Mobile Web Browsing

First, what should one keep in minds when designing for mobile browsers? Well, here are a few things...

  1. Limit HTTP requests: data transfer over 3G can be quite taxing. This includes limiting images where possible (from the CSS, for example).
  2. Varying screen sizes: Mobile devices tend to hover around the 320-480 pixel screen widths but can vary greatly depending on the device. So, predefining widths in the CSS is generally a bad idea for things like paragraphs and DIVs.
  3. Optimize for a subset: There are TONS of mobile devices, browsers, OS's, etc. Try to focus your testing on what you assume to be the most important. For me, this includes iPhone, iPad, Blackberry, and Android. This list should also include Windows Mobile but I simply do not have access to a Windows Mobile device.
  4. Hover must die: Okay, that's a little dramatic. However, touchscreens don't tend to support hover. So, when building menus, don't hide things behind hover events. Hover should only be used to enhance some effects (like color changes) not deliver important content (like drop-down menus).

"The overall point is to know ahead of time what your site is likely to look like in various browsers before seeing it."

Browser Support (on Desktops)

Secondly, keep browser support in mind. The proverbial "elephant in the room" is IE, of course. Good news, though! As it turns out, websites don't really need to look exactly the same in every browser. As long as it doesn't interfere with the content of the website, generally a browser not capable of processing CSS3 will still provide a more-than-acceptable experience. The overall point is to know ahead of time what your site is likely to look like in various browsers before seeing it.


Step 2. The HTML

The Body

"Keep the markup simple and clean."

Not only do we want to produce valid HTML, we also want to simplify it as much as possible. While it has always been a good idea to keep HTML streamlined and free of unnecessary DIVs, it is even more important now with the rise in mobile web browsing. Also, a lot of the effects that required 7 nested DIV tags can now be reproduced with a little CSS3.

Since this is not an HTML5 tutorial, I'm going to stick with XHTML strict. With that in mind, a lot of the markup here can be made even cleaner using some HTML5 elements. So, here's some HTML for a typical layout. We've got a page containing a header, footer, content area, and sidebar.

<body>
  <div class='pg'>
    <div class='head'>
      <h1><a href='#'>My Blog</a></h1>
    </div>
    
    <div class='pg-main'>
      
      <div class='entries'>
        <h2><a href='#'>An Entry About Something</a></h2>
        <p class='preview'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem elit, suscipit tempus pretium eget, varius ut erat. Donec lobortis est sit amet felis pellentesque vel egestas sapien iaculis. Maecenas eget quam nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>
        <p>Mauris nunc metus, pellentesque eget porta ut, facilisis ut metus. Etiam dignissim egestas semper. Aliquam tincidunt tortor non mi ultricies quis interdum quam scelerisque. Aenean risus libero, aliquam vel rhoncus sed, elementum eu leo. Pellentesque vitae ante urna, ut rhoncus sapien. In iaculis tristique lobortis. Nulla feugiat elit at odio dictum dignissim. Fusce tristique lacus nec justo porttitor egestas. Etiam vitae arcu risus, at interdum lacus. Ut dignissim, dui eu imperdiet accumsan, dui mauris hendrerit leo, vel fringilla mi ipsum vitae orci. Nulla libero quam, euismod eget rutrum sed, ullamcorper vitae felis. Mauris aliquam dignissim interdum. Sed sagittis blandit urna, sit amet pellentesque lorem egestas sed. Nam adipiscing, lorem non ornare volutpat, turpis ante sagittis elit, ac hendrerit arcu nunc ut est. Vivamus at arcu felis, eget porta odio.</p>
        <hr/>
        
        <h2><a href='#'>An Entry About Something Else</a></h2>
        <p class='preview'>Maecenas vitae metus ac est lobortis tincidunt laoreet et enim. Maecenas purus magna, condimentum at mattis vel, pellentesque sed nibh. Curabitur scelerisque pulvinar ante, quis pellentesque enim faucibus ac. Etiam suscipit fringilla mi, et tempor mauris convallis sit amet. Phasellus eros dolor, tempus at pulvinar ac, mollis sed eros. Morbi viverra pellentesque tellus, et tincidunt lectus fringilla non. Donec quis turpis in nunc venenatis rhoncus eget eget felis. Donec ut malesuada lorem. </p>
        <p>Vivamus placerat bibendum placerat. Nullam pretium, nisl vitae sodales rhoncus, ante massa ultricies purus, ac blandit ante felis sit amet erat. Nullam cursus ornare placerat. Sed accumsan malesuada iaculis. Proin suscipit ultrices mattis. Sed semper facilisis est in luctus. Etiam et quam a ligula laoreet iaculis vel quis leo. Etiam et purus a quam vehicula feugiat. Praesent ac ligula mi. Donec ut sapien in nunc sagittis interdum ac a tortor.</p>
        <hr/>
        
        <h2><a href='#'>A Third Entry</a></h2>
        <p class='preview'>Maecenas vitae metus ac est lobortis tincidunt laoreet et enim. Maecenas purus magna, condimentum at mattis vel, pellentesque sed nibh. Curabitur scelerisque pulvinar ante, quis pellentesque enim faucibus ac. Etiam suscipit fringilla mi, et tempor mauris convallis sit amet. Phasellus eros dolor, tempus at pulvinar ac, mollis sed eros. Morbi viverra pellentesque tellus, et tincidunt lectus fringilla non. Donec quis turpis in nunc venenatis rhoncus eget eget felis. Donec ut malesuada lorem. </p>
        <p>Vivamus placerat bibendum placerat. Nullam pretium, nisl vitae sodales rhoncus, ante massa ultricies purus, ac blandit ante felis sit amet erat. Nullam cursus ornare placerat. Sed accumsan malesuada iaculis. Proin suscipit ultrices mattis. Sed semper facilisis est in luctus. Etiam et quam a ligula laoreet iaculis vel quis leo. Etiam et purus a quam vehicula feugiat. Praesent ac ligula mi. Donec ut sapien in nunc sagittis interdum ac a tortor.</p>
      </div>
      
      <div class='sidebar'>
        <h2 class='not-there'>Blog Menu</h2>
        <h3 class='subscribe'>Subscribe</h3>
        <ul class='subscribe'>
          <li><a href='#'>RSS</a></li>
        </ul>
        <h3>Social</h3>
        <ul>
          <li><a href='#'>Facebook</a></li>
          <li><a href='#'>Twitter</a></li>
        </ul>
        <h3>Categories</h3>
        <ul>
          <li><a href='#'>Something</a></li>
          <li><a href='#'>Nothing</a></li>
          <li><a href='#'>All Things</a></li>
          <li><a href='#'>No Things</a></li>
        </ul>
        <h3>Archives</h3>
        <ul>
          <li><a href='#'>June 2010</a></li>
          <li><a href='#'>May 2010</a></li>
          <li><a href='#'>April 2010</a></li>
          <li><a href='#'>March 2010</a></li>
        </ul>
      </div>
    </div>
    
    <div class='foot'>
      <p>© No one in particular 2010</p>
    </div>
    
  </div>
</body>

As you can see, it's a pretty simple and typical blog layout with a few article and some menu options in the sidebar.

Viewport Metadata

In our head element, we will put all the typical pieces like stylesheets, content type, title, etc. However, there is one extra piece that we will include to smooth out mobile browsers.

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>

This is a little metadata tag, suggested by Apple, to help iPhones render a page. It essentially auto-fits the page to the viewport and prevents zooming. Several other mobile browsers support this too, including Blackberry's native browser. In my testing, keeping this tag doesn't harm desktop browsing whatsoever. So, let's just stick it in the head and forget about it.

Thinking About the Layout

This particular tutorial will focus on taking the above HTML and styling it into two layouts. One layout will be targeted at mobile browsing and one at desktop browsing. In practice, it will probably be useful to break such a layout into several different "targets." However, for the sake of this simplicity, this tutorial will only focus on those two.


Step 3. The Mobile Styling

Disclaimer

The purpose of this tutorial is not to talk about rich typography or brilliant graphical design. So, the presentation here is kept very simple. What is important is the thought process that drives the stylesheet.

The Approach

The main thrust of all of this is to think about designing a mobile layout first. The reason for this is that its likely that whatever you come up with for a mobile devices will also work on a desktop. Then, instead of ending up with a thrown-together mobile layout and a brilliant desktop layout, you'll start with a brilliant mobile layout and enhance it for desktop. This will also make sure that your website doesn't lose its audience as the world goes mobile.

The Inspiration

This approach is inspired by Luke Wroblewski who spoke at An Event Apart in Boston this year. His presentation was centered around thinking "Mobile First".

While this tutorial does not capture his presentation in any sort of entirety, one piece of it hit home more than the rest (for me). The current trend is design is to work on the desktop version of a website first, then strip it down and throw together a mobile website if there is time. Instead, we should start to design for the mobile world first, then change that design as desired for the desktop. The rational is essentially one of progressive enhancement... if the design is useful on mobile, it will work on desktop also. The reverse, however, is not usually true.

Some CSS

So, let's think about mobile browsing for a moment. Long scrolling screens are difficult to deal with. So, let's take the blog menu list items and make them easier to deal with.

.sidebar ul{
  border-left:solid 1px #ccc;
  padding:0 0 0 5px;
}
.sidebar ul li{
  display:inline;
  padding:0 5px 0 0px;
  border-right:solid 1px #ccc;
}

That should give us a nice, clean-looking menu with some pipe-looking separators. You'll notice that I didn't choose to move the menu away from the bottom of the screen. Menus at the bottom can be useful in mobile browsing. If you think about scrolling through a webpage, when you get to the bottom you'd have to scroll all the way back up in order to go somewhere else. Depending on the device, scrolling can be somewhat burdensome. There are pros and cons to this method but in this case, I think it works well.

However, I would like to move the RSS to the top banner, so let's do that too.

h3.subscribe{
  display:none;
}
.sidebar ul.subscribe{
  position:absolute;
  top:25px;
  right:10px;
  border:none;
  color:#fff;
}
.sidebar ul.subscribe li{
  border:none;
}

Aside from that, the rest is pretty much just some font-sizing of the heading elements and coloring of the anchors. For the purposes of this tutorial, I included a CSS-reset at the top of the sheet just for simplicity. The full CSS sheet can be found in the source code for this tutorial.

As you can see, there isn't really anything special about the mobile styling when approaching design from a mobile-first angle. Instead of thinking, "what do I want this to look like on my screen," you think "how can I use styling to make this most useful on a mobile device."


Step 4. The Desktop Styling

Media Query

In case you haven't guessed it, this whole thing is going to end up being driven by CSS3 media query. In case you aren't familiar, media query is a way for the stylesheet to flip declarations on and off based on various conditions. One such condition, and the topic of this sheet, is screen dimensions.

Again, the full CSS can be found in the source attached to this tutorial but let's examine this for a moment:

.pg{
  width:800px;
  margin:0 auto;
}

In this case, we don't really want an 800px page width unless we are sure the user's browser window is at least 800px wide. Otherwise, we will end up with one of those annoying horizontal scrollbars.

So, we're going to wrap that declaration (along with several others) inside a media query.

@media all and (min-width:800px){
  .pg{
    width:800px;
    margin:0 auto;
  }
}

That reads pretty easily, right? The "all" refers to "use this style for all types of media." There are other things that can go here, such as "print" for printer but there isn't a lot of consistent support. Anyhow, "all" will work just fine for this.

"Override" Previous Styles

We will put a lot of other stuff inside this media query too but the important thing to remember is to essentially override previous styles and add some new ones to achieve the new layout. This will allow browsers that do not support media query to simply fall back on the original styling. Even though they are optimized for mobile, there's nothing wrong with displaying that layout on a less-capable desktop browser.

For example, we'll move that sidebar out of the bottom and make the lists look like lists again.

@media all and (min-width:800px){
  .sidebar ul{
    border:none;
    padding:0;
  }
  .sidebar ul li{
    display:block;
    padding:0;
    border:none;
  }
  h3.subscribe{
    display:block;
  }
  .sidebar ul.subscribe{
    position:static;
    top:auto;
    right:auto;
    border:inherit;
    color:inherit;
  }
  .sidebar ul.subscribe li{
    border:inherit;
  }
}

That will put the sidebar off to the left (combined with a couple other floats found in the stylesheet) and place the subscribe back where it belongs for people browsing the site in atleast 800px width.

So, if you open up the source in a browser and resize it horizontally, you'll be able to watch the layout flip between the desktop format and the mobile-friendly format

You may be asking yourself, why 800px? Is there anything magical about an 800px width? No. In fact, I would argue that it is too wide. With the introduction of "snap" in Windows 7, I would argue that 600px should be the new target width for a desktop website. That way, the browser can be "snapped" to the right or left on a 1280px screen and still maintain its layout. However, this is really neither here nor there. Just be aware that 800px isn't anything special.

Browser Support

Important: The website will be styled as the mobile version in IE8 and below. Is this okay? I think so. Also, I've done this before and so far no one has arrested me. Plus, media query support is promised in IE9.


Step 5. Alternative Methods

This isn't the only way to accomplish this. However, the purpose of this tutorial was to show a very practical use for media query and present some ideas of mobile layouts based on CSS only.

That said, here's a few other ways to put together a mobile layout...

  • Serve different templates: If you have access to the templates for the site, a themeing system can usually be put in place where the requesting browser is detected, then a different HTML template is served based on the type of browser (mobile or not). This is usually accompanied by a separate set of CSS as well.
  • Subdomains: m., mobile., and .mobi tend to be the standards here, where an entirely different website is served. That said, it's usually the same as "serve different templates" to avoid content duplication.
  • Fluid layouts: One can also make their layout completely fluid such that no matter what size the browser window, the content adjusts itself. In fact, the "mobile" stylesheet in this tutorial is a fluid layout. The nice thing about using media queries is that you can reduce the background-images and produce fewer HTTP requests.

There are likely several other methods of handling mobile web browsing but often it will come down to a hybrid of some sort. However, whether it's a fluid layout with certain "kick" points based on media query or a subdomain redirection serving different templates, the important thing is begin planning mobile layouts ahead of time, so that your websites don't become increasingly less useful over the next 5 years.

Advertisement