-
Notifications
You must be signed in to change notification settings - Fork 686
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[css-fonts-4] [varfont] Supported variation font axes and font features are not discoverable #520
Comments
This is clearly out of scope for CSS (although I know next to nothing about CSSOM and Houdini). Additional or changed descriptors for |
Using a media query for this wouldn't work because media queries have no concept of a specific font face to investigate. Instead, it seems that such a mechanism would have to be in JavaScript. The canvas text metrics API and the forthcoming Houdini text metrics API expose some other font-driven information. However, these APIs give you information about a line (or lines) of text, and would include things like fallback fonts. Variation axes and features are font-specific, so including fallback fonts isn't the right level of abstraction for solving this problem. A natural place to put this would be to build off of the CSS Font Loading API. This API already has the concept of an object which represents a font face. In addition, a FontFace even already has a "status" enum property which has a relationship to a specific url() inside the FontFace (so there is precedent for this idea already). Maybe a function can be added to FontFace which returns a new object which has a bunch of properties including font info. Calling the function on an in-flight download would result in an exception or something. Any thoughts? @tabatkins @bramstein @nattokirai @SergeyMalkin @drott @heycam P.S. According to caniuse, Edge hasn't implemented the CSS Font Loading API, so they would probably have to implement at least some of it in order to go with this proposal. |
I agree that extending Font Loading API seems like a natural way to get this discoverability. Although it would be nice to be able to code up a test page in HTML/CSS to explore what some font provides. |
We probably would want something similar for font color palettes. |
Yes. At the early Houdini meetings the assumption was that Houdini would produce a font metrics API, to query features of a particular font (and with the advent of variation fonts, a particular instance). However, over time that was seen as less important for pollyfiller-writers than metrics on fonts used together in a text segment, which eventually became the text metrics API. There is still a need to query an individual font instance. |
Consider the following CSS: @supports (font-feature-settings: "subs" 1) {
sub, sup { vertical-align: baseline; font-size: 100% }
sub {
font-feature-settings: "subs" 1
}
sup {
font-feature-settings: "sups" 1
}
} Basically, I want to use have the font position/size the superscripts and subscripts if it supports those features. Otherwise, I want to use the default positioning/sizing. However, this doesn't work, because the browser does support |
Right. Thus the earlier conclusion of "this belongs in JS, probably attached to the FontFace API defined in Font Loading". |
Why should one have to write JS for these things? I don't think one should. And why should one have to use the font loading API if they aren't even loading any fonts, but instead using only the browsers preloaded fonts? In any case, it seems like font-variant-position is intended to handle my specific issue, though it doesn't seem to work in practice (yet). |
Because there's no reasonable way to talk about a single individual font file in CSS, but there is in JS. CSS just has a concept of a font stack, composed of family names, each of which is composed of 1 or more composite font faces, each of which is composed of one or more individual font faces/files (you can combine multiple faces into one composite face via
I didn't say you'd use the font loading API. I said you'd use the FontFace API, which happens to be defined in the spec called Font Loading. Nothing needs to be "loaded" to use this. It's just the right API location for this sort of ability to live. |
I really want this feature in JS. It would be super useful in building any type of text formatting tool and creating an interface to allow these features to be adjusted if they are available |
How about something like this: interface FontFaceFeature {
readonly DOMString featureTag;
}
interface FontFaceFeatures {
readonly setlike<FontFaceFeature>;
readonly record<FontFaceFeature, long> namedInstances;
}
interface FontFaceVariationAxis {
readonly DOMString name;
readonly DOMString axisTag;
readonly double minimumValue;
readonly double maximumValue;
readonly double defaultValue;
}
interface FontFaceVariations {
readonly setlike<FontFaceVariationAxis>;
}
interface FontFacePaletteValue {
readonly DOMString color;
}
interface FontFacePalette {
readonly maplike<unsigned long, FontFacePaletteValue>
readonly bool usableWithLightBackground;
readonly bool usableWithDarkBackground;
}
interface FontFacePalettes {
readonly maplike<unsigned long, FontFacePalette>;
}
dictionary FontFaceDetails {
readonly FontFaceFeatures features;
readonly FontFaceVariations variations;
readonly FontFacePalettes palettes;
}
partial interface FontFace {
readonly attribute FontFaceDetails details;
} |
Looks like a good first draft to me, thanks for writing this up. I would perhaps take the |
This looks great! Nitpick: something about the word |
@drott @bramstein In font design programs this type of information is usually in the |
Pinging @tabatkins |
That does look good. Time to put it into an unofficial draft? |
This has a lot more indirection than I think is needed. Maybe: interface FontFaceFeatures {
maplike<DOMString, (long or null)>;
/* null for the name-only features like ss01 */
};
interface FontFaceVariationAxis {
readonly DOMString name;
readonly DOMString axisTag;
readonly double minimumValue;
readonly double maximumValue;
readonly double defaultValue;
};
interface FontFaceVariations {
readonly setlike<FontFaceVariationAxis>;
};
interface FontFacePalette {
iterable<DOMString>;
readonly attribute unsigned long length;
getter DOMString (unsigned long index);
/* arraylike! using the TypedOM pattern, which seems to be right */
readonly bool usableWithLightBackground;
readonly bool usableWithDarkBackground;
};
interface FontFacePalettes {
iterable<FontFacePalette>;
readonly attribute unsigned long length;
getter FontFacePalette (unsigned long index);
};
partial interface FontFace {
readonly FontFaceFeatures features;
readonly FontFaceVariations variations;
readonly FontFacePalettes palettes;
}; Should the things on |
The Working Group just discussed
The full IRC log of that discussion<fantasai> Topic: Variation axes not discoverable<fantasai> github: https://github.com//issues/520 <fantasai> myles: One of the requests we got from ppl who make websites who like typography <fantasai> myles: There's no way for them to know what to put in their font-feature-settings and font-variant-settings properties <fantasai> myles: Right now they are parsing the font with JS to pull out the tables <fantasai> myles: So trying to think of ways that a browser could make this data available to web content <fantasai> myles: Best way I could think of was to hang off of Tab’s fontFace object <fantasai> myles: defined in font loading spec <fantasai> myles: New attribute on existing object <fantasai> myles: That gives a bunch of info about the font <TabAtkins> My proposal for the IDL for this https://github.com//issues/520#issuecomment-386153230 <fantasai> myles: Just wanted to check on general idea of extending fontFace like this <fantasai> astearns: Well I like the idea <fantasai> TabAtkins: I'm for it <fantasai> TabAtkins: I think this is the right place to put it, good approach for it <fantasai> myles: Tab's better at writing APIs, so we can use his suggestion if we think it's a good idea <fantasai> astearns: Any concerns about adding all this info? <fantasai> astearns: Instead of new UD, maybe another level? <fantasai> myles: ... <fantasai> TabAtkins: Let me see how mature the css-font-loading spec actually is, and then we'll decide <fantasai> fantasai: So, proposal is add it to css-font-loading, level TBD? <fantasai> astearns: Any objections? <fantasai> RESOLVED: css-font-loading, level TBD |
Would it be possible to extend this to include access to the OpenType 'MATH' tables? Some math-aware fonts include metric information in these tables which are necessary in order to do proper mathematical layout (i.e. to correctly position arguments on display operators such as integrals or to use the correct line thickness for fraction bar or square root over bar). Software libraries doing math layout such as MathJax or MathLive have to manually parse font files in JS or, more realistically, hardcode these metrics for a specific font. |
Some more thoughts, There are times when I want to query features and axis of a font but I don’t know what font is loaded. For example, I might have a font stack with San Francisco in it and this will only be available on Apple devices. I want to query the features available to me on any given element. If I want to make a rich text editor, the opentype and variable font menus will be different depending on what font is activated in the font stack. In this scenario I don’t know of a feature or axis to test for but I want to query a menu of all possible features and axis. Another scenario is if I want to accommodate for making text strong via a combination of weight and width axis I might want to use something more like |
Would variableFont.js work for system fonts though? |
@davelab6 Because it needs ~ 50KB of JavaScript to work and doesn't support WOFF/WOFF2 or system fonts. |
would love to see this exposed in js! it will super-boost a lot of web developmet project we do! |
I think that exposing it in JS and in dev tools is a good way to make a font's capabilities known, though as @svgeesus points out, the font should come with documentation and a sample page that shows it all off, but that's on the font vendor, not the browser. As a designer, I would be ok with reliably being able to use browser dev tools or a JS library to figure out what's possible, so I can then make decisions about how I want to use those capabilities. My current workflow tends to be 'get font, drag on to wakamaifondue.com, copy axes and values into my CSS as a set of comments for reference' - rinse, and repeat for every font I encounter. Having a way to do that more natively integrated in a browser or editor (VS Code plugin anyone?) would be really helpful. (While my comments above are focused on variable font axes, the same would be true for OpenType features) |
I would like to see something like this: element.font would return info: {
postScriptName: 'my font italic',
fullName: 'my font italic',
familyName: 'my font',
style: 'italic',
kind: 'opentype',
language: 'English',
version: '6.0.2',
copyright: 'copyright 2019 Acme Inc.'
},
metric: {
ascender: 82,
capHeight: 70,
xHight: 41.6,
descender: -25,
italicAngle: 18,
},
setting: {
smcp: true,
c2sc: true,
hist: true,
tnum: true,
frac: true,
swsh: true,
ss01: true,
ss02: true,
ss03: true,
ss04: true
},
variant: {
wght: {
min: 200,
default: 400,
max: 800
},
opsz: {
min: 8,
default: 16,
max: 72
}
}
} This allows me to either query the whole object, or target a specific value element.font.variant.wght.min I also added font info and metrics, because it seemed like a good thing to throw in there as well. edit: added defaults to variants thanks to @wentin for identifying that. |
“element.font” isn’t quite right because of font fallback. It could be that none of the text in the element is rendered with the primary font. The set of available features will be different depending on which font in the fallback list is used. |
@litherum This is the behavior I was expecting. I’d want to query what font features the loaded font on that element supports, not what features does the primary font in the font stack have. This brings up the edge case of multiple subsetted fonts being loaded at once. In that case maybe just the one first one in the stack that is loaded? Or we could get an array of these objects for each font in the stack, null if it does not exist? So |
If the object could also exposed named instances and named OpenType features (e.g. names of stylistic sets), that'd be useful too. |
Real world use cases
|
@scottkellum These are great - my only comment is under typesetting->weight axis, you should still use font weight, but you can use an explicit value rather than keyword or hundred-limited integers (100, 200, 300, etc) - and this is supported in all browsers now (same for font-stretch with percentage width values) |
I believe https://wicg.github.io/local-font-access/ provides this. |
It seems that https://wicg.github.io/local-font-access/ is limited to providing information about local fonts (see slightlyoff/local_font_access#1). Having access to font information of fonts that have been downloaded is important as well. Specific use case: a mathematical formula editor that needs detailed font information (e.g. the OpenType 'math' table) in order to do proper layout. Without access to this information for downloaded fonts, the information needs to be duplicated and provided by an sideband channel (currently I extract it from the font, turn it into a JSON object, and download the JSON with the font. This is redundant information which is already in the font). |
There can be a dozen different fonts used to render that element, though, with a dozen different sets of features. Doing this at the element level is the wrong place. interface FontFaceFeatures {
maplike<DOMString, (long or null)>;
/* null for the name-only features like ss01 */
}; This appears to tell you what the feature settings are, not which features are available. Something like this might make more sense: interface FontFaceFeature {
readonly DOMString featureTag;
readonly unsigned long minimumFeatureValue; // Usually 0. Maybe this member isn't even necessary.
readonly unsigned long defaultValue;
readonly unsigned long maximumFeatureValue;
}
interface FontFaceFeatures {
readonly setlike<FontFaceFeature>; // Setlike because there's no order.
}; |
This is for w3c#520. The [resolution](w3c#520 (comment)) is: > RESOLVED: [add this functionality to] css-font-loading, level TBD I added this to level 3, because level 4 doesn't exist. If the editor prefers this go in a level 4, that's no problem. The GitHub thread hasn't come to a conclusion about what should go in the `FontFaceFeatures` interface, so I left it blank for now.
This is for w3c#520. The [resolution](w3c#520 (comment)) is: > RESOLVED: [add this functionality to] css-font-loading, level TBD I added this to level 3, because level 4 doesn't exist. If the editor prefers this go in a level 4, that's no problem. The GitHub thread hasn't come to a conclusion about what should go in the `FontFaceFeatures` interface, so I left it blank for now.
This is for w3c#520. The [resolution](w3c#520 (comment)) is: > RESOLVED: [add this functionality to] css-font-loading, level TBD I added this to level 3, because level 4 doesn't exist. If the editor prefers this go in a level 4, that's no problem. The GitHub thread hasn't come to a conclusion about what should go in the `FontFaceFeatures` interface, so I left it blank for now.
This is for w3c#520. The [resolution](w3c#520 (comment)) is: > RESOLVED: [add this functionality to] css-font-loading, level TBD I added this to level 3, because level 4 doesn't exist. If the editor prefers this go in a level 4, that's no problem. The GitHub thread hasn't come to a conclusion about what should go in the `FontFaceFeatures` interface, so I left it blank for now.
This is for w3c#520. The [resolution](w3c#520 (comment)) is: > RESOLVED: [add this functionality to] css-font-loading, level TBD I added this to level 3, because level 4 doesn't exist. If the editor prefers this go in a level 4, that's no problem. The GitHub thread hasn't come to a conclusion about what should go in the `FontFaceFeatures` interface, so I left it blank for now.
This is for #520. The [resolution](#520 (comment)) is: > RESOLVED: [add this functionality to] css-font-loading, level TBD I added this to level 3, because level 4 doesn't exist. If the editor prefers this go in a level 4, that's no problem. The GitHub thread hasn't come to a conclusion about what should go in the `FontFaceFeatures` interface, so I left it blank for now.
I'll give people a few days to comment if I've messed anything up. Hearing nothing, I'll close this some time next week. |
Does (1) #6596 cover access to the OpenType |
Web authors have requested the ability to know which variation axes and font features are available in the fonts on the page.
The text was updated successfully, but these errors were encountered: