Table of Contents for
Mastering Responsive Web Design

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Mastering Responsive Web Design by Ricardo Zea Published by Packt Publishing, 2015
  1. Cover
  2. Table of Contents
  3. Mastering Responsive Web Design
  4. Mastering Responsive Web Design
  5. Credits
  6. About the Author
  7. Acknowledgment
  8. About the Reviewers
  9. www.PacktPub.com
  10. Preface
  11. What you need for this book
  12. Who this book is for
  13. Conventions
  14. Reader feedback
  15. Customer support
  16. 1. Harness the Power of Sass for Responsive Web Design
  17. The basic concepts of Sass for RWD
  18. Summary
  19. 2. Marking Our Content with HTML5
  20. The
  21. The
    element
  22. The
  23. The
    element
  24. The
  25. The
  26. Using WAI-ARIA landmark roles to increase accessibility
  27. A full HTML5 example page with ARIA roles and meta tags
  28. Output screenshots for desktop and mobile
  29. Summary
  30. 3. Mobile-first or Desktop-first?
  31. Sass mixins for the mobile-first and desktop-first media queries
  32. Dealing with legacy browsers
  33. How to deal with high-density screens
  34. Sometimes RWD is not necessarily the right solution
  35. Retrofitting an old website with RWD
  36. Retrofitting with AWD
  37. Retrofitting with RWD
  38. Summary
  39. 4. CSS Grids, CSS Frameworks, UI Kits, and Flexbox for RWD
  40. CSS grids
  41. CSS frameworks
  42. UI kits
  43. The pros and cons of CSS frameworks for RWD
  44. Creating a custom CSS grid
  45. Building a sample page with the custom CSS grid
  46. Stop using CSS grids, use Flexbox!
  47. Summary
  48. 5. Designing Small UIs Driven by Large Finger
  49. The posture patterns and the touch zones
  50. The nav icon – basic guidelines to consider for RWD
  51. The navigation patterns for RWD
  52. Summary
  53. 6. Working with Images and Videos in Responsive Web Design
  54. Third-party image resizing services
  55. The element and the srcset and sizes attributes
  56. Replacing 1x images with 2x images on the fly with Retina.js
  57. Making videos responsive
  58. The Vector Formats
  59. Summary
  60. 7. Meaningful Typography for Responsive Web Design
  61. Calculating relative font sizes
  62. Creating a Modular Scale for a harmonious typography
  63. Using the Modular Scale for typography
  64. Web fonts and how they affect RWD
  65. Sass mixin for implementing web fonts
  66. Using FlowType.js for increased legibility
  67. Summary
  68. 8. Responsive E-mails
  69. Don't overlook your analytics
  70. Recommendations for building better responsive e-mails
  71. Responsive e-mail build
  72. Third-party services
  73. Summary
  74. Index

The Vector Formats

We're going to see some HTML and CSS/SCSS snippets to get an idea of how to work with icon fonts and SVGs, but we're not going to go through the creation of such assets since that process is out of the scope of this section.

Vectors or bitmaps/raster images

When people ask what the difference between vectors and bitmaps/raster images is, the answers I often hear are usually around the idea, "If you enlarge it, it won't lose its quality. No worries for mobile devices." Although true, it doesn't fully answer the question. So here are the differences:

A vector image is a file made out of mathematical equations. The results of these equations are represented by a graphic (lines, shapes, colors). If the size of the image changes in any way, the values of those equations are recalculated and the resulting graphic is painted again.

A bitmap or raster image is a file made out of pixels. These pixels have a specific/defined width, height, and color. If an image is enlarged, the pixels are stretched and that's why the image looks blurry or pixelated.

With those definitions out of the way, let's talk about some of the vector formats used for RWD. Vector formats include:

  • Web fonts
  • Icon fonts
  • SVGs

Let's see how to rapidly implement icon fonts and SVGs; web fonts will be addressed in the next chapter.

Icon fonts

Icon fonts are basically a font file but instead of having letters as glyphs it has, well, icons. Some people love icon fonts (I do), and some aren't really too fond of them, especially since SVG has gained so much popularity.

Let's see the pros and cons of icon fonts.

Some advantages are:

  • Icon fonts are very likely smaller in file size than their SVGs counterparts. We can have many more icons in a single font file and it weighs a lot less than having an SVG sprite.
  • The properties of icon fonts can be modified with any properties used to modify text, for example, color, font-family, font-weight, and so on. After all, it's a font. This means that we don't have to learn any new syntaxes or properties.
  • They are relatively easy to implement. Once all the @font-face properties are set once, calling an icon font is a matter of adding a class to the HTML and calling a specific code called the Unicode Point in the CSS.
  • Icon fonts are vectors so they retain their optimum quality on any screen density, screen size, and zoom level.
  • They're very design-versatile. A single icon font can be wrapped in a colored container, have the icon reserved (knockout), and still be the same icon—no need for a separate file.

Some disadvantages are:

  • Updating a custom-designed icon can take some work, since we'd have to work with a third-party app to generate our icon font files.
  • Icon fonts can only use a single color. I honestly don't think this is a disadvantage.
  • One of the main disadvantages of icon fonts is that implementing a fallback in case the font file doesn't load is a bit complex and if you ask me, verbose. The name of the pattern is "A Font Garde". If you want to read about it, check out Zach Leatherman's post Bulletproof Accessible Icon Fonts (http://www.filamentgroup.com/lab/bulletproof_icon_fonts.html). The GitHub repo can be found at https://github.com/filamentgroup/a-font-garde.

Here are a few recommendations I can give you when using icon fonts:

  • If possible, avoid using them for critical content.
  • Always provide a title="" attribute in the element you're using the icon font on. If the font file fails to load, at least the text in the title tag can be seen.
  • If you're ok with it, use an extra HTML element to hold the icon. If the icon font file fails to load, users with and without assistive technologies can still use the feature the icon font represents.
  • In my years of experience, I have yet to see icon font files failed to load, but that doesn't mean it can't happen. So I recommend staying on top of your server logs to determine if the icon font file is or isn't being downloaded. If it's not, then you need to remedy the issue as soon as possible.

Let's implement an icon font then.

Implementing icon fonts

The fastest way to get icon font files is by using a third party web app like IcoMoon.io or Fontello.com. You can also get a copy of Font Awesome.

Tip

Be careful when considering using Font Awesome. Using a full font file with tenths of icons only to use a fraction of them is wasted bandwidth. If you're only going to use a handful of icon fonts, using IcoMoon.io or Fontello.com for custom icon selection is a better option.

Once you are able to unzip the provided files, the only file you're going to need is the .woff file. The reason you only need this file is because browser support for .woff files goes all the way back to IE9. Unless you want/need to support legacy browsers (desktop and mobile), you can then use .eot, .ttf, and .svg files.

Tip

I recommend that you keep it simple and avoid unnecessary headaches when trying to support icon fonts in legacy browsers. All they get is the text instead of the icon, or display the text in the title="" attribute.

Let's name our icon font file icon-font.woff. Create a /fonts folder and save the icon-font.woff file in it. This is what we are going to try to accomplish: a soft-blue link with an icon on the left, no underline, and 40px Arial/Helvetica font:

Implementing icon fonts

Using a pseudo-element

The great thing about using a pseudo-element is that our source markup always stays clean. In this case, we're going to use the :before pseudo-element, but this technique also works with an :after pseudo-element.

Let's take a look at the build.

This is the HTML snippet:

<a href="#" class="icon icon-headphones" title="Headphones">Headphones</a>

Here's the SCSS. The first thing we need is a mixin to handle any custom web fonts. In this case, it is an icon font:

//Web font mixin
@mixin fontFace($font-family, $file-path) {
    @font-face {
        font: {
            family: $font-family;
            weight: normal;
            style: normal;
        }
    src: url('#{$file-path}.woff') format('woff');
    }
}

Tip

Notice the nested properties in the font: {…} block. By doing this, we keep things DRY and avoid repeating the term font for the following instances: font-family, font-weight and font-style.

Then, we create a rule using attribute selectors to handle the basic styling properties of the icon font:

//Icon Font specific rule
[class^="icon-"], [class*=" icon-"] {
    font: {
        family: icon-font, Arial, "Helvetica Neue", Helvetica, sans-serif;
        weight: normal;
        style: normal;
        variant: normal;
    }
    text-transform: none;
    line-height: 1;
    speak: none;
    // Improve Font Rendering
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

Tip

Notice the ^ and * characters in the attribute selectors. The first one means select elements starting with the term icon- and the second select elements containing the term icon-.

Then, we need to call the fontFace mixin in order to bring the font into the compiled CSS file:

@include fontFace(icon-font, '/fonts/icon-font');

The great thing about the fontFace mixin is that all we need to do is declare the font name and then the file path. There is no need to declare the file extension; that's taken care of by the mixin.

This will compile to:

@font-face {
    font-family: icon-font;
    font-weight: normal;
  font-style: normal;
  src: url("/fonts/icon-font") format("woff");
}

Here is the rule that makes the magic happen using :before:

.icon-headphones:before {
    content: "\e601";
    margin-right: 10px;
}

For basic styling enhancement, we create these other two rules. However, they are not required. The code is as follows:

.icon { font-size: 40px; }

a {
    padding: 5px;
    text-decoration: none;
    color: #2963BD;
    transition: .3s;
    &:hover { color: lighten(#2963BD,20); }
    &:focus { outline: 2px solid orange; }
}

The final compiled CSS looks like this:

[class^="icon-"], [class*=" icon-"] {
    font-family: icon-font, Arial, "Helvetica Neue", Helvetica, sans-serif;
    font-weight: normal;
    font-style: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    speak: none;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
@font-face {
    font-family: icon-font;
    font-weight: normal;
    font-style: normal;
    src: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/9988/icon-font.woff") format("woff");
}

.icon-headphones:before {
    content: "\e601";
    margin-right: 10px;
}
.icon {
    font-size: 40px;
}
a {
    padding: 5px;
    text-decoration: none;
    color: #2963BD;
    -webkit-transition: .3s;
        transition: .3s;
}
a:hover {
    color: #6d9adf;
}
a:focus {
    outline: 2px solid orange;
}

Here's a demo I created for this in CodePen: http://codepen.io/ricardozea/pen/e62b201350efe7f59f91c934f9fc30fa

Here's another demo I created in CodePen with the icon fonts a bit more advanced: http://codepen.io/ricardozea/pen/5a16adffb6565312506c47ca3df69358

Using an extra HTML element

To be honest, using an extra HTML element goes a little against the principle of separating content from styling, since adding an extra HTML element for styling reasons is not something some developers recommend. However, we can also argue that the icon itself really is content, not styling. Either way, here's the run down.

Here's the HTML snippet:

<a href="#" title="Headphones"><i class="icon-headphones" aria-hidden="true"></i>Headphones</a>

Tip

In order to hide irrelevant content from screen readers, we use the aria-hidden="true" directive.

The SCSS code from the previous example is practically the same, except we move the font-size: 10px; declaration from the .icon class to the a rule and then delete the .icon class altogether. You will also see some extra properties but only for styling reasons.

The final SCSS looks like this:

//Web font mixin
@mixin fontFace($font-family, $file-path) {
    @font-face {
        font: {
        family: $font-family;
        weight: normal;
        style: normal;
    }
    src: url('#{$file-path}.woff') format('woff');
    }
}
//Icon Font specific rule
[class^="icon-"], [class*=" icon-"] {
    font: {
        family: icon-font, Arial, "Helvetica Neue", Helvetica, sans-serif;
        weight: normal;
        style: normal;
        variant: normal;
    }
    text-transform: none;
    line-height: 1;
    speak: none;
    // Improve Font Rendering
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
@include iconFont(icon-font, '/fonts/icon-font');
.icon-headphones:before {
    content: "\e601";
    margin-right: 10px;
}
a {
   font-size: 40px;
    //Styling stuff
    padding: 5px;
    text-decoration: none;
    color: #2963BD;
    transition: .3s;
    &:hover { color: lighten(#2963BD,20); }
    &:focus { outline: 2px solid orange; }
}

The compiled CSS looks like this:

[class^="icon-"], [class*=" icon-"] {
    font-family: icon-font, Arial, "Helvetica Neue", Helvetica, sans-serif;
    font-weight: normal;
    font-style: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    speak: none;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

@font-face {
    font-family: icon-font;
    font-weight: normal;
    font-style: normal;
    src: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/9988/icon-font.woff") format("woff");
}
.icon-headphones:before {
    content: "\e601";
    margin-right: 10px;
}

a {
    font-size: 40px;
    padding: 5px;
    text-decoration: none;
    color: #2963BD;
    -webkit-transition: .3s;
          transition: .3s;
}
a:hover {
    color: #6d9adf;
}
a:focus {
    outline: 2px solid orange;
}

Here's a demo I created for this in CodePen: http://codepen.io/ricardozea/pen/8ca49cb06aeb070f4643f0a8e064126c.

Scalable Vector Graphics

SVG graphics have gained incredible popularity very quickly. Browser support is 100 percent, even Opera Mini supports SVG images. Let's discuss some pros and cons of SVG images:

The pros of SVGs:

  • They can be created and edited with a text editor.
  • They are 100 percent accessible.
  • They can have multiple colors.
  • They are SEO-friendly since they can be indexed.
  • Since they are vectors, they maintain their quality on any screen density, screen size, or zoom level.
  • They can be animated, even the elements inside the <svg> tag.
  • The SVG spec is an actual, open standard developed by the W3C.
  • It's arguably more semantic than using a font for graphics.
  • Third-party online icon tools can also export to SVG in addition to icon font.
  • Browser support is 100 percent available in modern browsers.

The cons of SVGs:

  • An SVG sprite file can weigh more than its icon font counterpart.
  • If legacy browser support is required (IE8 and below), an image fallback is required.
  • Software that can save as SVG usually adds extra unnecessary markup in the final file, so we either have to remove it manually or use a third-party optimization tool to do it for us for every file. This in turn adds another layer of complexity to development workflow.
  • Although SVGs are made with XML structure, it requires a pretty advanced level of understanding to perform edits in a text editor.

An SVG file is basically an XML-formatted file. This is what the markup of the headphones graphic looks like:

<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
        <path id="left-ear-pad" d="M9 18h-2v14h2c0.55 0 1-0.45 1-1v-12c0-0.55-0.45-1-1-1z"/>
    <path id="right-ear-pad" d="M23 18c-0.55 0-1 0.45-1 1v12c0 0.6 0.5 1 1 1h2v-14h-2z"/>
        <path id="headband" d="M32 16c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 1.9 0.3 3.8 1 5.464-0.609 1.038-0.958 2.246-0.958 3.5 0 3.5 2.6 6.4 6 6.929v-13.857c-0.997 0.143-1.927 0.495-2.742 1.012-0.168-0.835-0.258-1.699-0.258-2.584 0-7.18 5.82-13 13-13s13 5.8 13 13c0 0.885-0.088 1.749-0.257 2.584-0.816-0.517-1.745-0.87-2.743-1.013v13.858c3.392-0.485 6-3.402 6-6.929 0-1.29-0.349-2.498-0.958-3.536 0.62-1.705 0.958-3.545 0.958-5.465z"/>
</svg>

There are many ways to use SVG images: inline via the <img>, <object>, <use>, or <svg> tags; as background images with CSS; using Modernizr in conditional classes to address fallbacks; or with jQuery or plain JavaScript, using third-party services such as grumpicon.com, you name it.

To keep things simple, we're going to focus on two methods:

  • Inline via the <svg> tag.
  • File-based with the <img> tag.

Inline via the <svg> tag

Inlining SVGs is the go-to method of many web designers and developers. The fact that we can control individual parts of the SVG with CSS and JavaScript makes it very appealing for animations.

One of the drawbacks of inlining SVG markup is that the image is not cacheable. In other words, every time the image appears, the browser has to read the XML of the SVG. If you have too many SVGs on your page, these can potentially be detrimental to the page speed and eventually the user experience. So be careful of the objective of the page and the types of visitors using your website/app.

Here's an HTML snippet of the SVG of the headphones inlined in a link tag:

<a href="#">
    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
        <path id="left-ear-pad" d="M9 18h-2v14h2c0.55 0 1-0.45 1-1v-12c0-0.55-0.45-1-1-1z" />
    <path id="right-ear-pad" d="M23 18c-0.55 0-1 0.45-1 1v12c0 0.6 0.5 1 1 1h2v-14h-2z" />
        <path id="headband" d="M32 16c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 1.9 0.3 3.8 1 5.464-0.609 1.038-0.958 2.246-0.958 3.5 0 3.5 2.6 6.4 6 6.929v-13.857c-0.997 0.143-1.927 0.495-2.742 1.012-0.168-0.835-0.258-1.699-0.258-2.584 0-7.18 5.82-13 13-13s13 5.8 13 13c0 0.885-0.088 1.749-0.257 2.584-0.816-0.517-1.745-0.87-2.743-1.013v13.858c3.392-0.485 6-3.402 6-6.929 0-1.29-0.349-2.498-0.958-3.536 0.62-1.705 0.958-3.545 0.958-5.465z"/>
    </svg>Headphones
</a>

To control its size, distance from the text, and appearance, we add the following CSS:

svg {
    width: 40px;
    height: 40px;
    margin-right: 10px;
    fill: #2963BD;
}
a {
    font-size: 40px;
    text-decoration: none;
    color:#2963BD;
}

Tip

SVGs files called via the <img> tag are not affected by CSS. If you want to make any style changes to it, you have to either make them in the actual SVG file or place the SVG markup inline.

However, this markup has a problem. It doesn't provide a fallback for legacy browsers, specifically IE8 and below. Let's try to fix this.

Providing fallback images to legacy browsers for inline SVGs

There are two ways to provide fallback images to legacy browsers for inline SVGs.

Using the <foreignObject> and <img> tags

Create a <foreignObject> element inside the <svg> tag and include an <img> tag that calls the fallback image:

<a href="#">
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="32" height="32" viewBox="0 0 32 32">
        <path d="M9 18h-2v14h2c0.55 0 1-0.45 1-1v-12c0-0.55-0.45-1-1-1z"/>
        <path d="M23 18c-0.55 0-1 0.45-1 1v12c0 0.6 0.5 1 1 1h2v-14h-2z"/>
        <path d="M32 16c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 1.9 0.3 3.8 1 5.464-0.609 1.038-0.958 2.246-0.958 3.5 0 3.5 2.6 6.4 6 6.929v-13.857c-0.997 0.143-1.927 0.495-2.742 1.012-0.168-0.835-0.258-1.699-0.258-2.584 0-7.18 5.82-13 13-13s13 5.8 13 13c0 0.885-0.088 1.749-0.257 2.584-0.816-0.517-1.745-0.87-2.743-1.013v13.858c3.392-0.485 6-3.402 6-6.929 0-1.29-0.349-2.498-0.958-3.536 0.62-1.705 0.958-3.545 0.958-5.465z"/>
        <foreignObject>
            <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/9988/headphones.png" alt="Headphones">
        </foreignObject>
    </svg>Headphones
</a>
Using an <image> tag

As we all know, there's isn't an <image> tag… or is there? In the SVG world, there is! This solution is very similar to the first method. The two differences are that we do not use a <foreignObject> element and we use an <image> tag. This is all inside the <svg> tag:

<a href="#">
    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
        <path id="left-ear-pad" d="M9 18h-2v14h2c0.55 0 1-0.45 1-1v-12c0-0.55-0.45-1-1-1z" />
        <path id="right-ear-pad" d="M23 18c-0.55 0-1 0.45-1 1v12c0 0.6 0.5 1 1 1h2v-14h-2z" />
        <path id="headband" d="M32 16c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 1.9 0.3 3.8 1 5.464-0.609 1.038-0.958 2.246-0.958 3.5 0 3.5 2.6 6.4 6 6.929v-13.857c-0.997 0.143-1.927 0.495-2.742 1.012-0.168-0.835-0.258-1.699-0.258-2.584 0-7.18 5.82-13 13-13s13 5.8 13 13c0 0.885-0.088 1.749-0.257 2.584-0.816-0.517-1.745-0.87-2.743-1.013v13.858c3.392-0.485 6-3.402 6-6.929 0-1.29-0.349-2.498-0.958-3.536 0.62-1.705 0.958-3.545 0.958-5.465z"/>
        <image src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/9988/headphones.png" xlink:href="" alt="Headphones">
    </svg>Headphones
</a>

Now, the reason this works is because we are combining a feature of SVGs and HTML into one element.

The SVG feature is that the <image> tag is a valid element within the SVG world. Now, as weird it sounds, all browsers see the <image> tag as an out-of-standards tag that resembles the <img> tag from HTML.

The HTML feature is that normally we use the src attribute to point to the asset's location. In the SVG world, assets are called with the xlink:href attribute. If we add a src attribute pointing to the asset and leave the xlink:href attribute empty, then legacy browsers will see the fallback image while modern ones won't because the xlink:href attribute is empty.

I recommend sticking with the second method; it's just more succinct and less hassle. Just remember that instead of <img>, we use <image>. Also, for the purpose of the book, I left the xlink:href attribute in the markup but this is optional. If it's empty, you can remove it altogether if you want.

Tip

Throughout the book, I've taken out the trailing slash /> on self-closing tags such as <hr> or <img> elements, for example. In HTML5, it is ok to go with or without it. However, the trailing slash is required in the path elements in SVGs, that's why you're seeing them here in these examples.

None of these methods I just mentioned cause double download on browsers that support SVG. That's a win-win situation if you ask me.

File-based with the xlink:href and src attributes

SVG is a type of image file, so calling it within an <img> is perfectly valid:

<img src="images/headphones.svg" alt="Headphones">

We know that SVG has flawless support in modern browsers, but the prior image isn't displayed in legacy browsers (IE8 and below).

Remember the previous explanation about the xlink:href and src attributes in SVG and HTML? Well, we're going to do pretty much exactly the same we did there. However, instead of inlining the SVG markup, we're just going to link to an SVG file while providing a fallback image for old browsers.

This clever trick was created by Alexey Ten. Here's the markup:

<a href="#">
    <svg width="39" height="39">
        <image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/9988/headphones.svg" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/9988/headphones.png" width="39" height="39">
    </svg>Headphones
</a>

There are issues here as well. Alexey's technique is not the offender, it is the browsers—specifically IE9, 10 and 11 as well as iOS 3 and 4. They download both the SVG and the fallback image.

If this double download is acceptable for you and you understand the consequences, go for it. Nonetheless, keep a mental note of where you can improve things like this for your next project.

Here's a demo I created for this in CodePen:

http://codepen.io/ricardozea/pen/594e718f36976f8e77d4f9cf1640e29a

Other sources to learn about SVG

We can't talk about SVGs without referencing three of the most noticeable names in the web design and development industry today: Amelia Bellamy-Royds, Sara Soueidan, and Chris Coyer. Amelia and Chris created one of the most complete guides about how to use SVG with fallbacks that I've read, A Complete Guide to SVG Fallbacks (https://css-tricks.com/a-complete-guide-to-svg-fallbacks/).

Sara Soueidan's blog is a must-read if you want to learn everything about SVG: http://sarasoueidan.com/articles/.