Open drott opened 6 years ago
The ital
axis is a bit weird; as registered, it is more for grouping roman and italic within a family than for a roman to italic variation axis:
The 'ital' axis tag is used within a STAT table of italic fonts to provide a complete characterization of a font in relation to its family within the STAT table. The Italic axis can be used as a variation axis within a variable font, though this is not expected to be common.
The problem is that when it is used as a variation axis, it is not used for matching.
@font-face { /* Font Face 1 has ital = 0.3 */
font-family: Example1;
font-style: auto
}
p {
font-style: italic;
}
Currently, regardless of the value of the ital
axis, it will never be matched with auto, only by explicitly declaring font-style: italic
in the descriptor:
The auto values for these three descriptors have the following effects: For font selection purposes, the font is selected as if the appropriate initial value is chosen
The initial value for the font-style descriptor is normal
, so even with ital=1.0
it will never match unless explicitly described as italic. Instead, the low-level property has to be used:
i, em {
font-family: Example1;
font-variation-settings: 'ital' 0.8;
}
There are a few nuances to this that are worth noting.
When using a variable font in two files (one containing upright characters, one containing italics), family grouping works perfectly in all browsers:
@font-face {
font-family: ExampleFont;
src: url('VariableFont_Roman.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: normal;
}
@font-face {
font-family: ExampleFont;
src: url('VariableFont_Italic.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: italic;
}
This results in every browser I've tested rendering the text correctly, calling the right font file and rendering the proper glyphs, so that
font-weight: 725;
gets you the proper bolder weight;
font-style: italic;
gets you proper italics;
font-weight: 725;
font-style: italic;
gets you the proper italics, set to the bolder value on the weight axis
Where this breaks down is when you have a single variable font file that contains both upright and italics. It's worth noting here that from the type designers' (and OT spec creators') perspective, italics ('ital') is boolean (0 or 1, upright or italic), whereas slant ('slnt') is intended to be a range. And it's highly unlikely that you would have both italics and slant in the same design.
If I understand it correctly, this is why it was implemented in Safari in this way (to use the degree range to indicate the presence of an italic axis). According to @litherum the correct syntax would be something like this:
@font-face {
font-family: ExampleFont;
src: url('VariableFont_Combined.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: oblique 0deg 20deg;
}
where the resulting behavior would be that the browser would inspect the font and based on the presence of an italic axis, clamp font-style: normal
or font-style: italic
to the correct axis value. If there is a 'slnt' axis, it would render at the indicated deg
value along that axis.
Currently, if I use that syntax, everything works as @litherum describes. If I omit font-style
entirely from the @font-face
definition, it will work as expected in all the other browsers, but in Safari it will also synthesize italics on top of the proper use of the italic axis.
Of Note
In all cases, you still get the expected output if you use font-variation-settings
Proposed solution Given that it is quite possible possible to have both a upright and italic character sets in a single file, it seems better to allow more specific declaration. I would suggest:
@font-face {
font-family: ExampleFont;
src: url('VariableFont_Combined.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: normal italic;
}
for when you have upright and italics, and
@font-face {
font-family: ExampleFont;
src: url('VariableFont_Combined.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: oblique 0deg 12deg;
}
for when a slant axis is present.
References: You can see all of this in action on the guide I wrote on the MDN site (it currently uses the syntax that @litherum suggested in the italics section) https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
And there's a CodePen of just the italics set up without the font-style
declaration so you can see it the other way and edit as you see fit.
https://codepen.io/jpamental/pen/EeOyyZ
What needs to happen to move this forwards? :)
@litherum the specification as written conflates the slnt
and ital
axes, and assumes ital
is a boolean. Do we want to fix that? If so how, and if not, how do we handle a font with an actual variable ital
axis?
The MDN site to which @jpamental contributed takes a strong position:
The Italic (
ital
) axis works differently in that it is either on or off; there is no in-between.
Do we want to enforce that? (it is common, but not universal).
I don't understand what motivates designers to create 2 fonts "A", "G" and others, for italic letters. I'm just an end-user, but I CAN'T STAND having to keep checking, before downloading a font, if there is only ONE font, for both the ITALIC and NON-ITALIC options...),=
I don't know if it was clear, but what bothers me the most is the existence, in the same font, TWO different letters "A", as well as letters "G" and others...),=
(Sorry for not replying on this until now.)
I can't really put replies inline, so I'll selectively pull quotes from above.
The font matching algorithm describes that after no match for
italic
is found, oblique 20deg and above should be tried next
This has now shifted down to 11deg (though the exact value doesn't affect the argument at hand).
This results in every browser I've tested rendering the text correctly
Right. The idea is that the @font-face
block should simply report the capabilities of the font file. No more, no less. In this example, there's a font that supports weights from 100 to 900 that isn't italic, and there's another font that supports weights from 100 to 900 that is italic. So far so good.
Where this breaks down is when you have a single variable font file that contains both upright and italics.
This is indeed the crux of the issue. When I designed this feature, I was assured that it was meaningless to say "0.5 ital", and that italics are, therefore, a boolean toggle. I did, however, neglect to handle the case where a font can support both values of the boolean toggle.
I was also assured that it would be a Bad Thing™ to make it easy for an author to request both oblique and italics at the same time. I think this is an orthogonal concern, though, as it affects the grammar of the font-style
property, and not the font-style
descriptor within @font-face
.
I think @jpamental's proposal makes sense, as it agrees with the spirit of making the @font-face
descriptor simply report the capabilities of the font file.
We do have a choice, though, whether we want a font to be able to advertise that it supports both italics and obliques. Do any such fonts exist?
If the answer is "yes," then this is probably the right grammar:
auto | [ normal || italic || [ oblique [ <angle>{1,2} ]? ] ]
If the answer is "no," then this is probably the right grammar:
auto | [ normal || italic ] | oblique [ <angle>{1,2} ]?
I did, however, neglect to handle the case where a font can support both values of the boolean toggle.
Is this still the case or has there been any progress on this issue?
It's very strange not to be able to use font-style
as a descriptor for a variable font file that contains both roman/upright and italic glyphs. If all my reading trying to understand this is correct, it sounds like the only way to use the italic glyphs from such a file is to use font-variation-settings
property when applying the font? But that runs counter to the guidance to "use high level properties" where relevant, and also forces you to re-declare any other font variation settings since resetting the property will overwrite cascaded values for other axes.
Am I understanding this correctly?
@litherum wrote:
We do have a choice, though, whether we want a font to be able to advertise that it supports both italics and obliques. Do any such fonts exist?
It seems we need a good answer to that question, before designing a solution.
Several years ago, @djrrb made a version of his Roslindale typeface where the italic axis is separate from the slant axis (which is used for oblique
settings). He talks about it here:
https://djr.com/notes/roslindale-variable-italic-font-of-the-month/
You can also preview how it works with a live demo here: https://v-fonts.com/fonts/roslindale-variable-italic
That Roslindale Variable Italic was tricky, because ideally I wanted font-style: italic
to implement both the cursive forms of the ital
axis and the slant of the slnt
axis.
I know it’s weird, but maybe also worth mentioning that I also wanted the ital
axis to be able to go past 1, so that I could have cursive forms such as the single-story lowercase g
that were even more extreme than what I wanted to appear in the default Italic appearance accessible via font-style: italic
.
Because of the technical limitations of ital
+slnt
, the full version of the Roslindale family currently blends them both into the slnt
axis, preserving the gradual onset of the cursive forms as the slant increases. The cursive forms are also available as OpenType stylistic sets so that users can still access “sloped roman” and “upright italic” modes, even without the second axis. However, if the ital
+slnt
combo was well-supported, I would happily move back to that approach.
It’s also worth mentioning @arrowtype’s Recursive does a similar thing, but uses a custom CRSV
axis to implement the italic cursive forms instead of the ital
axis.
What if font-style
could accept multiple values, mirroring that the font file is capable of covering several "styles"?
@font-face {
/* The font is expected to provide an 'ital' axis (it may or may not be a visually slanted italic or not, up to the font vendor) */
font-style: normal italic [ital value];
/* The font is expected to provide a 'slnt' axis (it is expected to be visually slanted) */
font-style: normal oblique [slnt angle];
/* The font has both 'ital' and 'slnt' */
font-style: normal italic [ital value] oblique [slnt angle];
}
* {
font-style: normal|italic [ital value] oblique [slnt angle];
/* equals font-variation-settings: 'ital' 0, 'slnt' 0 */
font-style: normal;
/* equals font-variation-settings: 'ital' 1 [, 'slnt' 0] */
font-style: italic;
/* equals font-variation-settings: 'ital' 0.5 [, 'slnt' 0] */
font-style: italic 0.5;
/* equals font-variation-settings: 'ital' 0, 'slnt' 10 */
font-style: normal oblique -10;
/* equals font-variation-settings: 'ital' 1, 'slnt' 10 */
font-style: italic oblique -10;
}
(I don't think a case should be made for "normal 0.5" manipulating the 'ital' axis akin to "italic 0.5", although it could be specced like that — it is more natural to define an "amount of italicness" via the "italic" attribute, imo.)
A variable font covering uprights, cursive forms triggered by "ital" and slanted italics covered by "slnt" could thus be used. It would even allow for gradual triggering of cursive forms using the specced ital range 0 to 1. The obvious inconsistency the two specs make regarding slant/oblique angle direction is already in existence, unfortunately.
On Mastodon, @svgeesus asked for examples of real variable fonts that provide oblique and italic options independently. However, based on the discussion both here & there, it seems font designers are avoiding that for technical reasons, rather than design ones. So I started imagining a design that would include both.
So here is my rough design spec (samples below), for a handwriting font family with two continuous variable axes: SLNT (slant angle) and CRSV (cursive style, from block print through connected cursive). I want easy access to six named instances: Normal, Oblique, Italic, Upright Italic, Cursive, and Upright Cursive. The slant angle for the named oblique style is different from the slant angle used in the named italic and cursive styles. I may or may not make masters for the higher slant angle in the cursive styles, but otherwise assume that both the change in slant angle and the change in cursive style are continuous between the shown samples. The variable font could also have other axes, like weight and width.
My question: How should this be implemented in OpenType? How should the styles be accessed in CSS?
Requirements:
font-named-instance
@font-face
descriptor, and then specifying unique values for other style descriptors or unique font-family names that it should match.)@font-face
rules for loading the same font file either with all variations enabled or as specific named instances.)Ideally (in my opinion):
font-variation-settings
for simple normal vs italic style switches.)font-style
property / descriptor, and the CRSV and SLNT angles will be adjusted to match the named styles in the font.font-style: italic 0deg
.font-style
property. (I think this is currently possible by setting the axis values and desired font-style value in two separate @font-face
rules, but I have no idea how that interacts with more complex values in the font-style
property on a given section of text.)@AmeliaBR Note that the VF spec allows arbitrary axes and convention is to uppercase those arbitrary tags (e.g. "CRSV"), as opposed to lower casing registered axes’ tags. A CSS spec should probably pertain only to registered axes and their ranges so ital
(0 – 1) and slnt
(-90 – 90).
Adapter would be one more variable font with both axes, albeit ital
is a defacto binary one (e.g. note the "a" changing on ital = 1
). Mind you cursive forms also apply to other scripts, e.g. Adapter supports this also for some Cyrillic, and it is perfectly thinkable to have meaning for Greek, Arabic, and many other scripts.
If simplification is the goal one could argue font-style: italic
should instruct the font to use absolute maximum values forital
and slnt
, any of which are found present. This is very often the intent of the design, meaning for a font with:
ital
/ cursive shapes but no slant this works, slnt
and no italic shapes this works, and ital
and slnt
activating both is likely also what the designer wants for the "italic" (the above mentioned Rosalinde and Cursive do this based on slnt
implicitly, and Adapter’s static italic fonts do this) (Mind you, font vendors can choose to implement axes in a way that they implicitly trigger another, so say a VF might be instructed to show ital = 1
cursive glyph shapes if slnt > x
via opentype features. You could argue that activating ital
for given slnt
values is up to the font vendor, but even here even this sample of three fonts yields three different implementations, stemming surely from the ambiguity of this very issue.)
If control is the goal, my suggestion from the previous post is applicable, at the expense of complexity.
It’s also worth mentioning @arrowtype’s Recursive does a similar thing, but uses a custom CRSV axis to implement the italic cursive forms instead of the ital axis.
It was my original intent to use both slnt
and ital
in one font, using the ital
axis for cursive form control instead of making a custom CRSV
axis. However, Google Fonts folks suggested not using slnt
+ital
in the same font – I forget if it was their opinion that this shouldn’t happen or because of an expectation that it might work better in browsers.
We (I) asked you to do that because the behavior was underspecified, iirc.
https://arrowtype.github.io/vf-slnt-test was also great work you did at that time :)
@jpamental initially reported this issue discussing font matching and rendering results for a variable font that has an
ital
axis.I do not see a clear and interoperable way to make them work described by the spec:
Assume there is a font face declaration as follows:
for a font that has an 'ital' axis ranging from 0 to 1.
And a style rule as follows:
The font matching algorithm describes that after no match for
italic
is found, oblique 20deg and above should be tried next, so Font Face 1 is matched.However, as there is no way of specifying
font-style: italic 0 1
the@font-face
declaration and the actual font axes mismatch. The@font-face
declaration pretends to be able to apply aslnt
/ oblique axis varying between 0 and 20 to the font. However, the font does not have aslnt
axis.If we really do not want to have a way of specifying a way for italic (not oblique) to be variable, then I am missing a clarification in the spec that would say something about how
oblique <angle> <angle>
and a resulting matched instance / style likeoblique 20deg
should be applied asital 1
in terms of variation parameters to a font that does not have a realital
axis but instead is declared withoblique <angle> <angle>
.CC @behdad @kojii @jpamental