Responsive Theming for Drupal (2014)

Chapter 7. Some Common Gotchas and Tips

It’s not all roses and meadows in the world of responsive web design—there are some common issues that throw a wrench into things from time to time, so it’s good to be aware of these before they hit so that you can save yourself some frantic Googling.

The basic gist of RWD is that you’re trying to reuse as much markup as possible between different resolutions by just styling things differently. However, there are a few cases where that doesn’t cut it, and you need to customize things a bit.

Different Resolution-Specific Navigations

Probably the most common area for this to happen is in the site navigation. For example, pretend that Riley’s turnip sauce site has a horizontal navigation with hierarchical, multilevel hover-based dropdown menus on desktop resolutions. How would you represent that for mobile resolutions and touch-based interfaces?

For one thing, touch interfaces have no idea when you’re hovering or not because there’s no mouse pointer to do the hovering. You can always use “touch” to replace “hover” (in fact, browsers on touch interfaces report a hover when you touchdown anyway so that’s not hard) but then that presents the problem of “hovering” and “clicking” being the same action. So hover-based dropdown menus in general are out.

So your options are to either display all of the menu options in one giant indented list that takes up three screens worth of scrolling, or figure out some other way to handle the “hover” action.

Select Dropdown as Mobile Navigation

One common method, for better or worse, is to generate a <select> dropdown out of the menu items to take the user to the respective menu path when an option is selected.

This brings the advantages of already having good mobile browser integration and already being understandable to the user, as well as not taking up a huge chunk of screen real estate.

The disadvantage is that you’re using a form element for something other than its originally intended purpose, and that can feel dirty to you and unexpected to your users at times.

That said, in many cases it’s a good choice, and it’s fairly easy to implement. You’ll be writing a few lines of jQuery that will cycle through your nav links and build a select dropdown out of them. This will be done regardless of screen resolution. Then, you’ll use an @media query to show it on mobile and hide the regular nav, and vice versa on desktop.

The jQuery can look something like this, which is taken from from Treehouse’s “CSS Tricks page”:

// Create the dropdown base

$("<select />").appendTo("#navigation"); // Use the correct selector

// Create default option "Go to..."

$("<option />", {"selected": "selected", "value" : "", "text" : "Go to..."})

  .appendTo("#navigation select");

// Populate dropdown with menu items

$("#navigation a").each(function() {

  var el = $(this);

  $("<option />", {"value" : el.attr("href"), "text" : el.text()}).

    appendTo("#navigation select");

});

// Make the select dropdown actually work

$("#navigation select").change(function() {

  window.location = $(this).find("option:selected").val();

});

That will generate the mobile-specific navigation select dropdown and insert it into the DOM after the desktop-specific navigation element, but that’s only half the battle. We also need to make sure the correct navigation is shown on the correct devices. Specifically, we only need the select dropdown to be visible on mobile and we need only the regular nav menu to be shown on non-mobile. So for that, we need this bit of CSS:

#navigation select {

  display: none;

}

@media (max-width: 960px) {

  #navigation ul     { display: none; }

  #navigation select { display: inline-block; }

}

See how that works? Simple, yeah? Now just make sure you add some styles for the select dropdown so that it will look nice and you’re good to go with your mobile-specific unobtrusive nav.

Mobile-Specific Navigation Hidden by Default

Another option is to include a mobile-specific navigation element that starts out hidden. This technique, which was perhaps popularized by Bootstrap, involves creating a hierarchical nav menu that emulates the format of the desktop dropdown menus, but is hidden by default until the user toggles it.

Often, this involves a little button at the top of the page that looks like three horizontal lines stacked on top of each other. Clicking that button slides down the nav, which is nothing more than a styled unordered list of links.

This way, the user is shown an actual nav (i.e., a list of links) as opposed to a form field (i.e., a select dropdown), but it doesn’t take up a huge chunk of space and doesn’t involve any funky “hover” interaction. Plus, you can usually use the exact same markup for all resolutions and just do the magic in CSS.

So say the CSS for your desktop hover-based dropdown nav looks something like this:

#navigation ul li {

  display: inline-block;

}

#navigation ul li ul {

  display: none;

}

#naviation ul li:hover ul {

  display: block;

}

That will obviously hide the submenus by default and show them when you hover their parents. So since we want all of the links to be shown on mobile when the nav is toggled, you’ll want to add this:

@media (max-width: 960px) {

  #navigation ul li ul {

    display: block;

  }

}

And we can’t forget about our little navigation toggle button itself. We’ll need to always output the markup for that, but hide it on non-mobile, like so:

@media (min-width: 961px) {

  #nav-toggle {

    display: none;

  }

}

Then, of course you’ll want to make the menu hidden by default and only slide down when the user clicks the little button:

$('#navigation').hide();

$('#nav-toggle').click(function() {

  $('#navigation').slideToggle();

})

And that’s that. A mobile- or desktop-ready navigation that is non-obtrusive but fully functional and uses all the same markup.

Dealing with Responsive Images

As any regular mobile web user can tell you, things tend to take a lot longer to load on smartphones. Bandwidth is tougher to come by, and phones are obviously a lot less powerful than their bulkier desktop/laptop cousins. So any way we can make things quicker is a good thing, whether it means less CPU cycles or a smaller download size.

As we all know, images are often a heavy hitter when it comes to download size. Wouldn’t it be nice if we could give mobile users smaller images than desktop users? This makes sense for two reasons:

1.    Load times decrease substantially

2.    Mobile users don’t need images to be as big anyway, since smaller files would look just as good on mobile resolutions

It turns out, this isn’t very difficult in Drupaltopia. In fact, there is a module that serves that exact purpose. Let’s take a look at how that works.

Installation

First, download and install the Picture module along with its dependencies, which are the Chaos Tools module and the Breakpoints module.

Then you’ll want to configure your theme by adding breakpoint information into the theme’s .info file. It will look something like this (make sure to flush the theme cache after changing an .info file):

breakpoints[mobile] = (min-width: 0px)

breakpoints[narrow] = (min-width: 560px)

breakpoints[wide] = (min-width: 851px)

breakpoints[tv] = only screen and (min-width: 3456px)

Once that’s done, you can make sure those breakpoints are recognized by going to Configuration → Media → Breakpoints to view them.

NOTE

You will need a new breakpoint group for each image style you want to be responsive. For example, if you want the image styles “thumbnail” and “medium” to be responsive, you will probably need to create two breakpoint groups, which you might call “Thumbnail” and “Medium.”

After that, you can use the wizard to create the image styles for each breakpoint. Go to Configuration → Media → Breakpoints → “Add responsive style” and fill out the self-explanatory form there.

From there, you can drill down into individual image styles and configure the sizes to, for example, make the mobile styles smaller than the desktop sizes. This is done in the regular Image Styles interface at Configuration → Media → Image Styles.

And finally, once all of that is done, we’re ready to map the image styles to the picture options. Head on over to Configuration → Media → Picture to associate your breakpoints with image styles. Now, don’t forget that you’ll also need to set the display format to “Picture” instead of “Image” in the Display Fields UI for any image fields you want to responsify.

From there, the module should handle the rest. It will output the correct image size and resolution based on the breakpoints you defined, giving your mobile users a much needed bandwidth break and your desktop users the preferred high-resolution versions of images all at once.

Adding a Touch Icon for Mobile/Tablet Touchscreens

If you’re going to look good on mobile, you might as well look good on mobile, and part of that means providing a slick mobile icon that will show up whenever someone adds your website to their smartphone’s home screen.

iPhones and Android phones both look for a link tag with an attribute called “apple-touch-icon” to determine what should show up when adding a website to your home screen. If it’s missing, it’ll just provide a default icon or use the favicon, which looks terrible. So it’s usually a good idea to make sure it’s there.

If we were talking about a static site, we’d just want to add this somewhere inside the <head> tag:

<link rel="apple-touch-icon" href="/your-custom-icon.png"/>

Make sure that whichever image you link to is 60px by 60px, unless you use custom sizes like so:

<link rel="apple-touch-icon" href="/your-custom-icon.png">

<link rel="apple-touch-icon" sizes="76x76" href="/your-custom-icon-ipad.png">

<link rel="apple-touch-icon" sizes="120x120"

  href="/your-custom-icon-retina.png">

<link rel="apple-touch-icon" sizes="152x152"

  href="/your-custom-icon-ipad-retina.png">

Easy enough, right? Well, Drupal doesn’t fight us too much on this one. We’ll just need to add that line to our html.tpl.php (if your theme doesn’t have one, copy and paste the default into your theme). If you open up that file you’ll see that it contains a <head> tag, so we can just add that line right in there. Of course, you’ll want to replace the href with the actual path, whatever that might be.

From there, it’s a matter of testing it out by adding a bookmark for your site to your phone’s home screen and seeing if the icon shows up. If not, try a Drupal cache flush, and try removing the bookmark on the phone completely (i.e., delete it from the browser app, not just the home screen), then readding it.

Supporting Older Internet Explorer Browsers

The age-old question—what about IE? Which versions of IE should I support? How much effort would it take to get IE8 up to speed? Is IE7 a possibility?

The short answer to this is that you should try your best to convince your client that it’s a good idea to drop support for older IE versions (anything under IE9 would be best, if possible). This means that you have to spend less time developing and debugging, and you’re able to write a more modern website that isn’t bogged down by making things work on old crusty browsers.

However, it also means that you’re hanging some users out to dry, so it can sometimes be a tough sell. In most cases, it makes sense to check analytics to see just how many of your users are coming from which browsers and if it’s financially viable for the client to lose that user base in the name of easier development and quicker turnaround.

If you do have to support IE8 or earlier, you should first of all note that media queries aren’t supported, so you’ll have to resort to some sort of polyfill to get things up to snuff.

Another option is Breakpoint’s No Query Fallbacks, which give you a couple options to use besides media queries. Specifically, you can use a separate fallback file that only IE uses, or you can add a class to rules in addition to a media query.

From there, it’s just a grind of finding something that looks broken, debugging it using the terrible IE dev tools, doing lots of Googling, and then finding a workaround. This isn’t really Drupal specific at all—this is sadly just the lay of the land when it comes to older versions of IE. Drupal can’t do much to save you from this.

Styling/Testing Common Drupal Elements

Drupal ships with a lot of default markup and elements, many of which are user facing. Some of these include forms (login, contact, register, etc.), tabs, tables, and lists. It’s usually a good idea to test all of these as much as possible to be sure that your theme is bulletproof and can handle whatever a client decides to throw at it.

As always, there’s a module for that: Style Guide. It will create a new page that will output a ton of typical Drupal markup and elements. This way, you can get a fairly complete rundown of anything that might appear on other pages all at the same place, so that it’s easier to tell at a glance if your theme is handling everything well or not.

If your theme makes all of that stuff look good, then you can feel fairly certain that you’re ready for whatever the client is going to throw at you (assuming he or she is only equipped with a WYSIWYG and some node edit forms, as opposed to something crazy like the full Panels interface).