I love a good origin story, like the origin of Batman in Detective Comics #33, or Kate Kane (the modern version, introduced in 52, not the 1956 one). It gives us greater insight into the motivations and characteristics of any particular thing, be it a character or a specification. Segue! 😈

As part of my perpetual obsession with typography, as well as CSS, I’ve been looking into how we got to having more web fonts than we can shake a stick at. What I love about how the W3C does things is that there are always links to previous versions of the specification, all the way back to the first drafts.

Although those are missing the full picture of the various discussions and meetings among all the individuals involved in crafting and implementing the specifications, it does offer some clues to how things got to where there are.

The many levels of CSS

You know how sometimes when you fill in your profile for job sites, or some code-related profiles, and they ask what your area of expertise is? Some of those fields are free-form taxonomies and you can see people making a distinction between HTML and HTML5, or CSS and CSS3, as if you need to underscore the point that you are oh-so-current by declaring the “latest” version number?
*at point of writing, emoji of my go-to IRL face of one eyebrow raised is not released yet, please imagine how my face looks*

When CSS started out, there was CSS1 and CSS2 (subsequently, CSS2.1 and CSS2.2). So the impression is that CSS has versions, like software, which increment as each new version gets released. That’s not exactly how it works though. Yes, CSS1 and CSS2 were monolithic specifications that covered every CSS property we had, but somewhere along the lines, a decision was made to modularise the specifications.

The advantages of doing so are outlined in the first working draft of the CSS3 roadmap published on 14 April 2000, written by Eric A. Meyer (yes, THE @meyerweb we know and love).

  • To help clarify the relationships between the different parts of the specification
  • To reduce the size of the complete document
  • To allow specific tests to be built on a per module basis
  • To help implementers decide which portions of CSS to support
  • To make it possible for individual modules to be updated as needed
  • To allow for a more flexible and timely evolution of the specification as a whole

By the next revision of the Working Draft in 19 January 2001, there was a breakdown of the entire document into 26 modules, and a lot more work went into refining the roadmap to the version we have right now. The roadmap is currently maintained by Tab Atkins Jr., Elika J. Etemad A.K.A fantasai and Florian Rivoal, and the full list of CSS specifications by module is available on the CSS specifications page.

Rachel Andrew wrote a concise and informative explanation of why there is no CSS4, but here’s the explanation stated in the CSS Snapshot:

There is no CSS Level 4. Independent modules can reach level 4 or beyond, but CSS the language no longer has levels. (“CSS Level 3” as a term is used only to differentiate it from the previous monolithic versions.)

Evolution of a CSS specification

CSS specifications do not just magically appear out of thin air. There is a lengthy process with numerous passes before a specification is finalised and becomes a formal standard, or W3C Technical Report, for implementers and authors to reference. Details are covered in the W3C Technical Report Development Process, but here’s a general overview.

According to the guidelines, the W3C follows these steps when advancing a technical report to Recommendation.

  • Publication of the First Public Working Draft,
  • Publication of zero or more revised Public Working Drafts.
  • Publication of a Candidate Recommendation.
  • Publication of a Proposed Recommendation.
  • Publication as a W3C Recommendation.
  • Possibly, Publication as an Edited Recommendation
Working Draft (WD)
A Working Draft is a document that W3C has published for review by the community, including W3C Members, the public, and other technical organizations.
Candidate Recommendation (CR)
A Candidate Recommendation is a document that satisfies the Working Group's technical requirements, and has already received wide review.
Proposed Recommendation
A Proposed Recommendation is a document that has been accepted by the W3C Director as of sufficient quality to become a W3C Recommendation.
W3C Recommendation (REC)
A W3C Recommendation is a specification or set of guidelines or requirements that, after extensive consensus-building, has received the endorsement of W3C Members and the Director. W3C recommends the wide deployment of its Recommendations as standards for the Web.

Chasing CSS fonts back in time

17 December 1996 - CSS1 W3C Recommendation
A small section, 5.2, which explains how font matching should be done and defines the initial set of 5 font properties, font-family, font-style, font-variant, font-weight and font-size, as well as the shorthand font. The next version, 11 Jan 1999, of the specification did not add much and this was pretty much what formed the basis of CSS fonts for CSS1 when it became a formal recommendation on 17 Dec 1996.

21 July 1997 - Web fonts Working Draft
A separate group in the W3C (this is my inference, but if I get the chance to talk to Chris Lilley again, I will clarify this) was formed to develop web fonts. It was meant to extend on the CSS1 font model by allowing font descriptions to be added to a style sheet. “The font descriptions consist of a set of font descriptors, individual pieces of information about a font, possibly including a URL where the font can be downloaded.”
*There is an earlier version published on 10 July 1997 but it’s W3C members-only access.*

04 November 1997 - CSS2 Working Draft
In CSS2, the fonts section (section 14) had expanded quite a bit. In addition to everything included in CSS1, generic font families were added. The font selection mechanism was extended, including intelligent matching, synthesis, and downloadable fonts. Generally whatever was in the web fonts module we talked about above.
System fonts were now a thing. And there was also this very detailed section on font characteristics, which were not specific to CSS per se, and could be mapped onto VRML (Virtual Reality Modeling Language) nodes, CGM (Computer Graphics Metafile) Application Structures or alternative stylesheet languages. Things pretty much held constant over the next 2 versions, 28 Jan 1998 and 24-Mar-1998. CSS2 became a formal recommendation on 12-May-1998

31 July 2001 - CSS3 Fonts Working Draft
As part of the CSS Style activity, the original CSS2 authors, together with Tantek Çelik, Marcin Sawicki, Michel Suignard and Steve Zilles wrote the first Working Draft of the CSS3 fonts module. It was stated that the module was dependent on two other CSS3 modules, Web Fonts and Text. It covered font matching, and the list of font properties.
*I’m probably going to chase the CSS3 text module next, so stay tuned*

2 August 2002 - CSS2.1 Working Draft
The first revision of CSS2 (aka CSS2.1) was meant to correct errors in the CSS2 specification as well as remove features that were unwanted or obsoleted by CSS3. In this version, there were substantial cuts to the fonts section, with only the bits about font matching and font properties remaining. The removed bits went to the CSS3 Web Fonts module. Web fonts were dropped in this version and here’s the explanation from the 20th birthday of CSS feature (those balloons are aces).

First of all there were few fonts whose copyright allowed them to be distributed. Most fonts could be used to print documents locally, but you weren’t allowed to put them on the Web.

Secondly, Microsoft and Monotype had developed a format called EOT (Embedded OpenType), which contained inside the fonts the names (URLs) of the documents that could be rendered with them. […] But, the format was proprietary and nobody else but Microsoft could use it.

Nothing much got updated in this section for the next 5 versions, and you're welcome to verify this for me.

2 August 2002 - CSS3 Web Fonts Working Draft
As mentioned, the cut bits from the CSS2.1 specification went in here, so everything with regards to @font-face and the font descriptors for font selection, as well as font characteristics could be found in this specification. The extended font matching algorithm was also defined here.

2 August 2002 - CSS3 Fonts Working Draft
This was quite a day, as the CSS3 Fonts Working Draft was also updated and now included a section on Font Decoration, with some interesting properties like font-effect, font-smooth, font-emphasize-style, font-emphasize-position and the font-emphasize shorthand.
*Spoiler alert: font-effect has been dropped, and technically doesn’t exist, while others have been moved to other modules*

06 November 2006 - CSS2.1 Working Draft
Finally, some action in the CSS2.1 Working Draft fonts section. The font-family section expanded with details on generic font families. The five generic font families are serif, sans-serif, cursive, fantasy and monospace.
Specifically, it mentions that user agents should provide reasonable default choices, which express the characteristics of each family as well as possible within technical limits. There are also proposed examples of font families to be used for different scripts.
This section does not see any more changes for the next five years, and again, feel free to verify this for me.

18 June 2009 - CSS Fonts Module Level 3 Working Draft
I bet a lot happened in the seven years between the last working draft and this one but I don’t know what happened. What we do know is that this version consolidates all that was previously covered in the CSS3 Fonts module and CSS3 Web Fonts module, into one nice meaty specification. There’s also a lovely Typography Background section at the beginning to set up some context for the use cases described later on in the specification. There are illustrative pictures and everything!

The age of modular CSS

Basically, from here on out, the format of the specifications (at least, to my amateur eyes), seems to have standardised quite well. So whatever comes next is just going to be a list of change logs.
For posterity’s sake.
Oh, don’t give me that look.

24 March 2011 - CSS Fonts Module Level 3 Working Draft

  • Revised definition of permissible unquoted font family names to match latest CSS 2.1 draft
  • Added font-kerning property
  • Added extensions to font-variant property for supporting OpenType font features
  • Added @font-feature-values rule for defining font-specific variant selectors
  • Added font-language-override property
  • Added font-feature-settings property for access to low-level OpenType features
  • Revised font matching algorithm
  • Added font-synthesis property

4 October 2011 - CSS Fonts Module Level 3 Working Draft

  • Made same-origin wording normative and marked it at-risk
  • Simplified definition of subscript/superscript variant property
  • Trimmed some font-variant property values and renamed others
  • Added more examples for various font variant value types
  • Added DOM interface definitions for @font-feature-values rules

23 August 2012 - CSS Fonts Module Level 3 Working Draft

  • Based on TPAC resolution, same-origin restriction is normative
  • Added parameter specifics for using CORS with font loads
  • Revised fallback handling of subscript/superscript variants
  • Switched to using CSS3 Values and Units hash notation for comma-delimited lists
  • Reworked font-family syntax to be clearer about the use of keywords in unquoted font family names
  • Tightened the syntax of font-feature-settings to only allow four-character tags
  • Added missing definitions of default values for some properties
  • Reworked description of default features and added none value for font-variant-ligatures

11 December 2012 - CSS Fonts Module Level 3 Working Draft

  • Tightened description and fixed errors in description of font-variant-caps
  • Added auto value to font-size-adjust
  • Added definition of font load events
  • Defined explicit steps for font matching grapheme clusters
  • Added font-stretch values to the font shorthand
  • Created object model section and revised definition of CSSFontFaceRule
  • Updated syntax of @font-feature-values rule based on CSS WG resolution
  • Other light cleaning and dusting

12 February 2013 - CSS Fonts Module Level 3 Working Draft

  • loadFont method takes a dictionary parameter that includes callbacks
  • Added example of system font names used as normal font family name
  • Added conformance section
  • Added CORS cross-origin request algorithm parameters
  • Added specification of Unicode caseless matching for font family names based on WG resolution
  • Include issue of synthetic oblique angle in CJK vertical text runs
  • Minor editorial tweaks hither and thither

11 July 2013 - CSS Fonts Module Level 3 Last Call Working Draft

  • Moved font load events into a separate spec
  • Tightened syntax rules for @font-feature-values rules
  • Added grammar productions for @font-face and @font-feature-values rules
  • Revised definition of unicode-range descriptor
  • Detailed font matching of composite faces
  • Revised object model interface of CSSFontFeatureValuesRule
  • Detailed effect of font-size-adjust on relative unit sizes
  • Reference the potentially CORS-enabled fetch method defined in HTML5

3 October 2013 - CSS Fonts Module Level 3 Candidate Recommendation

  • reorder feature precedence such that features implied by other CSS properties override font-variant settings
  • switched examples to use .woff files
  • revised wording of font fetching algorithm
  • drop auto value for font-size-adjust
  • clarify effect of font-size-adjust on line-height
  • allow user agents to synthesize OpenType kern feature
  • add example of ordinals and associated markup
  • minor editorial cleanups

Let’s talk about Editor’s Drafts

According to the guidelines for writing CSS specifications,

Working Groups and Interest Groups may make available “Editor’s drafts”. Editor’s drafts have no official standing whatsoever, and do not necessarily imply consensus of a Working Group or Interest Group, nor are their contents endorsed in any way by W3C.

Regardless, these documents are still interesting to read because they give us a peek into how the specifications are being worked out. There are footnotes and comments and questions wherever clarifications are needed. Personally, I appreciate the transparency of the entire process, as well as the sheer amount of effort it takes to refine a specification to a state where it can be deemed a proper standard.

For the CSS Fonts Module Level 3, a few changes have been made in the latest Editor’s Draft dated 19 January 2016, as of time of writing. So if you’re reading this far in the future, the link probably won’t be dated as such any more.

  • add omitted font-variant-position values to font-variant shorthand
  • make negative values for font-size-adjust invalid, along with negative percentage font-size values
  • remove the requirement that user agents use OS/2 table subscript/superscript metrics
  • minor editorial cleanups

The CSS Fonts Module Level 4 covers new features (which I am excited about), like font variation properties and colour font support. Again, the Editor’s Draft I’m referring to at time of writing is dated 10 May 2017, but this will definitely change when you try to access and read it.

Font variation properties

Font variation properties address the CSS properties that deal with variable fonts, which were announced at the ATypl conference in Warsaw on 14 September, 2016 to much fanfare (at least amongst those of us who are typophiles). Basically, it is a single font file that can perform interpolation to cover various weights. This behaviour is defined version 1.8 of the OpenType font format specification.

Colour fonts

Not much has been written about CSS colour fonts at the moment, and I suppose its because colour fonts are relatively new (with regards to CSS, not in general, because they’ve been around forever) but this is what I gleaned from the document.

We get a font-palette property that allows us to pick the palette of the colour font we’re using, which brings us to the @font-palette-values rule. This rule allows us to define a colour palette and associate it with a specific font. This is the example I pulled from the document:

@font-palette-values Augusta {
  font-family: Handover Sans;
  base-palette: 3;
  1: rgb(43, 12, 9);
  3: var(--highlight);

As with the @font-face rule, there are a number of font descriptors you can use in the @font-palette-values rule as well, like font-family, base-palette, <integer> and font-presentation. I need more time to dig in and wrap my head around this so just some superficial coverage for now, but did I mention I’m excited? I’m so excited! 💃🍷🎊

Wrapping up

So that’s it for this inaugural edition of “Chasing the Spec”, that it, if I decide to continue and make it a series. 🤓 Maybe. Depends on my mood. 😏 We’ll see. Life happens. 🤷

Further reading