W3C home > Mailing lists > Public > www-style@w3.org > November 2008

Re: [css3-fonts] duplication and @font-face rules

From: John Daggett <jdaggett@mozilla.com>
Date: Wed, 12 Nov 2008 22:20:14 -0800 (PST)
To: HÃ¥kon Wium Lie <howcome@opera.com>
Cc: "L. David Baron" <dbaron@dbaron.org>, www-style@w3.org
Message-ID: <27372402.130081226557213962.JavaMail.root@cm-mail01.mozilla.org>

> > 3. Handling multiple @font-face rules defining the same fonts
> > =============================================================
> >
> > Given two @font-face rules that describe the same font but have
> > different 'src' descriptors, which fonts are used?  For example:
> >
> > @font-face {
> >   font-family: "Foo";
> >   src: url(a.ttf);
> > }
> >
> > @font-face {
> >   font-family: "Foo";
> >   src: url(b.ttf);
> > }
> >
> > body { font-family: "Foo", Arial, sans-serif; }
> >
> > In this case, does the search for glyphs look in:
> >  (1) a.ttf, then b.ttf, then Arial, then other sans-serif fonts
> >  (2) b.ttf, then a.ttf, then Arial, then other sans-serif fonts
> >  (3) a.ttf, then Arial, then other sans-serif fonts
> >  (4) b.ttf, then Arial, then other sans-serif fonts
> > ?
> >
> 
> It's a hassle to have to record seemingly duplicate @font-faces, but
> with extensibility in mind, 2 may actually make more sense. 4 is
> simpler, though. I'm torn.

I think the default behavior for simple rules without a lot of descriptors set should be kept simple, I think (4) is simpler to understand, both for authors and for implementors.

There's also an interaction here with the unicode-range descriptor.  The default value for unicode-range is the full Unicode range (i.e. U+0-7FFFFFFF) so the definition of b.ttf above should effectively hide completely the rule for a.ttf.  This definitely needs to be clearer in the current CSS3 Fonts editor's draft but the CSS2 spec clearly defines the default value for unicode-range.

Another way to look at this is that if the font b.ttf has glyphs for characters in the range AAA to BBB, method (2) is essentially equivalent to:

  @font-face {
    font-family: "Foo";
    src: url(a.ttf);
  }
  
  @font-face {
    font-family: "Foo";
    src: url(b.ttf);
    unicode-range: U+AAA-BBB;
  }
  
We might even introduce an 'auto' keyword for the unicode-range descriptor. With this keyword, the range would be determined by the cmap of the font itself.  Using 'auto', method (2) would become:

  @font-face {
    font-family: "Foo";
    src: url(a.ttf);
  }
  
  @font-face {
    font-family: "Foo";
    src: url(b.ttf);
    unicode-range: auto;
  }
  
The downside of this is that the fonts would need to be downloaded to determine the cmap range, so one advantage of unicode-range would be lost in this case.  But the behavior would allow authors a certain amount of flexibility to deal with complex character fallback situations.

> > > 2. Handling of lists of values of the 'src' descriptor
> > > ======================================================
> > >
> > > The second issue is that the spec doesn't describe how a user agent
> > > should process multiple values of the 'src' descriptor.  In
> > > particular, when the 'src' descriptor is a list of values, there
> > > seem to be two reasonable possibilities:
> > >
> > >   (A) The user agent uses the first of those values for which it has
> > >   a usable font (e.g., a local() font that is present or a url()
> > >   that is in a format it supports) and ignores the rest.
> > >
> > >   (B) The user agent uses all of the values for which it has a
> > >   usable font, picking each glyph from the earliest in the list that
> > >   has a glyph for the character.
> > >
> > > (B) seems like it has some advantages, particularly when local() and
> > > src() are combined, and the font available locally may have more or
> > > fewer glyphs in it depending on what the user has chosen to install.
> > > It also feels more CSS-like to me (which could mean it fits author
> > > expectations better, although maybe not).
> 
> Agreed, it feels more CSS-like -- it's iso-morphic to the
> comma-separated list on 'font-family'.

But I think it confuses the font-family fallback properties with the src descriptor *load* properties.  I think it's important to keep the two separate, both to allow authors flexibility and to keep the mental model simple.

> One arguement for (B) is that Prince has implemented it this way and
> that it uses it in the default style sheet:
> 
>   @font-face {
>     font-family: sans-serif;
>     src: local("Arial"), local("Helvetica"), local("OpenSymbol"), local("DejaVu Sans")
>   }

This could also be constructed using unicode-range descriptors, either with an explicit range or something like the 'auto' keyword described above:

  @font-face {
    font-family: sans-serif;
    src: local("OpenSymbol");
  }
  
  @font-face {
    font-family: sans-serif;
    src: local("Helvetica");
    unicode-range: auto;
  }
  
  @font-face {
    font-family: sans-serif;
    src: local("Arial");
    unicode-range: auto;
  }
  
With (A) authors have the flexibility to separate per-platform or load-fallback behavior from character fallback behavior.  With (B) you effectively force the per-platform and load-fallback behavior down into font-family property rules.  
Received on Thursday, 13 November 2008 06:20:55 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:55:17 GMT