A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

A means to determine the font applied to a range

marcosc
2014-12-15

Use case

Given a range of text in the DOM, what font(s) is being applied to that range?

  • “Designer wants wider letter-spacing if Futura (1st font in stack) is displayed than if Century Gothic (2nd font) is displayed.” [1]
  • To save requests/bandwidth, determine if a font is available on the user’s system before loading it.

Existing solutions

There are no exact solutions to this use case in the platform. Right now, developers are using either a canvas hack [2] or javascript hack [3].

See also:

Limitations

window.getComputedStyle(element)

Get computed style only returns you the font stack, so you can’t actually determine which font is being applied to an element (or a range of characters).

Security and privacy considerations

Fingerprinting:

Refs and acknowledgements

This proposal comes originally from Dave Newton.

yoavweiss
2014-12-15

As pointed out by Jake Archibald, these use cases are covered by the Font Loading API’s check() function

marcosc
2014-12-15

So, obviously, before we close this, I’d like to see this working in Chrome and to make sure Dave’s case is fully met. I’ve not had a chance to try out the API yet.

Anyone willing to code this up quickly?

alanstearns
2014-12-15

The font loading APIs don’t address this - what’s needed is a way to find out which font in the font stack is actually being used to display the text. Which fonts are loaded isn’t sufficient - glyph fallback and font subsetting can complicate what font is being used where.

newtron
2014-12-15

CodePen with solution for my primary use case, based on feedback from Jake, Yoav, et al.

While my original use case is more or less covered, I think @alanstearns is right: this could break pretty easily given glyph fallback and font subsetting.

tabatkins
2014-12-15

That’s what the second argument to check() is for - you pass it a string of text you’re going to render, and it verifies the font stack against that text. In this case, you’d pass in the textContent of the element you’re checking.

But still, using check() for this requires you to break apart the font-family value for the text, and construct new strings using each family name and the style/weight/etc values on the text, and then check them in order. That’s annoyingly non-trivial for something that sounds reasonable.

@marcosc Your second use-case is already handled by @font-face and FontFace - just use a local() source before the url() source.

hexalys
2014-12-15

I agree with Alan. @newtron’s solution looks like a third hack around this problem.

@tabatkins A remaining issue with check() is that it doesn’t address font substitution, and is therefore unreliable, especially on mobile, where many basic desktop fonts are heavily substituted.

e.g. Jake’s example return true for helvetica. But Windows replaces all Helvetica text with Arial, so technically Helvetica should probably return false or something different like null. You still don’t know what font is being used.

alanstearns
2014-12-16

Strawman proposal: instead of font name strings, I’d like to see something that returned a font object which would contain the name and otherwise-inacessible font metrics information. The polyfill for drop caps needed the baseline and cap height metrics for the font being used to display the initial letter. It would be useful to get this from a Node and perhaps also a Range (giving the initial used font if there are multiple fonts used)

tabatkins
2014-12-18

The “name” of a local font is a difficult thing to determine - there are usually several of them. But if that can be worked out, this is fine with me - I have an issue in the spec for finding some way to deal with local fonts.