fromSeptember 2014
Feature:

Responsive Themes

Implementation With Drupal 8
0

Square Watermelong In 2010, Ethan Marcotte published his seminal article, “Responsive Web Design,” and the way we build web sites was forever changed. Although Drupal 7 came out at the beginning of 2011, there was nothing in core to support the themers who wanted to build responsive websites. By 2012, all of the popular base themes offered a stable release which included a responsive starting point. As of Drupal 8, the core themes, and the administrative interface, will be responsive – making Drupal usable at any viewport width.

The original tenets of responsive web design had three directives:

  1. Use a fluid grid to lay out page elements.
  2. Make images flexible, and responsive to their parent container.
  3. Use media queries to specify which styles should be assigned for any given viewport width.

In practice, it has been a lot more complicated to implement these guidelines so that they work across devices and are respectful of the slower connection speeds we often experience on mobile devices.

In this article we'll take a look at how to implement each of these three principles in your Drupal 8 themes. The article was written against Drupal 8.0-alpha13. Some things are likely to have changed between now and Drupal 8's official release. Where possible, I've noted where this might be the case.

Fluid Grids

Out of the box Drupal 8 does not provide any support for a universal fluid grid. It does, however, provide the cleanest, most semantic markup of any version of Drupal to date. Markup is almost entirely contained in template files, and the theme function has been virtually eliminated from core. All of these changes were accomplished by the team working to convert Drupal from PHPTemplate to Twig. As a result, it will be significantly easier to drop in your grid layout system of choice – whether it is custom built, or part of a framework such as Bootstrap or Foundation.

Working with a base theme is still, of course, an option for you. As of this writing, there are no base themes with a completely functional Drupal 8 release; however, a few have Drupal 8 branches if you'd like to help with their upgrade process.

Incorporating a grid framework into your own theme requires only a few steps to get started. The hardest part is probably choosing which framework you want to use. Front end developers have high standards and generally look down their nose at those who use “bloated” frameworks, such as Bootstrap or Foundation. I'm not going to judge; I'm just going to show you how to get started with Bootstrap so you can take things for a quick test drive.

At a high level, these are the steps to get a simple Bootstrap theme up and running.

  1. Put a copy of the core theme, Stark, into your site's themes folder.
  2. Rename the theme from stark to bootstrap, updating all file names and the contents of all configuration files (.info.yml and the contents of the config directory).
  3. Download the latest compiled and minified version of Bootstrap.
  4. Unpack the Bootstrap folder, placing the contents of the css, fonts, and js directories into the relevant theme folders.
  5. Add the CSS files to the theme's info file and remove the reference to Stark's layout.css file.
  6. Copy the core page template file from core/modules/system/templates/page.html.twig to your theme folder. (I put mine in a new folder: templates.)
  7. Add Bootstrap-specific class names to the template file page.html.twig.
  8. Switch the theme to your new Bootstrap theme at Manage » Appearance. Just as it would have been in Drupal 7, your new theme should be listed at the bottom with other disabled themes.

If your framework of choice also has JavaScript libraries, you'll need to load those as well. This is now done from within a new theme file, THEMENAME.libraries.yml. Into the libraries file, you can load several groups of JavaScript libraries. These changes were documented at “Remove 'scripts' and add 'libraries' key to theme info files” and “Replace hook_library_info() by *.libraries.yml file.” Take a look at the core theme Seven for some examples. I used the following library file for my own tinkering:

bootstrap-corescripts:
  version: VERSION
  js:
    js/bootstrap.min.js: {}
  dependencies:
    - core/jquery
    - core/drupal.ajax
    - core/drupal
    - core/drupalSettings
    - core/jquery.once

The libraries file still needs to be loaded by your theme. This is done from within your theme's info file:

libraries:
  - bootstrap/bootstrap-corescripts

Replace bootstrap with the name of your theme folder, and bootstrap-corescripts with the name of the grouping within the THEMENAME.libraries.yml file.

If you make changes to your theme's info or library files, you will need to clear the theme's registry. I found that using Drupal's Clear Cache button (which is located at Manage » Performance » Clear Cache) wasn't sufficient, and I had to disable and then re-enable the theme to clear the registry. If you have Drush installed, a simple drush cr should also work.

To apply the fluid grid to your theme, it will now be a matter of adding class names to the appropriate template file(s). I've always found this work to be somewhat tedious but somehow pleasant, both at the same time. I get a sense of satisfaction from making things snap into place just by applying a class name. If you don't enjoy the monotony of naming things, don't panic! By the time Drupal 8 is ready for its official release there will likely be a number of base themes available which offer native support for fluid grids.

Responsive Images with Picture and Breakpoint

In the earliest versions of responsive web design, we simply set the max-width of an image to 100% and went on our merry way. Unfortunately, this wasn't an ideal solution as very large images, often optimized for high-resolution displays, resulted in a lengthy download time for tiny mobile devices. In Drupal 8, we have a solution which takes advantage of the hard work that's been done by the web community to date.

The two modules, Picture and Breakpoint, allow themers to create a relationship between the size of the viewport, and the size of the image that we want the user to download. For example: I have banner images, author profile images, and inline article images. Each of these different types of image may have its own styles applied to it. A banner image at full width is very wide, but relatively short. When this same banner image is displayed on a handheld device though, the orientation of the screen is different. So perhaps at this viewport size it makes sense to use the same image style as an inline article image.

Essentially, images are now created and selected for display as follows:

  1. You upload your original image.
  2. Drupal creates a series of pre-set images according to your image styles – just like you could in Drupal 7.
  3. The breakpoint module allows you to create rules which target the viewport width for each of the image styles.
  4. The picture module creates an HTML wrapper element which helps the browser select the correct image – out of all the possible styles from the relevant group – for download and display.

To take advantage of this new capability, you will need to configure your settings for each of the decision points outlined.

Seeing as we started with a copy of Stark for this theme, you will need to find the place where the breakpoints are defined as of the time of publication. Once you locate the definition file for your breakpoints, you can review and adjust them as necessary. The configuration includes a name for the breakpoint, as well as the rule at which this breakpoint exists. For example: wide: 'screen and (min-width: 40em)'. Take a look at the core themes, Seven and Bartik, to see examples of how these breakpoints can be defined.

Breakpoint Configuration

At the time of writing, the configuration settings were in config/install/THEMENAME.breakpoints.yml, but we anticipate having a UI for this in time for Drupal 8’s official release. You can follow the issue on Drupal.org.

The responsive images work with the image styles you create. Just as it did for Drupal 7, Drupal 8 ships with three default styles: thumbnail, medium, and large. You can configure these styles (and add more styles) at Manage » Configuration » Image styles. Now that you are able to target image styles to breakpoints you will likely have more image styles than you had previously. When naming your image styles be aware of how you could reuse the styles in your design. For example, do you really need several different styles for your mobile images? My guess is that at narrower viewport widths you probably need fewer styles to choose from.

You will need to configure Drupal to match up which image styles should be used at what breakpoints. At the time of this writing the UI was not enabled by default. Navigate to Manage » Extend, and enable the module, Responsive Image. (When I wrote this article there were some rumblings that Breakpoint might be removed from core; if the module isn't there, you will need to download it.) Once the module is enabled, navigate to Manage » Configuration » Responsive image mappings. From this screen you will create a new map, and associate image sizes with each break point. It made more sense to me when I thought about this configuration screen as a mini content type for an image.

To see your new settings in action, you need to change the display widget for your content type from the Image widget to the Picture widget. Navigate to Structure » Content type » (select your content type) » Manage display. Next to each of your image fields, change the widget from Image to Picture. Below the column Format, set the fields for the Responsive image map and the Fallback image style (the single style that should be applied if the breakpoint-specific style isn't used). Assuming you are using Display Modes for your Views, there are no additional changes you need to make. You will need to update any of your Views that are using per-field image settings. (BTW: Don't do this! Make display modes!)

At this time the Breakpoint module is only used by the Picture module. During the development cycle there was some discussion of using Breakpoint in conjunction with SCOTCH for layouts. This did not come to pass, but could be introduced in a later version of Drupal (and perhaps as early as 8.1). These two modules have also been back-ported to Drupal 7. There are several articles in the resources section with step-by-step instructions on how to use them.

Media Queries

In building responsive themes, I have seen two approaches taken: the first is to use a style sheet per media query, and essentially provide a whole new layout which is optimized for very specific viewport sizes; the second is an object-oriented approach to the design, using components.

For a period of time, Omega shipped with a separate style sheet (and related media query) intended for global, default, narrow, normal, and wide layouts. Tucked into each of these files were the styles of how every design element would adjust at the new layout. This was an early approach to responsive theming, but it is not considered a best practice today. If your theme is structured this way, and it's working for you, great! But if you've often found it difficult to find where styles are located, or you're getting a lot of merge errors as multiple people simultaneously work on the same source files, you may want to consider modernizing the organization of your styles by adopting a component-based approach.

The component approach has been popularized with systems such as OOCSS, SMACSS, and BEM. These systems describe rules on how to organize your styles, but unlike Bootstrap, Foundation, or PatternLab, they're more about the naming convention than the starter kit you might download. This component-based approach to theming is one that I covered in my Drupal 7 video series for Drupalize.Me, and about which John Albin Wilkins has presented at DrupalCon Austin, “Managing Complex Projects with Design Components.”

Summary

When I first agreed to write this article, I thought things would be a little more stable, and a little easier to accomplish. When Drupal 8 ships, you will be able to take advantage of everything I've outlined here. Perhaps you'll need a little help from contrib, and perhaps your favorite base theme will already be upgraded, but the core concepts are responsive and ready for you to dive into. Dive in now. Ask questions. Everything you find will help Drupal ship an even better product that you love to build web sites with.

Image: http://www.istockphoto.com/photo/cube-watermelon-21568426