Advertisement

Building a Mobile First Responsive WordPress Theme

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

Theme building is at the heart of WordPress. It's the technique you use to build bespoke websites for yourself or your clients and it's a vital skill for anyone wanting to design and develop with WordPress.

More and more WordPress themes now are responsive - they use CSS media queries to adapt to different screen widths, adjusting the layout and making design and interface changes to make any site created using the theme easier to read and interact with on a range of devices and screen sizes.

In this tutorial I'm going to show you how to build a Mobile First WordPress theme, which starts with the styling for the smallest screens and works upwards.


What You'll Need for This Tutorial

In this tutorial I'm going to take a WordPress theme with minimal styling and then style it to make it mobile first. The eventual design will be very simple - the idea is to cover the building blocks of the content and layout and you can add your own design goodies afterwards if you want.

To follow the steps in this tutorial you'll need the following:

  • A text or code editor. If you don't already have one, both TextWrangler and Kompozer are free.
  • If you're developing locally, MAMP, WAMP or XAMPP so that you can run PHP and MySQL and work locally using WordPress.
  • If you're developing remotely, an FTP client such as FileZilla.
  • A local WordPress installation (or a remote one you're happy to use for testing)

I'm assuming that you're already familiar with installing and working with WordPress. I'll work on a remote WordPress installation
and provide links as I go along.

Unless you have your own theme you're working on, you'll also need the starting code for the tutorial. You can see my theme at http://rachelmccollin.co.uk/nettuts-wpresponsive-tutorial/ and download the code for the theme at various stages of its development from xxx [to be added based on nettuts+ downloads system].


Before We Start: What's Mobile First?

Mobile First is a term which was first coined by Luke Wroblewski. It refers to the
strategy of turning the way we design websites and themes on its head. Instead of starting with a desktop design and then adjusting it for mobile devices, we work in the other direction - we start by designing and coding for mobile devices and then add what's needed for larger screens. This has a few advantages:

  • It's faster - content or styling which isn't needed on small screens isn't sent to them. This can be faster than just hiding or overriding it.
  • It changes the way we plan content - by focusing on small screens, we focus on what's really important rather than on what we're including because w have the space. Designing in this way can have a drastic impact on the eventual desktop design.

1. Our Starting Theme

The starting theme has minimal styling applied to it, and no layout styling at all yet - that will be added as we work through the tutorial.

The elements which the theme includes are shown below:

01-theme-doctree.jpg

At present, the theme looks like this on a smartphone (i.e. at 320 x 480px screen size):

02-startingtheme-320px-screen.png

As I haven't applied any widths yet, the site should resize to smaller screens - but it doesn't because the smartphone is displaying it as if it were 960px wide. The first thing to do is tell smartphones to display the site at the actual width of the screen.


2. Setting the Screen Width

To tell smartphones to behave nicely with regard to screen width, I add a line into the <head> section in header.php, as follows:

<meta name="viewport" content="width=device-width" />

This instructs smartphones to display the page at the device's screen width rather than create a virtual 960px wide viewport which is the default behaviour.

Now the theme looks like this on a small screen:

03-startingtheme-correct-screen-width.png

If you've created responsive stylesheets before but not Mobile First ones, this will be a bit of a revelation. Remember all that extra styling you added to your media queries for small screens? You'll need very little of it, as a page with minimal layout styling already looks better on mobile than it does on the desktop, as you can see from this screenshot, taken at 1024px wide:

04-starting-theme%20desktop.png

But I still need to add some layout styling for small screens, which is the next step.


3. Style the Main Layout Blocks for Small Screens

I'll start by adding some widths and floats for the main elements, to ensure that they stretch across the screen. I add some widths and a clear:both declaration to the relevant elements:

header, nav.main, .container, .content, .sidebar, footer {
	width: 100%;
	clear: both;
}

Next, to avoid the design looking squeezed into the small screen, I'll add padding to some elements:

header, nav.main, .container, footer {
	padding: 10px;
}

Note that these are the only horizontal values I'll be defining in pixels, and I do this because I don't want the padding to become too big as the screen size increases.

Now the site looks less crowded and the main elements are displayed beneath each other:

05-mobile-padding-applied.png

Next I'll tidy up the widget areas and improve the navigation.


4. Add Additional Styling for Small Screens

The navigation needs to span the width of the screen and I'd like to centre each menu item, so I'll add some styling for the menu:

nav.main {
	background: #3394bf;
	overflow: auto;
	text-align: center;
}

This gives me a much smarter looking menu:

06-centred-menu.png

The widget areas are all quite close together and it's difficult to see where one ends and another begins. I'll add some borders and padding to address that:

.sidebar .widget {
	padding: 10px 0;
	border-top: 1px solid #3394bf;
}

Next, the footer widgets. I'll do something similar to them too:

footer .widget {
	padding: 10px 0;
	border-top: 1px solid #fff;
}

This adds some separation between my widgets:

07-widgets-border.png

I now have a simple layout for my theme on small screens, with some colours, borders, margins and padding to help things along. I won't add any extra styling here as it could slow the theme down on mobile devices and I don't believe it's always necessary on small screens. So the next step is to start creating media queries.


5. Add Some Media Queries

For this theme I'm going to target three additional screen sizes:

  • 600px wide and up, which will encompass tablets in portrait or landscape as well as desktop screens
  • 800px wide and up, which will include tablets in landscape mode and desktops
  • 1025px wide and up, which will encompass all but the smallest desktop screens. I'm deliberately going one pixel above 1024px so that large tablets aren't affected by this media query.

You may have spotted that my media queries aren't all based on the width of a specific device. This is because as the range of devices and screen widths expands, targeting specific devices becomes less reliable than setting media queries at the point at which the layout benefits from them. I've tested the layout by resizing my browser window and at 600px wide it looks like this:

08-mobile-first-theme-at-600px.png

In my view, the design looks wrong at this width and can benefit from some layout changes.

So, I start by adding my media queries at the end of the stylesheet:

/* tablets - portrait */
@media screen and (min-width: 600px) { }

/* tablets - landscape */
@media screen and (min-width: 800px) { }

/* desktops*/
@media screen and (min-width: 1025px) { }

Note that I've used min-width, not max-width as you would if you were styling desktop first and writing media queries for smaller screens.

Next I'll move on to styling for tablet devices.


6. Add Styling for Tablet Devices in Portrait Mode

I want to improve my layout to make better use of the screen space on these larger screens, and I'll also add some CSS gradients to make the design a bit more polished.

Firstly, the layout. Inside my media query for screens 600px and larger, I add:

/* layout - widget areas side by side */
footer {
	overflow: auto;
}
.sidebar .widget,
footer aside {
	float: left;
	width: 49%;
	margin-right: 2%;
}
.sidebar .widget:nth-child(even),
footer aside:nth-child(even) {
	margin-right: 0;
}

This adds floats and some margins to make better use of the screen width:

09-tablet-widgets.png

I'm now going to alter the navigation, as the current layout leaves a lot of empty space next to each item and takes up a lot of room. I add the following styling to create a horizontal navigation bar:

/* navigation - float items next to each other */
nav.main {
	text-align: left;
	padding: 0 10px;
}
nav.main li {
	float: left;
	margin: 0;
}
nav.main li a {
	padding: 0 20px;
}

I'll also add a gradient to the menu for this screen size and above:

nav.main, nav.main a {
	background: #183c5b; /* Old browsers */
	background: -moz-linear-gradient(top, #183c5b 0%, #3394bf 100%); /* FF3.6+ */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#183c5b), color-stop(100%,#3394bf)); /* Chrome,Safari4+ */
	background: -webkit-linear-gradient(top, #183c5b 0%,#3394bf 100%); /* Chrome10+,Safari5.1+ */
	background: -o-linear-gradient(top, #183c5b 0%,#3394bf 100%); /* Opera 11.10+ */
	background: -ms-linear-gradient(top, #183c5b 0%,#3394bf 100%); /* IE10+ */
	background: linear-gradient(top, #183c5b 0%,#3394bf 100%); /* W3C */
}

Depending on the devices and browsers I'm targeting, I could omit some of those browser prefixes but I've left them in for any other users of my theme.

So, I now have an improved layout for tablets in portrait orientation, as shown in the screenshot:

10-tablet-navigation-gradient.png

7. Add Styling for Tablet Devices in Landscape Mode

I'm only going to make one change for screens of this width: I'm going to move the sidebar to the right of the content, as the content looks a bit stretched if it spans the whole screen. To do this, I add the following into the media query targeting min-width of 800px:

.content {
	width: 65%;
	float: left;
}
.sidebar {
	width: 33%;
	float: right;
	clear: right;
}
.sidebar .widget {
	width: 100%;
	float: none;
}
.sidebar .widget:first-child {
	border-top: none;
}

This does a few things:

  • It moves the sidebar to the right of the content
  • It resizes the sidebar and content and adds floats and a clear property for the layout
  • It removes floats on the widgets so they're now in a column
  • It removes the border-top from the first widget, which no longer needs it

The theme now looks like this on a tablet in landscape mode:

11-tablet-landscape.png

8. Add Desktop Styling

If I had built my responsive theme in the traditional way, desktop first, I would be working on this screen size first, but here I'm working with it last. You may have noticed by now that this makes things very efficient - in my experience, removing desktop styling in media queries aimed at mobile takes much more work than tweaking my mobile layout for desktop.

I'm going to adjust the footer layout to have all four footer widget areas next to each other, and add a background image to the header. This image isn't crucial to the content but is there for decoration, so I'm comfortable with the fact that it isn't in my markup.

First, the layout. As well as adjusting footer layout, I'll add a max-width value to the body tag to avoid stretching the layout across the full width of very wide screens:

body {
	width: 95%;
	max-width: 960px;
	margin: 0 auto;
}
footer aside {
	float: left;
	width: 23.5%;
	margin-right: 2%;
}
footer aside:nth-child(even) {
	margin-right: 2%;
}
footer aside.fourth {
	margin-right: 0;
}

The styling above goes in the media query for screens with a min-width of 1025px, and does the following:

  • Adds max-width to the body
  • Adjusts the width and right hand margin on the aside elements in the footer
  • Adjusts the margin for even numbered widget areas to 2% in line with the other widget areas
  • Using the class assigned to the fourth widget area in the theme (.fourth), reduces its margin to 0. I've deliberately used a class here instead of nth-child as I need this to work across browsers

So, what does my theme look like in the desktop?

12-desktop-version.png

Not bad. Finally I'll add a background image to my header.

header {
	background: URL(images/banner-image.jpg) center bottom no-repeat;
	padding-bottom: 210px;
}

This adds my image as a background with some padding to allow space for it:

13-final-desktop-banner-image.png

The advantage of using this approach is that this image will only be downloaded by desktop machines. As it's not in the core styling or the media queries for smaller devices, it won't slow them down. There are downsides to using images as backgrounds though, especially relating to accessibility - so it's important to only use this technique when the image is for design only and isn't part of the content. Alternatively, I could have added a smaller version of the image in my markup and used CSS to hide that and display a larger version of the same image as a background for larger screens.


Summary

I now have a responsive, Mobile First theme. By starting with small screens and working my way up I reduced the amount of code needed to create my responsive design and was able to ensure that a large image isn't sent to mobile devices.

As more developers and site owners require their sites to be responsive, being able to build responsive WordPress themes will become an invaluable skill. In this tutorial I've shown that it needn't be an onerous process and shouldn't take too long. Of course, you can take the process further and add mobile-specific content or additional styling targeted at specific devices, but that's something for another day!

Advertisement