Loading Fonts

Now that we have a better idea of what fonts we want to use and the font stack we’ll see how to load them into the page. We’ll explore 3 ways: local loading using the @font-face syntax, loading fonts using the Google font API, using Google’s Web Font Loader and a new tool called Font Face Observer

@font-face

We have been able to use fonts on our web content since the days of IE 3 (3.5 for Macintosh if I remember correctly) but we’ve always had to contend with font creators and foundries fear of piracy. It’s only recently that they have relented and allowed their fonts to be used. The basic syntax, covering all modern browsers, looks like this:

@font-face {
    font-family: 'stone-sans-webfont';
    src: url('../path-to-font-file.eot');
    src: url('../path-to-font-file.eot?#iefix') format('embedded-opentype'),
         url('../path-to-font-file.woff2') format('woff2'),
         url('../path-to-font-file.woff') format('woff'),
         url('../path-to-font-file.ttf') format('truetype'),
         url('../path-to-font-file.svg#stone-sans-webfont') format('svg');
    font-weight: normal;
    font-style: normal;
}

And then we associate the font with CSS like we normally would matching the font-family attribute in the @font-face declaration with the font-family attribute of the element where we want to use it:

html {
        font-family: 'stone-sans-webfont', arial, sans-serif;
}
        

Since we want to avoid faux bold and faux italics in our content, we add the bold and italics versions of our font to the page and then match them to the correct attributes with selectors similar to this:

strong {
  font-family: 'Stone-Humanist-Semi';
}

em {
  font-family: 'Stone-Humanist-Ita';
}

/*
  When using both we don't care what order they are used in
*/
strong em,
em strong {
  font-family: 'Stone-Humanist-SemiItalic';
}

Where Stone-Humanist-Semi is our (semi)bold font, Stone-Humanist-Ita is italics and Stone-Humanist-SemiItalic is the semibold italics combination. Since <b> and <i> have different semantic meaning in HTML5 I’ve chosen not to style them.

Some things to keep in mind

Adding the font to your site/book/app adds to the overall file size. Depending on the font this may increase the size of your project considerably. Taking Gentium as an example, the font supports Latin, Greek and Cyrillic character sets but it weighs a hefty 500k for the regular font (in one format out of the 5 formats needed to support multiple browsers/devices). Add Bold, Italic and you get 1.5 Megabytes just for the font! And it may not be the only font you use in the project.

The flipside to this issue of size is that embedding the fonts means they are always available to desktop and mobile browsers readers that support embedding (and it should be all of them.) Choosing what browsers and what versions to support is a different story.

Google Fonts API

Google has two ways of using web fonts, the first one is directly through their API. Using Google’s font API is a two step process. First add the font to your html head element with the following syntax (using Tangerine as an example):

<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine">

The link produces a CSS @font-face declaration that we can use in our CSS as normal. The version produced in Chrome and Firefox uses the woff2 format

@font-face {
  font-family: 'Tangerine';
  font-style: normal;
  font-weight: 400;
  src: local('Tangerine'), url(http://fonts.gstatic.com/s/tangerine/v6/HGfsyCL5WASpHOFnouG-RJBw1xU1rKptJj_0jans920.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}

While Safari uses True Type to render the font.

@font-face {
  font-family: 'Tangerine';
  font-style: normal;
  font-weight: 400;
  src: local('Tangerine'), url(http://fonts.gstatic.com/s/tangerine/v6/HGfsyCL5WASpHOFnouG-RCZ2oysoEQEeKwjgmXLRnTc.ttf) format('truetype');
}

As you can see the advantage of using the APi is that we don’t need to use multiple formats in our @font-face declaration. Google takes care of that for us.

The obvoius disadvantage is that this only works online. That’s why a fallback option or options is even more important when working with the API. If we’re offline or connectivity is limited we want a good fallback font.

Google web font loader

One of the things neither the font API or directly downloading the content doesn’t address is the “flash of unstyled text.” According to the Typekit Help Center:

Fonts are loaded as assets into a web page—just like images or video. Depending on your browser or your connection speed, they can load quickly or lag behind the rest of the page. Different browsers handle font loading differently; for example, Safari and Chrome will refrain from displaying text set in a web font until the font has loaded, while Internet Explorer won’t show anything on the page until the font loads. Meanwhile, Firefox will display the site with the fallback fonts in the font stack, and then switch to the linked fonts after they’ve finished loading. This results in a flash of unstyled text, or FOUT.

Typekit, in collaboration with Google, has created loader library to make working with type easier. It works by adding scripts to the page that load the library and tell it what fonts to download and use. For example to load the Droid Sans font from Google you’d use code like this:

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>
<script>
  WebFont.load({
    typekit: {
      id: 'xxxxxx'
    },
    custom: {
      families: ['Droid Sans', 'Source Code Pro'],
    },
    google: {
      families: ['Droid Sans', 'Droid Serif'],
      text: 'abcdedfghijklmopqrstuvwxyz!'
    },
    fontdeck: {
      id: 'xxxxx'
    },
    monotype: {
      projectId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
      version: 12345 // (optional, flushes the CDN cache)
    }
  });
</script>

Or using asynchronous loading:

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>
<script>
  WebFontConfig = {
    google: { families: [ 'Lora:400,700,400italic,700italic:latin' ] }
  };
  (function() {
    var wf = document.createElement('script');
    wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
      '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
    wf.type = 'text/javascript';
    wf.async = 'true';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(wf, s);
  })();

<noscript>
  <link href='http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
</noscript>

For an explanation of the values for each foundry check the Font Loader’s readme file in Github.

The font loader creates a set of events, both CSS and Javascript, for developers to interact with. This is similar to the way Modernizr handles feature detection. The Javascript classes are:

  • loading – This event is triggered when all fonts have been requested.
  • active – This event is triggered when the fonts have rendered.
  • inactive – This event is triggered when the browser does not support linked fonts or if none of the fonts could be loaded.
  • fontloading – This event is triggered once for each font that’s loaded.
  • fontactive – This event is triggered once for each font that renders.
  • fontinactive – This event is triggered if the font can’t be loaded.

CSS events are implemented as classes on the html element. The following classes are set on the html element and correspond to the descriptions above:

  • .wf-loading
  • .wf-active
  • .wf-inactive
  • .wf-<familyname>-<fvd>-loading
  • .wf-<familyname>-<fvd>-active
  • .wf-<familyname>-<fvd>-inactive

The <familyname> placeholder will be replaced by a sanitized version of the name of each font family in lowercase with only alphanumeric characters. For example, Droid Sans becomes droidsans. The <fvd> placeholder is a Font Variation Description, a shorthand for describing the style and weight of a particular font.

So why would we use the Font Loader?

In short: to make the user’s experience less jarring. Since fonts are downloaded as any other resource in your web page. If we use the following font stack: 'stone-sans-webfont', arial, sans-serif, we can then use the Font Loader Defined classes to make the transition to our fonts smoother and better looking. Let’s look at one possibility:

.wf-inactive body{
  font-family: arial, sans-serif;
  line-height: 1.4em;
}

.wf-active body {
  font-family: 'stone-sans-webfont', arial, sans-serif;
  line-height: 1.3
}
     

.wf-inactive indicates that loading the font or fonts (in this case we are using one) has not started. To make sure that the user doesn’t see a system fault we provide a fallback option while the web font(s) are loading. This may be an instant or maybe several seconds in a slow or congested network connection (try Starbucks on a Sunday afternoon.)

Once the font(s) load, the class will switch to .wf-active where we put out web font stack and attributes related to font. In this case I only added a different line-height attribute to the selector but you can be as detailed as you want.

One last detail: What happens if Javascript is disabled?

If you’re fonts are loaded from google you can revert back to using the Google API to load your fonts. You can do something like:

<noscript>
  <link href='http://fonts.googleapis.com/css?family=Roboto:700italic,300,700,300italic' rel='stylesheet' type='text/css'>
</noscript>

Font Face Observer

As good as the Webfont Loader is good it causes some Flash of Invisible text when the fonts load and the browser switches from the system fonts to the webfonts it just loaded. The script for the Webfont Loader must be placed in the head of the document with all the performance pitfalls inherent to it.

Font Face Observer, a fairly new delivery mechanism developed by Adobe Typekit engineer Bram Stein, uses JavaScript’s scroll events to load and monitor web fonts. Unlike the Web Font Loader, the Font Face Observer can be referenced at the end of document to avoid the extra overhead. Scott Jehl’s approach, as documented in the Filament’s Group blog and is the system we’ll discuss below. The full page is shown below and will be explained as we go along.

<!DOCTYPE html>
<!--#if expr="$HTTP_COOKIE=/fonts\-loaded\=true/" -->
<html lang="en" class="fonts-loaded">
<!--#else -->
<html lang="en">
<!--#endif -->
<head>
  <meta charset="utf-8">
  <title></title>
  <meta name="viewport" content="width=device-width">
  <style>
  @font-face {
    font-family: 'Lora';
      src: url('lora-regular.woff2') format('woff2'),
           url('lora-regular.woff') format('woff'),
           url('lora-regular.ttf') format('truetype');
    font-weight: 400;
    font-style: normal;
  }
  @font-face {
    font-family: 'Lora';
      src: url('lora-italic.woff2') format('woff2'),
           url('lora-italic.woff') format('woff'),
           url('lora-italic.ttf') format('truetype');
    font-weight: 400;
    font-style: italic;
    }
    body {
        font-family: serif;
  }
    .fonts-loaded body {
        font-family: Lora, serif;
  }
</style>
</head>
<body>
    <p><!-- paragraph text --></p>
    <script src="fontfaceobserver.js"></script>
    <script>
    (function( w ){
    if( w.document.documentElement.className.indexOf( "fonts-loaded" ) > -1 ){
        return;
    }
    var font1 = new w.FontFaceObserver( "Lora", {
        weight: 400
    });
    var font2 = new w.FontFaceObserver( "Lora", {
        weight: 400,
        style: "italic"
    });
    w.Promise
        .all([font1.check(), font2.check()])
        .then(function(){
            w.document.documentElement.className += " fonts-loaded";
        });
    }( this ));
    </script>
</body>
</html>

The first thing we do is to use Server Side Includes, a way to have the server generate pieces of content for the web, to add the fonts-loaded CSS class if the corresponding cookie has already been set. In this way the loader will only use the fonts if they’ve been already been loaded, otherwise it will not add the class and the process will continue.

<!--#if expr="$HTTP_COOKIE=/fonts\-loaded\=true/" -->
<html lang="en" class="fonts-loaded">
<!--#else -->
<html lang="en">

While still in the head of the document we load our fonts using the @font-face syntax we discussed earlier and associate the fonts with the css needed. Note that we have two classes for the body, a plain one where only system fonts are used and a version with the fonts-loaded class where the webfont is the primary and the system font is our backup.

  <style>
  @font-face {
    font-family: 'Lora';
      src: url('lora-regular.woff2') format('woff2'),
       url('lora-regular.woff') format('woff'),
       url('lora-regular.ttf') format('truetype');
    font-weight: 400;
    font-style: normal;
  }
  @font-face {
    font-family: 'Lora';
      src: url('lora-italic.woff2') format('woff2'),
       url('lora-italic.woff') format('woff'),
       url('lora-italic.ttf') format('truetype');
    font-weight: 400;
    font-style: italic;
  }

  body {
    font-family: serif;
  }
  .fonts-loaded body {
    font-family: Lora, serif;
  }
</style>

At the bottom of our pages, along with all the other scripts, we add a link to the fontfaceobserver library. The second script begins with a conditional check to see if the class-loaded class hs been added to the root element (html); if it has been then quit, there is nothing left to do.

We next define variables for each of the fonts we will use in our document. This will be used in the last part of the script, discussed below.

<script src="fontfaceobserver.js"></script>
<script>
(function( w ){
  if( w.document.documentElement.className.indexOf( "fonts-loaded" ) > -1 ){
      return;
  }
  var font1 = new w.FontFaceObserver( "Lora", {
      weight: 400
  });
  var font2 = new w.FontFaceObserver( "Lora", {
      weight: 400,
      style: "italic"
  });
    

The last part of the script uses a JavaScript promise. Once both promises fulfill it will add the fonts-loaded class to the document (root) element, in this case, html.

w.Promise
  .all([font1.check(), font2.check()])
  .then(function(){
      w.document.documentElement.className += " fonts-loaded";
  });
}( this ));
    </script>

The next result is that the fonts will be loaded asynchronously and that the system font assigned to an element will only change after the font has loaded. This prevents flashes of unstyled content and flashes of invisible content. But in the end which font loading strategy you use is up to you.

Links and Resources

Font Selection

All type shares characteristics. We’ll look at some of them before we dive into selecting font stacks and other type related element. As we move along we’ll discover that these elements are all interrelated and that changing one of these elements will force changes in others too.

Visual representation of type related terms
Visual representation of type related terms

X-height

When you look at your text what is the size of the lowercase glyphs/letters to uppercase? In different fonts the height of lowercase glyphs (measured by the x-height) can be different, some of them being barely half the uppercase height and in others being as tall as two-thirds of the uppercase height.

When looking at type, particularly when you’re testing your content in your chosen typeface and size, make sure that the size is not too small to read. When the height of the lowercase gets too small for the size you chose it gets too hard to read.

Glyph Apertures

Aperture refers to the spacing between open points in letters like ‘c’, ‘e’ or ‘a’. If these apertures are too close the letter can be confused with a lowercase ‘o’ and make the reader’s experience harder than it needs to be

Even Spacing

Make sure that the space between the glyphs and the width of the glyphs in the font you choose are constant and not too far or to close to each other. This constant spacing will make your text easier to read or scan online

Clear Terminals

Terminals are the flourishes at the end of the letters a, c, f, j, r, and y. They can be classified according to the shape: ball (circular), beak (spur), and teardrop (globular).

In long-form text, letters with clear terminals (distinguishable shapes of ball, beak, or teardrop) are easier to spot; therefore, they are more readable than letters with lacking terminals.

Distinguishable Ascenders & Descenders

Ascenders (the lines above the main body of a glyph) and descender (the line below) help make characters easier to read. When you’re choosing typefaces, contrast sans-serif versus serif type to see the difference in how the ascenders and descenders look. For a bad example look at Helvetica.

Styles & Weights

When we see bold and italics on the web, we usually see the browser’s interpretation of bold and italics not the actual italic and bold versions of the chosen typeface.

To make sure that this doesn’t happen to you, make sure that the typefaces you work with have at least 4 versions:

  • Regular
  • Bold
  • Italic
  • Bold Italic

If one of the style fonts are not available then you’re at the browsers’ mercy regarding how bold and italics will render for your page.

Contrast

In this context, contrast refers to the differences between thick and thin strokes of the font. When working with body copy the thin strokes may disappear or the think strokes may overwhelm the rest of the text.

To make sure none of these situations happen pick a font with low or no contrast.

Context

Until now we’ve looked at the technical aspects of type where we will use the typeface is also important. Context has more to do with how the type feels. If you’re developing responsive sites, does the type feel too tight or constrained in larger screens? Does it feel too loose in smaller displays? The goal is to find typeface that works consistently across your target devices.

Font stacks

Unless you’re using one of the universal fonts, those available everywhere, you will most likely have to plan for what happens if your browser cannot load the font because your internet connection just died or you got caught using a font that you were not licensed to use. That’s where you use the font stack.

html {
  font-family: 'Museo Sans', Verdana, sans-serif;
}

The browser will use Museo Sans, if is available in a format that the browser can read, if it isn’t then the browser will use Verdana and… in the unlikely event that verdana is not available the browser will use the system’s default sans serif font.

Why is this important, you may be asking. Because not all fonts are the same. Even fonts that look very similar may be different enough to cause problems with your layout. Let’s look at the same Lorem Ipsum text in two different fonts.

The first example will use Stone Humanist, the font I chose for the body text in this document.

See the Pen Example using Stone Humanist by Carlos Araya (@caraya) on CodePen.

The second example uses Verdana, a font created for and released by Microsoft in 1996.

See the Pen Font Example Using Verdana by Carlos Araya (@caraya) on CodePen.

Notice, in particular, how Verdana’s characters are wider and therefore make the line have less content when compared with Stone Humanist. As a further experiment change the front in Example 2-2 from Verdana to Arial and see the difference.

“Web Safe” Fonts

Ever since browsers started using fonts they’ve been able to use fonts available on the user’s system. These are the “web safe” fonts.

CSS Font Stack presents a list of some of the most common desktop fonts that are installed in Macintosh and Windows operating systems. As you can see there are a few fonts that are really safe to use across platforms.

This is yet another consideration when building our font stack. If we build backups other than generic fonts we need to be careful to pick fonts that are wide used or pick 2 or more options to cover both Windows and Macintosh cases.

Generic font families

Most of the time we have a certain font selected for our project and most of the time they will work ok. But what happens when they don’t?

As we saw in the earlier examples the typeface you choose will affect number of words you can fit in a line of text and the way the font writes on screen may look different with the same line height

CSS defines a number of generic font families for use with your content. These families are (with definitions taken from the CSS 2.1 specification):

serif
Glyphs of serif fonts, as the term is used in CSS, tend to have finishing strokes, flared or tapering ends, or have actual serifed (including slab serifs). Serif fonts are typically proportionately-spaced. They often display a greater variation between thick and thin strokes than fonts from the ‘sans-serif’ generic font family. CSS uses the term ‘serif’ to apply to a font for any script, although other names may be more familiar for particular scripts, such as Mincho (Japanese), Sung or Song (Chinese), Totum or Kodig (Korean). Any font that is so described may be used to represent the generic ‘serif’ family.
sans-serif
Glyphs in sans-serif fonts, as the term is used in CSS, tend to have stroke endings that are plain — with little or no flaring, cross stroke, or other ornamentation. Sans-serif fonts are typically proportionately-spaced. They often have little variation between thick and thin strokes, compared to fonts from the ‘serif’ family. CSS uses the term ‘sans-serif’ to apply to a font for any script, although other names may be more familiar for particular scripts, such as Gothic (Japanese), Kai (Chinese), or Pathang (Korean). Any font that is so described may be used to represent the generic ‘sans-serif’ family.
cursive
Glyphs in cursive fonts, as the term is used in CSS, generally have either joining strokes or other cursive characteristics beyond those of italic typefaces. The glyphs are partially or completely connected, and the result looks more like handwritten pen or brush writing than printed letterwork. Fonts for some scripts, such as Arabic, are almost always cursive. CSS uses the term ‘cursive’ to apply to a font for any script, although other names such as Chancery, Brush, Swing and Script are also used in font names.
fantasy
Fantasy fonts, as used in CSS, are primarily decorative while still containing representations of characters (as opposed to Pi or Picture fonts, which do not represent characters).
monospace
The sole criterion of a monospace font is that all glyphs have the same fixed width. (This can make some scripts, such as Arabic, look most peculiar.) The effect is similar to a manual typewriter, and is often used to set samples of computer code.

Using a generic family as the last item in your font stack is essential. The system is guaranteed to be available and you can style your content with this in mind. It also makes your CSS less susceptible to slow connections or network failures.

Additional Considerations

There are a couple more elements to consider when selecting a font. They may not seem as important but when put together with everything else we’ll discuss in this page, it’s a lot more important than we give it credit for.

Font size

Even when working with Desktop Operating Systems alone a font may look very different. It doesn’t necessarily have anything to do with the design and all with how the operating system renders fonts and it may not even happen but this is something to consider when testing.

Smaller sizes may cause font details to disappear as the font grows smaller. This may affect the typeface you use for your body text, particularly in smaller devices.

Fonts have become more interesting when particularly since Apple released ‘Retina’ iPhones and iPads and Android phones have been released with even higher pixel density. While the higher density allows you to use more typefaces, your design must still consider browsers with lower pixel density in your design.

This page displayed during development in Chrome for OSX

Content displayed in Microsoft Edge running in a Windows 10 virtual machine

Line height

In CSS line-height control the vertical space between lines. It can help readability and make it easier for people with disabilities to engage with your content.

p {
  font: 1em/1.5 arial, helvetica, sans-serif;
}

Which is equivalent to this, much more verbose, syntax:

p {
  font-family: arial, helvetica, sans-serif;
  font-size: 1em;
  line-height: 1.5;
}

I personally prefer the second syntax. It’s explicit in telling you what each attribute controls and it saves you from having to remember what does each part of the expression means. That said you’re more than welcome to use either syntax.

So why do we care about line height. In the example below change the line height attribute, play with values from 1 to 2 or even 3 and see the difference. Which one is more comfortable to read?

See the Pen Line Height Example by Carlos Araya (@caraya) on CodePen.

Line width

 

Anything from 45 to 75 characters is widely regarded as a satisfactory length of line for a single-column page set in a serifed text face in a text size. The 66-character line (counting both letters and spaces) is widely regarded as ideal. For multiple-column work, a better average is 40 to 50 characters. Robert Bringhurst’s The Elements of Typographic Style, (p.26)

Until I started working with web type I had never considered line length as an element when building content. But it makes sense, the longer a line of text is the more we need to be mindful when working with it. In the example below, the text at the same width looks significantly different when we adjust the line height.

See the Pen Line Length Example by Carlos Araya (@caraya) on CodePen.

So what should the stack look like?

So, after all these conversations about different types of typefaces, fonts, availability and when to use and not to use them, what should a good font stack look like?

As with many thing in the web it depends. If you were given fonts as part of your design brief then you should follup up with the designer regarding fall back fonts.

If this is your design then I’d suggest sites like Fonts in use or Typewolf to see how other people are using fonts. Another way is to identify a font you like (like I did with the body font for this page), research whether it’s available as a web font and how much would it cost to license.

Once you know what font you want to use, there are services like Typecast to see what the font will look like in an actuall web page… you can even add chunks of your own content to get a more acurate picture of what the typeface will look like with your content.

My default font stack for this project looks like this:

html {
  font-family: 'Stone-Humanist', arial, sans-serif;
}
        

I use a different stack for headings and this will be discussed when we talk about headings in more detail.

Type Terminology and Definitions

Before we dive into Type selection we’ll do a few things: clear terminology and setup some common definitions to work from. The first one is the difference between typeface and font and then we’ll dive into a short (and incomplete) glossary of typographical terms

Font versus Typeface

I’ve been guilty of this: use font and type face interchangeably. They are most definitely not the same thing and should not be used as if they are.

Typeface refers to the design of the font.

Fonts is the media that contains typefaces and allows you to use them in your projects.

The best analogy I’ve heard about is that the relationship between typeface and font is analogous to the relationship between music and mp3. One is the content and the other is the media that content is delivered in.

For more information, check out font or typeface and Styles, Weights, Widths — It’s All in the (Type) Family both at Fontfeed.com.

Font Glossary

Visual representation of type related terms
Visual representation of type related terms

Definitions taken from Fontshop’s Typography Glossary and Typography Deconstructed’s Type Glossary

Uppercase
The capitals in a typeface. The name refers to the days of metal type, as the capitals were kept in the upper part of the type case.
The capital letters of the alphabet are uppercase glyphs. Uppercase letters are normally used at the beginning of sentences and as the first letter of proper names.
Lowercase
The small letters in a typeface. The name refers to the days of metal type, as the small letters were kept in the lower part of the type case.
The little letters or non-capital letters of the alphabet are lowercase glyphs. They make up the bulk of written text, with uppercase or capital letters used primarily only to start sentences or proper names.
Typeface
An artistic interpretation, or design, of a collection of alphanumeric symbols. A typeface may include letters, numerals, punctuation, various symbols, and more — often for multiple languages. A typeface is usually grouped together in a family containing individual fonts for italic, bold, condensed, and other variations of the primary design. Even though its original meaning is one single style of a type design, the term is now also commonly used to describe a type family (usually only with the basic styles regular, italic, bold, bold italic).
Font
(also, fount) A collection of letters, numbers, punctuation, and other symbols used to set text (or related) matter. Although font and typeface are often used interchangeably, font refers to the physical embodiment (whether it’s a case of metal pieces or a computer file) while typeface refers to the design (the way it looks). A font is what you use, and a typeface is what you see.
Ascender
Any part in a lowercase letter that extends above the x-height, found for example in ‘b’, ‘d’, ‘f’, ‘h’, ‘k’, etc. Some types of ascenders have specific names.
The ascenders of some letters may touch or almost touch letters in the line above causing awkward or distracting patterns. This is most likely to happen or be obvious when a line of text with tall ascenders is below a line of text with long descender. To resolve the problem of touching ascenders and descender you can: Increase the leading (line spacing) between lines of type; Choose a different typeface; For headlines and subheads, some careful editing/re-wording can eliminate the problem; Changing the alignment of the text may also help
Axis
An imaginary line drawn from top to bottom of a glyph bisecting the upper and lower strokes is the axis. The slant of the axis (or lack thereof) often helps determine the type classification.
An imaginary line drawn from top to bottom of a glyph bisecting the upper and lower strokes is the axis. For typefaces that exhibit changes in the thickness of curved strokes, the inclination of the axis of the lowercase o is used to measure the angle of stress. A completely vertical axis indicates a design with an angle of 0 or vertical stress. When the axis leans to the left or right the design has angled (positive or negative) stress. Early styles of typefaces generally shared similar axis or stress angles.
The axis or design axis is also an adjustable attribute of some fonts, such as Multiple Master fonts. Adjusting the design axis results in variations in the weight, width, size, and other features of the typeface.
Bracket
The bracket is a curved or wedge-like connection between the stem and serif of some fonts. Not all serifs are bracketed serifs.
Baseline
The imaginary line upon which the letters in a font appear to rest.
Cap Height
The height from the baseline to the top of the uppercase letters (not including diacritics).
Beak
A triangular, serif-like protrusion at the end of a stroke in certain serif type designs.
Spine
The main curved stroke in the letter ‘S’ and ‘s’.
Counter
The enclosed or partially enclosed circular or curved negative space (white space) of some letters such as d, o, and s.
Descender
Any part in a lowercase letter that extends below the baseline, found for example in g, j, p, q, y, etc. Some types of descenders have specific names.
For contrast, see Ascender
Diacritics
A diacritic is a ancilliary mark or sign added to a letter. Accents are one type of diacritics. In the Latin alphabet their function is to change the sound value of the letters to which they are added; in other alphabetical systems like Arabic or Hebrew they may indicate sounds (vowels and tones) which are not conveyed by the basic alphabet.
Shoulder
The curved part projecting downward from a stem in the lowercase ‘h’, ‘m’, ‘n’.
Small Caps (SC)
Small caps are capital letters that are approximately as high as the x-height of the lowercase letters. When properly designed small caps are absent in the selected font, many applications can create small caps by scaling down the capitals. However this makes these fake small caps too light and narrow, and they don’t harmonize properly with the lowercase. Originally small caps were only available for the roman text weight(s), but nowadays many type families also have them for the italic styles and the bolder weights.
When small caps are built-in as OpenType features, certain (older) operating systems and applications will not be able to access them.
Spacing
Spacing refers to the distribution of horizontal space on both sides of each character in a font to achieve a balanced and even texture. Spacing problems in difficult letter combinations (exceptions) are solved with kerning. Well-spaced fonts need comparatively less kerning pairs.
Kerning
Kerning refers to the horizontal space between individual pairs of letters (a kerning pair), and is used to correct spacing problems in specific letter combinations like “VA”. Well-spaced fonts need comparatively less kerning pairs. Fonts that are properly kerned appear evenly spaced without large open gaps of white space between any two characters.
Leading
Linespacing
Its original meaning is increasing the vertical space between lines of metal type by literally inserting lead strips. In the digital age it now means the vertical space between lines of text, from baseline to baseline.
Serif
In typography, a serif is the little extra stroke found at the end of main vertical and horizontal strokes of some letterforms.
Sans Serif
Typeface that without extensions at the letter’s termination points. Sans serif type lends a clean and sharp appearance to the text, and is suitable for headlines or highlighted matter. Such type, however, is known to retard readability of large bodies of text, specially when less than 10 point in size.
Literally ‘without serif’.
Tail
The descending, often decorative stroke on the letter ‘Q’.
X-Height
The height of the lowercase letters, disregarding ascenders or descenders, typically exemplified by the letter x. The relationship of the x-height to the body defines the perceived type size. A typeface with a large x-height looks much bigger than a typeface with a small x-height at the same size.
Foundry
A company that designs and/or distributes typefaces; a type manufacturer. The name originated in the days of metal type when type was made from molten lead.

There are many more terms to define but I believe these are enough to get us started. Check the references listed at the beginning of the glossary for additional terms.

Why Typography

This is the first of a series of articles on Typography and the potential of text on the web

Over the past few months I’ve rekindled my interest in typography; how it works in print and how it works online. I’m also working through two typography books that are very relevant to both typographic work and overall front end design and development. Responsive Typography by Jason Pamental, On web typography by Jason Santa Maria and Professional Web Typography by Donny Truong.

But it wasn’t until fluent that I got a better idea of why typography is important.I got the chance to talk with both Eric Meyer, one of my early web design influences, and Jason Pamental, the author of Responsive Typography and a very good presenter.

What I got out of multiple presentations about CSS, typography and new technologies coming and going away (sadly) is that the basics are still important. With that in mind I’ll look at typography through a series of exercises.

The first thing to learn is that all typefaces are different. What works for the typefaces I chose may or may not work for the typefaces you choose for your projects. Where possible I’ll show the typefaces used in this page against other typefaces (most likely from the ‘web safe’ font set.)

Why worry about typography on the web?

Universal Typography — Tim Brown

I love the web and I’ve been working on digital content for almost 20 years. While I agree with the universality and accessibility requirements for the web (it should be accessible by anyone anywhere, regardless of disability or network connection) the content doesn’t have to be boring or plain

Whether we are reading a paper book or a web page or a iBook or Kindle ebook, typography still matters and it’s still an important part of the design process.

For the longest time I’ve heard that the web is not print and that we shouldn’t look at books as sources for web design inspiration. This may be true: the web is not print. But we’re getting to the point where CSS on its own or a combination of CSS and Javascript will gives a large part of what we see in print in a way that won’t look terrible in older browsers, when the user access it with assistive technology, or when CSS and Javascript are disabled.

I started taking a serious look at typography about 3 years ago. I’m not an expect and I’m most definitely not a professional but I’m learning and the more I learn the more I think we can use the full range of web technologies to enhance the text and the reading experience for our users.

I’m also including several things such as CSS Transitions and Animations that, while not directly related to typography, still affect the way text appears on screen.

Responsive SVG graphics

One of the most intriguing things I’ve learned about SVG over the last few months is that we can run CSS, including media queries, inside the SVG file itself so the queries will modify the internal content of the files will change based on the queries inside the svg.

Getting started

[codepen_embed height=”564″ theme_id=”2039″ slug_hash=”MwrgJp” default_tab=”html” user=”caraya”]See the Pen SVG basic example by Carlos Araya (@caraya) on CodePen.[/codepen_embed]

The CSS for the SVG graphic is embedded in the SVG file itself. We copied the SVG file’s XML content directly in the pen, but there’s no reason why the content cannot be saved in a text file with a .svg extension.

Because SVG is an XML vocabulary we need to take some protective measures, particularly with our CSS. You will see < ![CDATA[]]> element surrounding the CSS inside our tag. This is an XML artifact that renders all its content as character data instead of markup. We do this to prevent any possibility of illegal XML characters inside our CSS from messing up the content.

Simple changes

[codepen_embed height=”482″ theme_id=”2039″ slug_hash=”qdpWoJ” default_tab=”result” user=”caraya”]See the Pen SVG with Media Queries by Carlos Araya (@caraya) on CodePen.[/codepen_embed]

For our example, we’ll add ID attributes to all elements. Since we are working in an individual SVG file we don’t need to worry about weight or specificity, we can just do it.

After we add color to our content we create two media queries.

  1. The first one will trigger when the width is smaller than 600px and it will hide the circle by setting its display property to none.
  2. The second one will trigger when the screen becomes smaller than 320px and it will hide the rectangle by setting its display property to none, leaving only the start visible in our SVG image.
@media (max-width: 600px) { /* 1 */
  #circle1 {
    display: none;
  }
}

@media (max-width: 320px { /* 2 */
  #rectangle1: {
    display: none;
  }
}

We can get more sophisticated by performing multiple actions within each media query. This allows to play with with both animations, different media query types that I wouldn’t normally use and animations where they are appropriate.

<div class='container'>
  <?xml version="1.0" encoding="iso-8859-1" ?>
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
  <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">

    <defs>
      <style>
              #rectangle1 {
                fill: #f00;
              }

              #circle1 {
                fill: #00f;
              }

              #star1 {
                fill: #0f0;
                transform:  rotate(0deg);
              }

              /* Media Queries */
              @media (max-width: 1000px) { /* 1 */
                #circle1 {
                  display: none;
                }
              }

              @media (max-width: 800px) { /* 2 */
                #circle1 {
                  display: block;
                  fill: #f0f;
                }

                #rectangle1: {
                  display: none;
                }

                #star1 {
                    display: #663399; /* rebeccapurple */
                    animation: animationFrames ease-out 2s;
                    animation-iteration-count: 2;
                    transform-origin: 0 0 ;
                  }

                  @keyframes animationFrames{
                    0% {
                      transform:  rotate(0deg);
                    }
                    99% {
                      transform:  rotate(180deg);
                    }
                    100% {
                      transform: roatete(0deg);
                    }
                  }
                }
      </style>
    </defs>

    <rect x="61.768" y="61.768" transform="matrix(0.7071 0.7071 -0.7071 0.7071 150 -62.1321)" width="176.464" height="176.464" id='rectangle1' />

    <circle cx="150" cy="148" r="96" id='circle1' />

    <polygon points="150, 16.914 176.961, 99.892 264.208, 99.892 193.624, 151.174 220.585, 234.151 150, 182.869 79.415, 234.151 106.376, 151.174 35.792, 99.892 123.039, 99.892 " id='star1' />

  </svg>

</div>

We’ll take the same image as we used in the example before and both change colors and perhaps move them around when we hit the different breakpoints. In the Codepen above we do the following things:

  1. In addition to the color for the #star1 element’s fill we make sure that we rotate it to 0 degrees by default
  2. When the browser is 1000 pixels or smaller we hide the circle element
  3. When the browser is 800 pixels or smaller we do the following:
  4. We display #circle1 again (it was hidden in the previous query) and we change its color to #f0f
  5. We take the #star1 element, change its color to #663399 and set up animation attributes: animation tells the user agent what animation, what animation type and for how long we want to use the animation
  6. Definition for the animation steps references in step 5. We define each frame as what percentage of the animation we want that specific action to work on. In this case we defined 3 frames but we can define additional frames to make the animation smoother
#star1 { /* 1 */
  fill: #0f0;
  transform:  rotate(0deg);
}

/* Media Queries */
@media (max-width: 1000px) { /* 2 */
  #circle1 {
    display: none;
  }
}

@media (max-width: 800px) { /* 3 */
  #circle1 { /* 4 */
    display: block;
    fill: #f0f;
  }

  #rectangle1: {
    display: none;
  }

  #star1 { /* 5 */
    display: #663399; /* rebeccapurple */
    animation: animationFrames ease-out 2s;
    transform-origin: 50% 50% ;
  }

  @keyframes animationFrames{ /* 6 */
    0% {
      transform:  rotate(0deg);
    }
    99% {
      transform:  rotate(180deg);
    }
    100% {
      transform: rotate(0deg);
    }
  }
}

The one shortcoming of our image as currently implemented is that there are not enough steps for a smooth 360 degree transition. We could add more steps and make each step more gradual, something like this:

  @keyframes animationFrames{ /* 6 */
    0% {
      transform:  rotate(0deg);
    }
    25% {
      transform:  rotate(90deg);
    }
    50% {
      transform:  rotate(180deg);
    }
    75% {
      transform:  rotate(270deg);
    }
    100% {
      transform: rotate(0deg);
    }
  }

You can use the same techniques to completely change the appearance of your SVG graphic based on size or any query type you can use Media Queries with. The good news is that Media Queries Level 4 provides a much larger feature set for you to work with.

For example, we can modify our SVG content based on whether we’re working with monochrome displays by using a query like this:

@media (monochrome) {
  /* Rules for monochrome displays go here */
}

Support in browsers or readers

CSS animations should work in all modern browsers that support SVG (all modern browsers from IE9 onwards according to caniuse.com).

When I first looked at CSS animations in e-readers I got scared that epub3 didn’t support SVG animations but then I realized that it’s SVG-only animations not CSS animations applied to SVG.

As with all the techniques I’ve discussed here test all your content in your target devices

Conclusion

We can leverage a lot of the CSS tools and specifications inside of SVG files. This is not the only way to do it… We can take the CSS outside of the SVG and incorporate it with the CSS selectors and rules in the rest of our document. This adds our SVG CSS to the list of potential problems of specificity and you’ll have to do a lot more work to make sure the cascade works for your design.

Either way it’s a very interesting technique to add interactivity to your content in the open web.