WebFonts: how to reference fonts from HTML

Editor: Håkon Lie (howcome@w3.org)
Last changed: July 7, 1996

Introduction

Within W3C, a working group on fonts has been established to discuss how fonts can be integrated onto the Web. This document is of three "working drafts" that will be among the group's deliverables.

This document discusses how to reference fonts on the Web. More specifically, it outlines ways of referencing fonts -- both locally installed fonts as well fonts on the web -- from HTML documents. Also, strategies for finding the right font in over- and under-constrained problems are described.

Terminology

author
the author of an HTML document
CSS
Cascading Style Sheets
CSS1
Cascading Style Sheets, level 1.
font face
a "handle" that refers to a specific font, excluding the font size (?)
font data
the data that defines the glyphs of a font, most often glyph outlines
font description
a description of a font, but without the actual glyphs shapes. The level of detail can vary from just the name of the font up to a list of glyph metrics.
font reference
a request for a certain font face from a document
HTML
Hypertext Markup Language, an application of SGML.
reader
the person for whom the document is rendered
UA
User Agent, often a "web browser" or "web client"

Requirements

The Web needs a way to reference fonts. More specifically, we need a way to attach information about requested fonts to HTML documents (also, other media types need font solutions in the future).

In WebFonts it must be possible to:

HTML and style sheets

HTML is a simple document format much in use on the Web. HTML comes from the world of structured documents formally defined in SGML. In the last few years, HTML has been under pressure to add tags and attributes to represent visual presentation preferences. Among the elements that have been introduced by browser vendors are:

Some of the extensions have been widely deployed on the Web, and e.g. CENTER and FONT (with the SIZE and COLOR attributes, but not FACE) are likely to appear in the forth-coming HTML 3.2 [ref].

During the last year, there have been efforts to define a style sheet language for the Web that attaches style to structural elements instead of replacing them with presentational element. CSS1 [ref] has been developed within W3C and is now (July 96) starting to be supported in commercial browsers. Compared to HTML extensions, style sheets:

For these reasons, CSS style sheets will be the glue that connects HTML with fonts. However, browsers do not need to support the full CSS1 specification to implement WebFonts; a required subset will be clearly defined.

CSS1

CSS1[ref] is a specification of a simple style sheet language. Although general in principle, CSS1 has been developed in the context of HTML and offers features much requested on the Web: control over white space, color, backgrounds and fonts.

CSS1 has two main goals:

The list of properties and values is expected to increase as the demands on HTML presentations increase: fonts, high-quality printing, aural renderings. The CSS mechanism has been designed to scale up to these demands.

CSS1 and fonts

CSS1 defines several properties to describe the requested font:

  H1 { 
    font-weight: bold; 
    font-size: 12pt;
    line-height: 14pt; 
    font-family: helvetica; 
    font-style: normal
  }

In addition, there is a shorthand notation:

  H1 { font: bold 12pt/14pt helvetica }

which is equivalent to the previous example.

The current CSS approach relies on an underlying font matching mechanism that is not defined in CSS1. E.g., CSS1 does not define what the UA should do if it cannot find the a bold 12pt helvetica. The only exception to this rule is the comma-separated list of font family values.

Adding WebFonts support to CSS

To support the concept of WebFonts, we propose to add the following to CSS:

("at-rules" is one of the extension mechanisms in CSS. In CSS1 it is only used in the @import .. construct)

Here is an example of medium complexity:

<HTML>
  <STYLE>
    @font-face Folio Black Oblique {
  
      /* panose numbers */
  
      panose1: 2263545234;
      panose2: 42263545234226354523;
    
      /* font definitions a la PDF */
    
      italicsangle: -20;
      widths: 301 464 522 568;
    
      /* CSS1 properties */
    
      font-family: Folio, sans-serif;
      font-weight: extra-bold;
      font-style: oblique;
    
      /* where to find it */

      src: url(http://www.fonts.org/sans/folio/black_oblique);

      /* other information may be added in the future */
    
      font-id: lk097w34rdflkjd09;
      glyph-substitution-table: ..;
    }
    
    H1 {
      font-face: Folio Black Oblique;
      font-size: 36pt;
      margin-left: 2%;
    }
  
    P {
      font-face: none;
      font: 12pt/14pt serif;
      margin-left: 10%;
    }
  </STYLE>
  <BODY>
    <H1>Lettering</H1>
    <P>Letters are signs for sounds.
  </BODY>
</HTML>

The above HTML example could be rendered as:


Figure 1

Notes to the example:

For a description of the 'font-face' in CSS terminology, see Appendix A.

Inline font declarations

Document created on-the-fly will sometimes need to add font descriptions in the middle of a document. To allow for this, is is suggested that the 'STYLE' element is allowed also inside the 'BODY' element:

<HTML>
  <HEAD>
    <TITLE>  </TITLE>
    <STYLE>
      @font-face gill_sans {
        ..
      }
      H1 { font-face: gill_sans }
    </STYLE&g;
  </HEAD>
  <BODY>
    <H1>Lettering</H1>

  <STYLE>
    @font-face futura {
      ..
    }
  H2 { font-face: futura }
  </STYLE>
    <H2>Typography</H2>
  </BODY>
</HTML>

Style sheets inside the 'BODY' element should be cascaded in the order they appear. It is the author's responsibility not to change any style rules for elements that have already occurred earlier in the document since this will make progressive rendering impossible.

Strategies

This section outlines what the UA should do when it a) knows the font face and is looking for a usable font, and 2) does not know the name of the font face.

When the font face is known

Deciding where to look for fonts and what font to display on the screen (or on paper) at what time is potentially a complex problem. Variables in the equation include network performance, machine CPU, reader's wait costs, reader's display device, visual quality demands, font costs and legal restrictions. The optimal solution to this equation will vary between readers, display devices and documents.

Instead of trying to solve the above equation or defining means for authors and readers to specify solutions, this specification suggests a fixed list that is to be traversed until the font data behind a font face name is found:

  1. Use locally installed font face. I.e., use the system API to see if a font face with exactly the same name is available
  2. Use font face from other local sources, e.g. an intranet font repository. local font cache. Note that the URL is not used at this stage -- the configuration and addressing of the font cache is system-dependent
  3. Download and use the font face from the URL. This may require installing it through a system API.) During download a substitute font can be used. The substitute font is either matched or synthesized from the font description. If the reader has turned off font downloading from URLs, the UA may choose to use a matched/synthesized font or proceed in this list
  4. If the UA supports style sheets, use style sheet font properties to find the best matching font. Normally, locally installed or cached fonts will be used, but if the browser is aware of other external fonts, they can also be used
  5. Use system-dependent default. All UAs must have a font that is guaranteed to work if everything else fails.

When the font face unknown

HTML is a structured markup language that can be parsed into a tree of elements. One advantage of the tree structure is that elements can inherit properties -- stylistic and others -- from their parent element. Consider the following example:

  <H1>An Essay on <EM>Typography</EM></H1>

The 'EM' element inside 'H1' will, when rendered with a common browser, be displayed in the same font family, font size and color -- i.e., these properties are inherited from the parent element. One property, most likely the font style, will not be inherited since 'EM' elements are normally rendered in italics/oblique.

For many HTML elements, the HTML 2.0 specification [ref] suggests certain font properties to be changed. E.g., 'TT' and 'PRE' are to be rendered in monospace fonts, while 'B' and 'STRONG' are to be rendered in bold. Therefore, in most cases, font face values cannot be inherited from parent to child elements.

Consider the following example:

  <STYLE>
  @font-face foobar {
    src: url(http://font.org/foobar);
  }
  </STYLE>
  ..
  <P STYLE="font-face: foobar">The <B>only</B> way
  to reform modern lettering is to abolish it.</P>

From the HTML source, the only information known about the font face of the 'P' element is its URL. Even after fetching the URL successfully, the UA may not know anything about its serifness, boldness etc., and creating a bolder version of 'foobar' -- as the child element demands -- may be infeasible if not impossible.

The general solution to this problem is for the UA to

  1. gather as much information as possible about the font face in question: in the example above there in no information available in the font description (but the font data itself may have some)
  2. compare the font properties of the child element with the ones of the parent: in the example above the UA would note that only the weight was different between the two
  3. make efforts to find or synthesize the right font face based on the information

Of course, the above chain of reasoning is not necessary if a font face has been specified for the child element:

  <P STYLE="font-face: foobar">The 
  <B STYLE="font-face: foobar_bold">only</B> 
  way to reform modern lettering is to abolish it.</P>

Using CSS terminology, the above outlined method could be described as: The 'font-face' property, if specified, will take precedence over the CSS1 font properties. When a font face is referenced, the UA should assign the font description information that corresponds to font property values for that element. Child elements will then inherit values that correspond to the font face of the parent element, and these will be used to find the font face -- along with the values set explicitly for the child element.

Also, a CSS-compliant UA is allowed to be smart beyond CSS1 properties. E.g., the "condensedness" of a font does not have a property of its own in CSS1, but UAs should still be allowed to remember and reuse it.

Unresolved issues

References

To be added.

Appendix A

This is a very preliminary description

As a CSS property, 'font-face' is described as follows:

'font-face'

Value: none | inherit | <face name>
Initial: none
Applies to: all elements
Inherited: no
Percentage values: N/A

A <face name> value is a reference to a font face described in a corresponding "font description".

A value of 'none' means that the CSS1 properties should be used to find the font for the element. 'inherit' means that the value of 'font-face' should be taken from the parent element.