Cloud Four Blog

Technical notes, War stories and anecdotes

A Responsive Guide to Type Sizing

When starting new projects, a CSS builder’s initial concerns tend to involve typography. Setting a typographic foundation with the right mixture of ingredients can form something solid enough to support many other building blocks of design. It’s an approach that makes structural sense.

Proportions are a key ingredient to the mixture. Calibrating your type proportions for a balance of aesthetics and order can be an obsessive undertaking. It’s a challenge getting proportions right for a given screen size, let alone any possible screen size. This process can be less challenging — even for responsive designs — if you use a modular scale and let math do the work for you.

Using a modular scale for typographic proportions

In his detailed article on the subject, Tim Brown demonstrates using a modular scale for composing type. He explains how compositions can benefit from using numbers that relate to each other in a meaningful way:

Modular scales[…] help us achieve a visual harmony not found in compositions that use arbitrary, conventional, or easily divisible numbers.

This modulation-based approach is particularly useful for determining type sizes. Selecting sizes using a ratio (instead of guessing) yields a more harmonious range of proportions.

With tools like this indispensable calculator, you can see how different bases and ratios affect your scale. These are the variables in your scale’s equation. The value produced by multiplying or dividing these variables is a step on your scale. Repeating the operation on each resulting value forms a new step:

Step Math Result
+3  40 × 2 80   
+2  20 × 2 40   
+1  10 × 2 20   
 0  none 10   
−1  10 ÷ 2  5   
−2   5 ÷ 2  2.5 
−3 2.5 ÷ 2  1.25
Example with a base of 10 and a ratio of 2

You can also associate each step in the sequence with the number of times the ratio has been multiplied or divided:

Step Math Result
+3 10 × 2 × 2 × 2 80   
+2 10 × 2 × 2     40   
+1 10 × 2         20   
 0 none 10   
−1 10 ÷ 2          5   
−2 10 ÷ 2 ÷ 2      2.5 
−3 10 ÷ 2 ÷ 2 ÷ 2  1.25

Experimenting with base and ratio parameters is a quick way to gauge how much proportional contrast is right for your project. Compare the following scales:

Due to their ratios, these scales have wildly differing degrees of change between each step. The “golden section” ratio yields much more change than the “minor third”. Consider how much change you’re likely to need, and how it correlates with varying screen sizes and content hierarchy.

Comparing two scale ratios

Scales with the ratios of 1.618 and 1.2 compared on modularscale.com

The balance of typographic contrast in scale is dependent on screen size. A scale that works well on a large screen may have too much contrast for a small screen (and feel obtrusive). Likewise, a scale that is harmonious on a small screen may be too subtle when viewed on a large screen.

One solution to this conundrum is to create a scale intended for small screens that is also capable of adapting for large ones. The first thing to consider when creating that scale is which ratio to use.

Step Font size Result
 0   1.0em
Abcdefg
+1   1.2em
Abcdefg
+2  1.44em
Abcdefg
+3 1.728em
Abcdefg
+4 2.074em
Abcdefg
+5 2.488em
Abcdefg
The minor third ratio (1.2) with a base of 1em

The minor third ratio of 1.2 yields a gradually changing range of sizes. They all feel reasonable for small screens, and are distinct enough for levels of typographic hierarchy. At step #5, the resulting size can still be used while retaining a reasonable number of characters per line. With these attributes, this ratio feels like a good selection for small screen proportions.1

Applying your scale from the ground up

After figuring out a scale that works well for your project, you’ll probably want to put it into practice. CSS offers a few options:

  1. Copying and pasting numbers for a bunch of property values
  2. Using preprocessors like Sass with built-in math capabilities
  3. Using the native CSS calc() function

The following examples employ option #3, using PostCSS in order to provide browser support for calc() and var(). If you prefer a different CSS processor, you can apply the same operations with that tool’s own arithmetic and variable syntax.2

For more complex modular scale applications, you should check out these plugins available for PostCSS and Sass:

They provide a cleaner syntax than calc() for getting scale values, and also support multiple values for base and ratio.

Configuring the variables

The first step is to define values for the ratio and base variables that much of the scale logic depends on:

:root {
  --ratio: 1.2;
  --base: 1;
  --base-em: calc(var(--base) * 1em);
  --base-px: calc(var(--base) * 16px);
}

There are three base-related properties defined here. This is to provide flexibility when different CSS units (or no units) are needed.

Next, you need to establish the range of scale steps you’re likely to use:

:root {
  --ms0: 1;
  --ms1: var(--ratio);                    /* 1.2   */
  --ms2: calc(var(--ratio) * var(--ms1)); /* 1.44  */
  --ms3: calc(var(--ratio) * var(--ms2)); /* 1.728 */
  --ms4: calc(var(--ratio) * var(--ms3)); /* 2.074 */
  --ms5: calc(var(--ratio) * var(--ms4)); /* 2.488 */
  --ms6: calc(var(--ratio) * var(--ms5)); /* 2.986 */
  --ms7: calc(var(--ratio) * var(--ms6)); /* 3.583 */
}

With these step properties defined, you can now compute them with your base to get values from your scale:

font-size: calc(var(--base-em) * var(--ms1)); /* 1.2em  */
font-size: calc(var(--base-em) * var(--ms2)); /* 1.44em */

Establishing default sizes

The browser default font-size paired with the scale step of 1.44 for line-height feels like an appropriate choice for body copy:

body {
  font-size: calc(var(--base-em) * var(--ms0));
  line-height: calc(var(--base) * var(--ms2));
}

Headings probably don’t need to consist of six different sizes (as there are other ways to differentiate them). However, if you do wish to incorporate a different size for each, you can use a series of steps from your scale:

h6 { font-size: calc(var(--base-em) / var(--ms1)); }
h5 { font-size: calc(var(--base-em) * var(--ms0)); }
h4 { font-size: calc(var(--base-em) * var(--ms1)); }
h3 { font-size: calc(var(--base-em) * var(--ms2)); }
h2 { font-size: calc(var(--base-em) * var(--ms3)); }
h1 { font-size: calc(var(--base-em) * var(--ms4)); }

In addition to heading font-size, you should also consider the values for line-height.

Using a lower step of the scale in this case can benefit readability when lines are wrapping:

h3, 
h2 { line-height: calc(var(--base) * var(--ms1)); }
h1 { line-height: calc(var(--base) * var(--ms0)); }

With these defaults for body copy and headings in place, you have a nice foundational hierarchy that works well on small screens:

Ratio of 1.2 on a small screen

A scale with a ratio of 1.2 applied to content on a 320×480 screen

Expanding your scale when proportional contrast is needed

Increasing screen sizes and viewing distances will reveal new typographic requirements for your layout. Your body copy and the contrast in scale of all typographic elements will likely need adjustments to suit the new context:

@media (min-width: 480px) {
  html { font-size: calc(var(--base-px) * var(--ms1)); }
}

Bumping the global font size like this is a practical adjustment that requires little effort. While this practice is common, it’s worth noting that even small tweaks like this can leverage steps from your modular scale. Rather than incrementing the size by an arbitrary few pixels or a percentage, you can use your scale to determine the new value.

In line with amplifying your body copy, you might also want to increase the amount of change between each heading size. You can do this by overriding the larger headings with sizes from higher up your scale:

@media (min-width: 768px) {
  h3 { font-size: calc(var(--base-em) * var(--ms3)); }
  h2 { font-size: calc(var(--base-em) * var(--ms4)); }
  h1 { font-size: calc(var(--base-em) * var(--ms5)); }
}
 
@media (min-width: 1024px) {
  h2 { font-size: calc(var(--base-em) * var(--ms5)); }
  h1 { font-size: calc(var(--base-em) * var(--ms6)); }
}
 
@media (min-width: 1360px) {
  h1 { font-size: calc(var(--base-em) * var(--ms7)); }
}

With these size adjustments in place, viewport width will determine how far up the scale your headings are allowed to climb:

(View the full CodePen to see how the text size responds.)

Broadening the usage of your scale

Limiting your scale’s influence to just specific elements would be highly illogical. You want flexible, abstracted styles to build complex interfaces with. Utility classes can provide that flexibility:

.u-textBigger { 
  font-size: calc(var(--base-em) * var(--ms1)); 
}
 
.u-textSmaller { 
  font-size: calc(var(--base-em) / var(--ms1)); 
}

With one ratio relating all the text sizes, anything affected by these classes will adhere to the steps of your scale. Even when combining or nesting the classes, the resulting text will remain in relative proportion:

<div class="u-textBigger">
  <h2>Now I'm as big as an H1</h2>
  <h3>Now I'm as big as an H2</h3>
  <p class="u-textSmaller">I haven't changed at all.</p>
</div>
 
<div class="u-textSmaller">
  <div class="u-textSmaller">
    <div class="u-textBigger">
      <span class="u-textBigger">Same as it ever was.</span>
    </div>
  </div>
</div>

TL;DR

  • Use a modular scale to define your typographic proportions.
  • Create a scale that is flexible enough to work on many screen sizes.
  • Use higher steps from your scale when more proportional contrast is needed.
  • Don’t limit the use of your scale to specific elements.

Further reading


Footnotes
  1. Using one base and one ratio isn’t the only way to arrive at a scale that works within small screen limitations. You can also create a multi-stranded scale by using multiple base or ratio values instead of just one. Here is an example using a secondary base value to shorten the distance between each step. See modularscale.com for a better explanation.
  2. The postcss-cssnext plugin can be used to transform the output of calc() and var().

Donating the proceeds from Responsive Field Day

Our core mission for Responsive Field Day was to put on an event that would benefit the Portland tech community. That mission drove every decision we made including what to do with any money we made.

We decided early on that any proceeds we made would be donated to programs that support open web technologies, the tech community and education. But we didn’t know what program to donate the funds to.

We’ve finally found the right organization! Log Camp

Log Camp is is a not-for-profit school providing technology education and career training for low-income, minority, and foster youth in the Portland Metro area.

Log Camp has launched a holiday campaign to provide laptops for underserved youth in the Portland area. Many of us at Cloud Four remember our first computer and the large impact it had on our lives.

Therefore, we’re donating the proceeds of Responsive Field Day ($3,157.50) towards Log Camp’s holiday campaign.

We want to thank all of attendees and speakers of Responsive Field Day for making this possible. And we encourage you to donate to Log Camp and support its efforts.

Seriously, Don’t Use Icon Fonts

Icons are everywhere. These “little miracle workers” (as John Hicks described them) help us reinforce meaning in the interfaces we design and build. Their popularity in web design has never been greater; the conciseness and versatility of pictograms in particular make them a lovely fit for displays large and small.

But icons on the web have had their fair share of challenges. They were time-consuming to prepare for every intended display size and color. When high-resolution displays hit the market, icons looked particularly low-res and blocky compared to the text they often accompanied.

So it’s really no wonder that icon fonts became such a hit. Icons displayed via @font-face were resolution-independent and customizable in all the ways we expected text to be. Sure, delivering icons as a typeface was definitely a hack, but it was also useful, versatile, and maybe even a little fun.

But now we need to stop. It’s time to let icon fonts pass on to Hack Heaven, where they can frolic with table-based layouts, Bullet-Proof Rounded Corners and Scalable Inman Flash Replacements. Here’s why…

Screen Readers Actually Read That Stuff

Most assistive devices will read aloud text inserted via CSS, and many of the Unicode characters icon fonts depend on are no exception. Best-case scenario, your “favorite” icon gets read aloud as “black favorite star.” Worse-case scenario, it’s read as “unpronounceable” or skipped entirely.

They’re a Nightmare if You’re Dyslexic

Screenshot of icon issue after replacing fonts on GitHub

Many dyslexic people find it helpful to swap out a website’s typeface for something like OpenDyslexic. But icon fonts get replaced as well, which makes for a frustratingly broken experience.

They Encroach on Emoji Turf

Most of the time, we rely on automated tools to choose which Unicode characters are assigned to which icon. But Unicode’s also where our beloved emoji live. If you aren’t careful, they can overlap in confusing (albeit hilarious) ways. My favorite example: Etsy’s “four stars and a horse” bug. More recently, our own Jason Grigsby encountered random fist-bumps on ESPN’s site.

They Fail Poorly and Often

Microsoft's example missing glyph characters

When your icon font fails, the browser treats it like any other font and replaces it with a fallback. Best-case scenario, you’ve chosen your fallback characters carefully and something weird-looking but communicative still loads. Worse-case scenario (and far more often), the user sees something completely incongruous, usually the dreaded “missing character” glyph.

Custom fonts shouldn’t be mission-critical assets. They fail all the time. One look at Bootstrap’s icon-related issues and it’s no wonder why they’re removing them entirely from the next version.

Worse still, many users will never see those fonts. Opera Mini, which frequently rivals iOS Safari in global usage statistics with hundreds of millions of users worldwide, does not support @font-face at all.

They Never Looked Right

Detail of Stackicons' octocat in IE11

The way browsers hint fonts to optimize legibility was never a good fit for our custom iconography, and support for tweaking that behavior is all over the place.

Multicolor icons are even worse. The technique of overlaying multiple glyphs to achieve the effect is impressively resourceful, but the results often look like their printing registration is misaligned.

You’re Probably Doing It Wrong

“But Tyler,” I hear you say. “You’ve completely ignored Filament Group’s Bulletproof Icon Fonts, complete with feature tests and sensible, content-driven fallback solutions.”

And you’re right. Those techniques are great! If you’re using an icon font, you should definitely follow their recommendations to the letter.

But you probably won’t.

What you’ll probably do is adopt whatever your framework of choice has bundled, or drop in some massive free icon font you can use right away. You won’t modify how they work out of the box because that’s really hard to prioritize, especially when they look great on your monitor with virtually no effort at all.

Or maybe you will do the work, designing and curating a custom icon font, choosing your Unicode characters carefully, documenting and evangelizing the importance of implementing your icons in an accessible way with appropriate fallbacks. Then one day, Dave forgets to add a fallback image to that iconographic button he added (which looks great, by the way), which Roberta reuses for her related Pull Request, and before you know it, your app has devolved into a fragile, hack-littered wasteland once more.

These examples are not hypothetical (though names have been changed to protect the innocent). I’ve seen them happen to multiple organizations, all of them starting with the best possible intentions.

There’s Already a Better Way

SVG is awesome for icons! It’s a vector image format with optional support for CSS, JavaScript, reusability, accessibility and a bunch more. It was made for this sort of thing.

But I hear a lot of excuses for why teams avoid using it, even for brand-new projects. Here are a few…

“SVGs can’t be combined into sprites.”

They totally can. There are even really great tools like svg-sprite and IcoMoon that can help automate that process.

“SVGs are larger in file size.”

Usually when I hear this, the team’s comparing a single binary icon font to multiple, uncompressed SVG files. The gap narrows dramatically when you optimize your SVGs, combine reusable ones into sprites, and deliver those with active Gzip compression or embedded in-page.

Occasionally I’ve heard the gap is still too wide when hundreds of icons are included. This begs the question: Why are you including hundreds of icons on every page?

“The icon markup is too verbose by comparison.”

Let’s compare:

<!-- Typical @font-face icon: -->
<span class="icon icon-search" aria-hidden="true"></span>
 
<!-- Typical SVG icon: -->
<svg class="icon">
  <use xlink:href="path/to/icons.svg#search"/>
</svg>

The SVG markup is barely more verbose, and way more descriptive and semantic than some empty, ARIA-hidden <span> element.

“Browser support for SVG is worse.”

As of this writing, global support for SVG is up to 96%… 4% higher than the same stat for @font-face. Plus, SVGs are way more accessible and their fallbacks are much more straightforward.

“The framework we chose already has an icon font.”

If your framework told you to jump off a bridge, would you?

Don’t Be “Table Guy”

I was in school when the Web Standards movement hit critical mass. While the majority of my instructors saw the merits of semantic markup and embraced it wholeheartedly, one passionately held out. “Table Guy” argued that no layout tool could usurp <table>, that it was inherently better-suited for crafting grid-based designs. He boasted of how quickly and easily he could achieve the “Holy Grail” layout with his trusty table cells. He cited the wealth of cross-browser inconsistencies that continued to plague CSS.

Table Guy and I kept in touch. Today, he freely admits he was wrong about CSS. He feels embarrassed to have been so married to a technique that was so clearly misappropriated in hindsight.

If you won’t stop using icon fonts for people with screen readers, people with dyslexia, people with browsers that don’t support @font-face, people who randomly didn’t load the icon font once for some reason, or designers who just want their icons to look right on-screen…

Then do it for yourself. Don’t be Table Guy.

SVG 101: A Gentle Introduction

Fun fact: Cloud Four’s design team really digs SVG. Our enthusiasm for the image format accumulated gradually over many months, thanks in large part to Sara Soueidan’s tireless documentation of its most mysterious features and quirks. It was during the process of designing the Responsive Field Day site that our collective interest level hit fever pitch, which caused our coworkers to wonder what all the fuss was about!

It turned out to be a difficult question to answer. Most of the resources we found online either covered the very basics of the format, or jumped right into the nitty-gritty of coordinate systems, complex animation, automated sprite-building, etc. So fellow Cloud Four designer Sara Lohr and I decided to put together an internal presentation with reveal.js to bring everyone up to speed.

SVG 101: A Gentle Introduction →

Perhaps unsurprisingly, we learned a ton from the process of organizing what we thought we knew about SVG into a presentation format. Sections were revised multiple times as we uncovered new information. At one point I even engaged with Sara Soueidan and GreenSock on Twitter to help demystify the landscape of JavaScript-powered SVG animation frameworks… and by now that info is already out of date!

In spite of those challenges, the talk was a hit. I think we introduced concepts in a way that made sense for the audience, emphasizing the sorts of things they’d find most useful day-to-day.

Then again, maybe it’s just easy to win people over with demos like “Jasonflower”:

See the Pen Jasonflower: CSS by Tyler Sticka (@tylersticka) on CodePen.

It’s hard to argue that SVG isn’t the greatest format ever once you’ve seen that.

The web’s lost opportunity to be on TV

Apple announced the new Apple TV yesterday. As many expected, it didn’t come with Safari. What was unexpected is that it doesn’t appear to have WebKit at all.

The utility of WebKit for app developers seems straightforward. Apps often use embedded web views to display information that it doesn’t make sense to duplicate in native code or for rendering links that people share.

TV_AppleTV_Remote_800

But without webkit available for tvOS, there will be no embedded web views and no third party browsers.

We now have both Apple TV and Android TV without the web, and it’s a bloody shame.

I’m well aware of the argument that people don’t want to browse the web on TVs. I believe the jury is still out on that one, but even if I concede that point, there is still tremendous utility in using web technology for building apps for TVs.

The reason I started researching the web on TVs dates back to the original Google TV Showcase. There was a Vimeo app in that showcase that I loved.

Vimeo couch mode screenshot

I used that app for several months before I accidentally hit a button that converted it from the TV app that I knew into the standard Vimeo web page.

I had inadvertently discovered that the Vimeo app was just a different view of Vimeo’s normal web page. Vimeo calls this couch mode.

Nintendo, Samsung, LG, and others have all built app platforms on top of HTML. For years, Netflix built all of their TV apps on HTML5 before recently going native.

Web apps on TVs can be great experiences. Maybe it is because we don’t notice the lag as much when we’re using remote controls instead of touching the interface directly. Maybe it is because the interfaces for most non-game, TV apps are fairly simple.

Whatever the reason, building TV apps using web technology just seemed to work. Bridging the gap between native and web apps on TVs was easier than it was on mobile.

But year after year at Google I/O when I’d try to talk to people about Chrome on TVs, I wouldn’t get anywhere. Google TV shipped with Chrome, but it was a forked version that the Chrome team wasn’t responsible for and grumbled about.

I remember trying desperately to figure out who to talk to about the browser on Google TV. I was repeatedly and humorously pointed to Chris Wilson. Chris hadn’t working on Google TV in months. It became a running joke between the two of us.

I found this photo of Android TV on the Android TV site. The name of the file was lessbrowsing.jpg.

A couple years later, Google announced that their TV product would be called Android TV. Google touted how the TV would finally be running the same version of Android as phones and tablets. It would be kept up to date.

Except it would no longer have a browser.

At the time, Microsoft showed more interest in the web on TVs than Google. That may still be the case. I haven’t checked in awhile. Firefox OS has recently moved to TVs and Opera still has a TV browser. So all hope isn’t lost.

Back in 2012, I was trying to muster enthusiasm in browser makers for working on the web on TVs. It seemed likely that TVs were going to be the next platform and instead of playing catch up like the web did on phones, we could be ready for the web on TVs from the beginning.

I feared playing catch up again. In retrospect, I should have feared much worse.

The two biggest mobile operating systems are now on TVs. One started with a browser, but no longer has one. The other just shipped without even an embedded web view.

From what I’ve seen, the web on TV could have been a star. What a missed opportunity.