Advanced Responsive Design Techniques

Now that we’ve mastered flexible grids and media queries it’s time to take our responsive design to the next level.

Introduction

RWD is incredibly simple. Flexible grids for the layout, flexible media (images, video, iframes), and apply @media queries to update these measurements to best arrange content on any viewport. One source, millions of viewports.

In practice, we’ve learned that it is not really that easy. Tiny issues that crop up during every project that keeps us scratching our heads and occasionally carving fingernail trenches on our desks.

Ever since I began curating the Responsive Design Weekly newsletter I’ve been fortunate to speak with many of you and feature your experiences each week. With a few hundred great tips in the bag I wanted to know what you what you wanted to learn, and through a survey circulated
to the readers here were the top results.

  1. Responsive Images
  2. Improving Performance
  3. Responsive Typography
  4. Media queries in javascript
  5. Progressive Enhancement
  6. Layout

With those topics in mind I ran a series of podcasts asking some of our industry leaders for their advice around advanced these responsive topics.

Their answer was unanimous. Focus upon getting the basics right before you start worrying about new, exciting or advanced approaches.

By taking things back to the basics we are able to build a robust interface for everyone, layering upon features when the device or users context allows.

“So… what about these advanced techniques?” I hear you asking.

I think Stephen Hay summed it up best when he shared the ultimate advanced responsive design technique:

The ultimate RWD technique is to start off by not using any advanced RWD techniques. That’s it. Start from the basics and go from there. Start with structured content and build your way up. Only add a breakpoint when the design breaks and the content dictates it and… that’s it.

We’ll still take a look at those advanced techniques but ensure you start off with the basics and add layers of complexity as the situation allows.

Lets get started.

Responsive Images

Fluid media was a key part of RWD when first defined by Ethan Marcotte. width: 100%; max-width: 100%; still works today but the responsive images landscape has become a lot more complicated.

With increasing screen sizes, density, and devices to support we craved greater control over the image being sent to the user.

The three concerns were defined by Responsive Images Community Group (RICG)

  1. The kilobyte size of the image we were sending over the wire;
  2. The physical size of the image we were sending to high DPI devices; and
  3. The image crop in the form of art direction for the particular size of the viewport.

Yoav Weiss, with a lot of help from the community has done the majority of the work for the Blink implementation and by the time you’re reading this it will be shipped in Chrome and Firefox. Safari 8 will ship scrset however the sizes attribute is only in nightly and <picutre> itself is not yet implemented.

With the arrival of anything new to our web development process, it can be difficult to get started. The markup itself can be confusing so let’s take a step by step run through an example.


    <img 
      <!-- Declare the fallback image for all non picture supporting browsers -->
      src="horse-350.jpg" 
      <!-- Declare all of the image sizes in srcset. Include the image width using the w descriptor so the browser knows the width of each image.-->
      srcset="horse-350.jpg 350w,
      horse-500.jpg 500w,
      horse-1024.jpg 1024w,
      horse.jpg 2000w" 
      <!-- Sizes are what tells the browser our site layout. Here we're staying for any viewport that is 64ems and bigger use an image that will occupy 70% of the viewport -->
      sizes="(min-width: 64em) 70vw,
      <!-- If the viewport isn't that big, then for any viewport that is 37.5ems and bigger use an image that occupies 95% of the viewport -->
      (min-width: 37.5em) 95vw,
      <!-- and if the viewport is smaller than that then use an image that occupies 100% of the viewport-->
      100vw"
      <!-- always have alt text.-->
      alt="A horse" />

From a performance point of view it doesn’t matter if you use min-width or max-width in the sizes attribute, but the source order does matter. The browser will always use the first matching size.

Also remember we are hardcoding the sizes attribute to be directly defined against our design/layout. This may cause issues moving forwards when redesigning your site having to revisit all of the <img> or <picture>‘s and redefining the sizes.

This can be overcome as part of a build process if you are using a CMS. WordPress already has a plugin to help by defining the srcset on WP standard image varieties and it allows you to declare sizes in a central location and it looks like Drupal 8 will ship with something similar. When the page is generated from the database it swaps out any mentions on <img> and replaces it with the picture markup.

Basics

  • Think about whether you really need to include an image. Is it telling part of the story? Is the image core content, or is it decorative. One less image will mean a faster load time.
  • Have you optimised images using ImageOptim?
  • Set expire headers for your images on your server or .htaccess file (see details below in performance).
  • PictureFill provides polyfill support for picture.

Advanced

Performance

To get the fastest perceived performance on our pages we need all the HTML, CSS, and JS required to render the top part of our page within the first response from the server — that magic number is 14kb.

Patrick Hamann, Technical Front End lead at the Guardian, and team has managed to break the 1000ms barrier by introducing a mixture of front end and backend techniques. The Guardians approach is to ensure the content — the news article — is delivered to the user as quickly as possible and within
the 14kb magic number.

Lets look at the process:

  1. User clicks on a link news story from Google.
  2. A single blocking request is sent to the database for the article (no related stories or comments are requested).
  3. The HTML is loaded containing Critical CSS in the <head>
  4. A “Cut the Mustard” process is undertaken and any conditional elements based upon the users device features are loaded.
  5. Any content related to or supporting the article itself (related article images, article comments etc) are lazy loaded into place.

By using the critical CSS approach means the <head> is 222 lines long however the critical content still comes within the 14kb initial payload when gzipped and it’s this process that helps break that 1000ms barrier.

Conditional & Lazy loading

Conditional loading is improving the users experience based on their device features. Tools like Moderizr allow you to test for these features, but beware that just because a browser says it offers support
that it doesn’t always mean full support. Another approach might be to “Cut the Mustard”.

If the browser is deemed as enhanced after the check then you can provide them with a more immersive experience. To see a working example try disabling javascript on the bbc.co.uk and see the difference.

Another approach might be to hold off loading something until the users shows intent to use a feature. This would be considered conditional based upon the user context. You can hold off loading in social icons until the user hovers or touches the icons, or you could avoid loading an iframe google map on smaller viewports where the user is likely to prefer linking to a dedicated mapping application.

Lazy loading is defined as something that you always intend to load on the page — images that are a part of the article, comments, or other related articles — but that don’t need to be there for the user to start consuming the content.

Back to Basics

Advanced Techniques

  • Set up Fastly or CloudFlare. CDN’s deliver your static content to users faster than your own server.
  • Enable SPDY for http2 enabled browsers to take advantage of HTTP2 features like parallel HTTP requests instead of synchronous. CloudFlare offers this for paid accounts.
  • Social Count allows for conditional loading of your Social Icons.
  • Brad Frost built out this example using the Static Maps Google API
  • Ajax Include Pattern that will load content snippets from either a data-before, data-after data-replace attribute.

Responsive Typography

Typography is about making your content easy to digest. Responsive typography extends this to ensure readability across a wide variety of devices and viewports.

Jordan Moore admits that type is one thing he isn’t willing to budge on. Drop an image or two if you need, but make sure you have great typography.

Stephen Hay suggests setting the HTML font size to 100% (read: just leave as it is) because each browser/device manufacturer makes a reasonably readable default for a particular resolution/device. On the majority of desktop browsers this is set to 16px, but there are devices with browser defaults set
much higher.

On the other hand, Jordan uses the REM unit & HTML font-size to set a minimum font size for certain content elements.

For example, you want the byline of an article to always be 14px, then set that as the base font-size on the HTML element and set .byline { font-size: 1rem;}. As you scale the body: font-size; to suit the viewport you will not impact the .by-line style.

Getting a good reading line length is also important, between 45 and 65 characters is the goal. You can use this bookmarklet to check to see that your existing content works.

If you are supporting multiple languages with your design then line length may vary as well. Jordan suggests using :lang(de) article {max-width: 30em} to cover off any issues there.

For good vertical rhythm set the margin-bottom against content elements <ul> <ol> <table> <blockquote> to the same as your line-height.

The rhythm can be interrupted with the introduction of images so it’s good to incorporate baseline.js or baselineAlign.js

Basics

  • Base your font on 100%
  • Work in relative EM units
  • Set your Margins to your line height to maintain vertical rhythm

Advanced

  • Improve font loading performance with Enhance.js or Smashing Magazines approach
  • Use Sass @includes for semantic headings Often we need to use the h5 style in a sidebar widget that requires h2 markup. Using Bearded’s Typographic Mixins you can use the below code to control the size and remain semantic.
    .sidebar h2 {
        @include heading-5
      }

Media Queries in Javascript

Ever since we were able to control the layout across a variety of viewports through Media Queries we’ve been looking for a way to tie that into running our javascript as well.

There are a few ways to fire javascript on certain viewport widths, heights and orientations, and some smart people have written some easy to use native js plugins like Enquire.js and Simple State Manager. You could even build this yourself using matchMedia however you have the issue that you need to duplicate your media queries in your CSS and Javascript.

Aaron Gustafson has a neat trick that means you don’t have to manage and match your media queries in your CSS and your JS.

Link your JS to CSS Media Query values

The idea originally came from Jeremy Keith and in this example Aaron Gustafson has taken it to a full implementation. With getActiveMQ it injects div#getActiveMQ-watcher at the end of the body element and hides it, then within the CSS you set #getActiveMQ-watcher {font-family: break-0;} to the first media query, font-family: break-1; to the second, font-family: break-2; to the third and so on.

The script uses watchResize() to check to see if the size of the viewport has changed and then reads back the active font-family. Now you can use this to hook JS enhancements like adding a tabbed interface to a <dl> when the viewport allows, or changing the behaviour of a lightbox updating the layout of a data table. Check out thegetActiveMQ Codepen.

Basics

  • Forget about javascript for different viewports. Provide content and website functions to users in a way they can access it across all viewports. We should never need javascript.

Advanced

  • Extend Aarons method by using Breakup as a predefined list of media queries and automating the creation of the list of font-families for #getActiveMQ-watcher

Progressive enhancement

There’s a common misconception about progressive enhancement that people think ”oh well I can’t use this new feature“, but instead it’s the opposite. Progressive Enhancement means that you can deliver a feature if it’s only supported in 1 or even no browsers and over time people will get a better experience as new versions are browsers improve.

If you look at the core function of any website you can deliver that as HTML and have the server side do all the processing. Payments, forms, likes, sharing, emails, dashboards, it can all be done.

Once the basic task is built we can then layer the great awesome technologies on top of that because you have a base safety net to catch those that fall through.

All of the advanced approaches we have talked about here are based upon progressive enhancement.

Layout

Flexible layout is simple to say, but it has many different approaches.

Floats and nth-child(2n+1);

Create simple grid layouts with less markup by using :nth-child() selector.


     /* declare the mobile first width for the grid */
    .grid-1-4 { float:left; width: 100%; }

    /* When the grid is the 50% per element clear floats every 2nd element AFTER the 1st. This targets the 3rd, 5th, 7th... element*/
    @media (min-width: 37.5em) {
      .grid-1-4 { width: 50%; }
      .grid-1-4:nth-of-type(2n+1) { clear: left; }
    }
    @media (min-width: 64em) { .grid-1-4 { width: 25%; }
/* When the grid elements are 25% clear the float every 4th element AFTER the first. This targets the 5th, 9th... in the grid.*/
      .grid-1-4:nth-of-type(4n+1) { clear: left; }
    }

A new layout

Wave goodbye to using position and floats for our layouts. While they have done us well to date their use for layout has been a necessary hack. We’ve now got two new kids on the block that will help fix all our layout woes — Flexbox and Grids.

Switching to Flexbox

Flexbox is great for individual modules, controlling the layout of pieces of content within each of the modules. For example, a photo and caption pair where you might have one above the other depending on the breakpoint.

There are layouts we attempt to deliver that can be more easily achieved using Flexbox, and this rings out even more true when building sites responsively. There are some great articles that take us through all the capabilities of flex-box.

Links to Flexbox

CSS Grid Layout

Grid is more for the macro level layout. The page. The grid layout module gives you a great way to describe your layout within your CSS.

While it’s still in draft at the moment I recommend following Rachel Andrew because as Ethan Marcotte put it “Rachel has forgotten more about the Grid Spec then any of us hope to learn”.

Finally

These are just a few tips to extend your responsive practice. When approaching any new responsive work take a step back and ensure that you get the basics right, start with your content, HTML and layer improved experiences upon them and there won’t be any limit to where you can take your designs.

Subscribe to RWD Weekly to keep across the latest news, and follow RWD.is for more interviews and podcasts.

Subscribe to our Newsletter

Add your email address and receive an email every Friday covering off everything worth knowing about building your websites responsively.