w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.46k stars 657 forks source link

[css-fonts] Proposal to extend CSS font-optical-sizing #4430

Open Lorp opened 4 years ago

Lorp commented 4 years ago

Introduction

This proposal extends the CSS Fonts Module Level 4 font-optical-sizing property by allowing numerical values to express the ratio of CSS px units to the the units used in the opsz OpenType Font Variation axis. The ratio is intended to be multiplied by font-size, measured in px, allowing control over the automatic selection of particular optical size designs in variable fonts.

The proposal resolves the conflicting implementations of the font-optical-sizing: auto behaviour, and provides additional benefits for font makers, CSS authors, and end-users.

Examples

Background

OpenType Font Variations in CSS

When the OpenType Font Variations extension of the OpenType spec was being developed in 2015–2016, Adam Twardoch and Behdad Esfahbod proposed the addition of the low-level font-variation-settings property to the CSS Fonts Module Level 4 specification, modeled after font-feature-settings.

For higher-level control of font variations, there was general consensus that the font-weight property would be tied to the wght font axis registered in the OpenType specification, font-stretch would be tied to wdth, while font-style would be tied to ital and slnt.

OpenType opsz variation axis and CSS font-size

The consensus was that the CSS font-size property could be tied to the axis registered for optical size, opsz. The opsz axis provides different designs for different sizes. Commonly, a lower value on the opsz axis yields a design that has wider glyphs and spacing, thicker horizontal strokes and taller x-height. The OpenType spec suggests that “applications may choose to select an optical-size variant automatically based on the text size”, and states: “The scale for the Optical size axis is text size in points”. Apple’s TrueType Variations specification (on which OpenType Font Variations is based) also mentions point size as the scale for interpreting the opsz axis: “'opsz', Optical Size, Specifies the optical point size.” It is notable that neither the OpenType spec nor Apple’s TrueType spec addresses the interpretation of opsz values in environments where the typographic point is not usefully defined.

Optical sizing introduces a new factor in handling text boxes in web documents. If the font size of a text box changes, the proportions of the box not remain constant because of the non-linear scaling of the font; typically the width grows at a slower rate than the height, because of the optical compensations in typeface design mentioned above. Realizing that many web documents may rely on the assumption of linear scaling, Twardoch proposed an additional CSS property font-optical-sizing:

The font-optical-sizing property is currently part of CSS Fonts Module Level 4 working draft.

Controversy: opsz axis and CSS font-size (px vs. pt)

Unfortunately recent browser developments introduced ambiguity in terms of how opsz values should be interpreted:

Proposed resolution: numerical values in font-optical-sizing

The CSS font-optical-sizing property currently controls the relationship between font-size and opsz by means of a simple switch (auto/none). We propose to allow a numeric value for font-optical-sizing. This value expresses the ratio of opsz units to CSS px. Examples:

Results

Note

Proposers

twardoch commented 4 years ago

I’d like to add that in the old times with static TTFs, the original ppi difference between Mac and Windows resulted in different ppm sizes of the font being used for a given pt size. This was optical sizing to some extent on screen because of different hinting instructions being used, but the difference was quite small in most cases. Only very few fonts modified the advance width to a noticable extent, and ultimately many apps such as Word discouraged that, caching higher-res spacing and enforcing it — to prevent reflow when zooming.

But with opsz, it’s dramatic. Most fonts with opsz will have quite noticeable spacing differences between 9 & 12 or between 12 & 16. That's the whole point of optical sizing.

I’m no longer sure which numbers to use, but I know a few things:

  1. When in doubt, it's better to user the lower opsz value. Choosing a “too low” opsz value will get you slightly clunkier text but it will be readable. Choosing a “too high” opsz value will get you unreadable text that’ll defeat the purpose of font-optical-sizing.

  2. If we get end up having inconsistent implementations, then we really should stop. As the original author of the font-optical-sizing property, I’d call for its removal, and I’d recommend that opsz is never automatically selected.

  3. Ultimately, we’re still early in the process (there aren’t many VFs with opsz, and if there are some, they can be fixed). But it really matters that we do it “right”, and communicate it clearly.

  4. Adobe has the largest library of fonts with optical sizes as an axis (there were the old MMs and I imagine they could make some test VFs). Because perhaps we should try to eyeball it. Though still, a potential *0.75 difference is just huge.

  5. Even if we adopt a consistent solution, this proposal for extending font-optical-sizing with a multiplier still is very useful. Ultimately, it’s a tool to control the viewing angle, or “gamma”. There will always be cases where the automatic opsz selection will be not optimal — for a tiny dense screen or when using a projector, or when designing something in DIN A4 that will then ultimately be printed as a poster.

litherum commented 4 years ago

@robmck-ms

Of course, we can't do that because we wouldn't have cross-platform consistency.

There are plenty of things that are not consistent across platforms on the web. Text antialiasing, generic font families, behavior of editing commands, and now optical sizing. Indeed, having pixel-exact renderings across platforms is an anti-goal of the web.

and the web follows the macos convention

I’m not proposing that the Web following the macOS convention. I’m proposing that each browser follow the platform conventions that they’re running on.

Regarding optical sizing specifically, we’ve arrived at a tension between consistency across multiple apps on a particular platform, and consistency of a particular app across multiple platforms. When those two are in conflict, consistency across multiple apps on a particular platform wins, because there are way more users who use multiple apps on a particular platform than who use a particular browser across multiple platforms.

The bottom line is: We can’t have text rendering looking different in Safari than on the rest of the platform (by default - if the web author wants it to look different, they can use font-variation-settings).

robmck-ms commented 4 years ago

I’m proposing that each browser follow the platform conventions that they’re running on.

Regarding optical sizing specifically, we’ve arrived at a tension between consistency across multiple apps on a particular platform, and consistency of a particular app across multiple platforms. When those two are in conflict, consistency across multiple apps on a particular platform wins, because there are way more users who use multiple apps on a particular platform than who use a particular browser across multiple platforms.

Given that, do you believe then that Firefox (and I believe Chrome is going in the same direction) have incorrectly built their non-macos implementations as they follow the macOS one of opsz=CSS px, which does not equal the OS point size on other platforms?

If it is to be the case that some browsers follow opsz=CSS px, and other browsers and non-browser apps follow opsz=points (CSS, docx, pdf, etc), do you have a recommendation for mitigating the problem that one font cannot be designed for all this? Relying on font-variation-settings is untennable in practice as it does not cascade well in the complex DOMs in most big production sites. I've talked to several design studios of various Microsoft sites and they've all given up on font-variation-settings. Things need to work from the higher-level settings (font-weight, font-stretch, etc).

Also, I would still like to understand: How will optical size be handled on macOS outside the browser, as the rest of the platform does not have a 4:3 ratio to grapple with? Will there not be inconsistency already?

litherum commented 4 years ago

I can't comment on other specific implementations. (I've been yelled at before by maintainers of those other implementations for doing so.) All implementations should follow the individual typographic conventions of the platforms they ship on, for each platform they ship on. Luckily, the platforms I work on share this typographical convention.

Matching the typographical conventions of the OS is a good thing, and is correct. It should be difficult to achieve incorrect behavior in CSS. It's certainly possible to achieve incorrect behavior in CSS, both in general, and with font-variation-settings. I don't think we should be making it easier for authors to achieve incorrect behavior when they can already achieve it themselves using the existing facilities.

litherum commented 4 years ago

@robmck-ms

How will optical size be handled on macOS outside the browser

Sorry, I don't understand the question. App authors specify font size in points, and we render it at the appropriate size in points. There doesn't seem to be any inconsistency here.

robmck-ms commented 4 years ago

Matching the typographical conventions of the OS is a good thing, and is correct.

I would also say that producing legible text, and having fonts that work the same everywhere are also good things, both correct.

robmck-ms commented 4 years ago

How will optical size be handled on macOS outside the browser

Sorry, I don't understand the question. App authors specify font size in points, and we render it at the appropriate size in points. There doesn't seem to be any inconsistency here.

This is exactly my point (pun not intended): As you describe, other apps will specify font size in points, thus opsz will be set to that same value. The app rendering 12pt text will do so with opsz=12. But, in the browser, a document that specifies font-size: 12pt will render with opsz=16. Thus, if you open a number of apps - Word, Pages, Text Edit, and Safari, with documents that specify 12pt in the documents coordinate system, and render at 100% zoom, Safari will render with opsz=16 and all others will use opsz=12. Safari will be inconsistent with everything else.

Your argument rests on the principle that internal consistency is paramount over all other issues (including cross-platform). My assertion is that Safari as implemented is already inconsistent from the point of view of the units that customers use in the documents they create. My assertion may be wrong, and if so I would happy to learn from my error.

litherum commented 4 years ago

On all Apple platforms, optical size is applied automatically for most fonts. Native app authors don’t have to do anything and they just get optical sizing goodness automatically. This is very similar to CSS where the initial value of font-optical-sizing is auto.

Even for fonts which don’t get automatic optical sizing, authors enable optical sizing by specifying "auto" for the kCTFontOpticalSizeAttribute key like so:

CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes(@{(NSString *)kCTFontOpticalSizeAttribute : @“auto”});
CTFontRef resultFont = CTFontCreateCopyWithAttributes(originalFont, CTFontGetSize(originalFont), CTFontGetMatrix(originalFont), descriptor);

In fact, this code is exactly what WebKit does internally.

Native app authors can also specify a numerical value of optical sizing if they want, just like they can in CSS using font-variation-settings.

Therefore, by default, CSS text rendering uses the same optical sizing value as native text rendering on Apple platforms.

litherum commented 4 years ago

Thus, if you open a number of apps - Word, Pages, Text Edit, and Safari, with documents that specify 12pt in the documents coordinate system, and render at 100% zoom, Safari will render with opsz=16 and all others will use opsz=12.

I thought I showed in https://github.com/w3c/csswg-drafts/issues/4430#issuecomment-543315394 that 1 CSS px in all browsers on macOS = 1 point in all native apps on macOS (for some definition of “all”). It seems to me that opsz values fall out naturally from this.

davelab6 commented 4 years ago

Adobe has the largest library of fonts with optical sizes as an axis

@twardoch how many is that, exactly?

there were the old MMs and I imagine they could make some test VFs).

Err if they have old MMs and haven't converted them to OpenType VFs, I'm not sure they can be counted here :)

However, Httparchive shows that opsz is currently the most commonly used axis today, followed by weight and width. So resolving the problem @lorp has identified seems to me very urgent.

davelab6 commented 4 years ago

I've talked to several design studios of various Microsoft sites and they've all given up on font-variation-settings. Things need to work from the higher-level settings (font-weight, font-stretch, etc).

@robmck-ms I'm curious, did you tell them to use FVS using CSS custom properties as values?

@roeln blogged about this at https://pixelambacht.nl/2019/fixing-variable-font-inheritance/ and I believe this gives CSS authors the "higher level setting" capabilities they are ragequitting without... like the 'inheritance' that is the C in CSS ;)

I am hopeful that CSS custom properties used in this way will prevent the need for many new high level properties for axes that will soon be commonly used but not registered by Microsoft in the OpenType Spec

davelab6 commented 4 years ago

How about a new opsx axis that is specified to pixels not points?

dberlow commented 4 years ago

There is opsz, but as we know now it is some value translated into some pixels translated in some size by environments, and not necessarily resulting in type where the input in points represents the output in typographic points.

We should then resurrect POPS, FBs proposed optical size axis that is valued only in typographic points, as determined by standard measure of 72 to the inch, or equivalent devices whose ppi can be measured in actual pixels per inch/72.

And PPMS could stand for an axis that represents pixels per em, which would be useful for variations based on pixels as the target for both typographic glyphs, (the more complex the glyph(s), the more useful such an axis would be), and also for emoji and other small graphics, where pixels are important, and either resolution is not, and/or hinting in not available. Such an axis could require separate x and y values, though today, its target would be primarily be a square grid.

On Jan 17, 2020, at 12:22 PM, Dave Crossland notifications@github.com wrote:

 How about a new opsx axis that is specified to pixels not points?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

davelab6 commented 4 years ago

We should then resurrect POPS

I thought you proposed that as OOPS :P

That is what I am suggesting, but I think to pair opsz with pops wouldn't be wise because they would not sort together in a simple alphabetical list of axes in a font; whereas opsx will sort next to, but just before, opsz, and is more obviously related :)

arrowtype commented 4 years ago

Whew, this is a long thread. I hope I don’t repeat points too much, but I think a couple are worth calling out.

There is no way for a font maker to make a single font that works the same in print as it does on the web. For example, many font makes have customers in the magazine, newspaper and book publishing world (as well as advertising), who care very much that print matches web.

Echoing @robmck-ms on this – to me, this is the single biggest problem in the current implementation.

As a personal example, I am working on a typeface which has a “Text” style at opsz=12. The basic idea here is to optimize this style for ideal readability at the common default text size of 16px on the web and 12pt in print (at least in MS Word). This is based on my speculation that the majority of the total words read in this font will be at platform default sizes.

I do not want to disrupt text scaling between browsers and the rest of macOS, and I don’t think anyone here is suggesting doing that. I don’t really mind that 12pt on my MacBook screen is not the same at 12pt on a typographic ruler. However, I do worry about how I will explain to people that even though optical sizing is “automatic” in web browsers, it automates in a way that makes things more confusing, so they will still have to use font-variation-settings to accurately match the design of Text between web and print.

In my case, 12pt or 16px (on a MacBook Pro 16" screen at default scaling) is significantly physically smaller than 12pt printed out from a document in macOS Pages. The same test site renders with still smaller physical size when viewed on an iPhone XR.

This means that the optical size problem is compounded, because when the browser selecting opsz=16 rather than the intended opsz=12, it is inaccurate in the in an extra-unhelpful direction, making letterspacing even more extra-tight-fitting than its larger size. For designs that are high-contrast fonts (e.g. Didots), this would be an even worse problem. As @twardoch said:

When in doubt, it's better to user the lower opsz value. Choosing a “too low” opsz value will get you slightly clunkier text but it will be readable. Choosing a “too high” opsz value will get you unreadable text that’ll defeat the purpose of font-optical-sizing.

image

Before realizing the magnitude difference in physical scale between 12pt on screen vs 12pt on paper, I was pretty skeptical of the numeric scaling proposal at the top of this thread. However, with this physical difference in mind, I think it would be very sensible to give CSS users the ability to dial in the scaling of optical sizing.

The one tweak I would suggest is that it would probably make more sense to newcomers for the default to be font-optical-scaling: 1;, and for this value to make 12pt in CSS apply opsz=12, to better meet the OpenType spec (“Scale interpretation: Values can be interpreted as text size, in points.”) and to help make sure that default text at 16px can use a default Text opsz. This would not have to change anything about the way browsers scale px or pt; it would simply modify the way opsz is called to be more accurate. And then, if a magazine publisher wanted to really match a certain context (e.g. Safari on the latest iPhone) to their print design, they would have the ability to tweak this automated behavior to achieve that goal (or even use JavaScript to match many different devices to the print sizing & optical design).

davelab6 commented 4 years ago

As I prepare optical size upgrades to popular Google Fonts families for publication, this is becoming more vexing for me.

Lorp commented 4 years ago

Thanks for this, @arrowtype. It’s a good suggestion. Even though CSS uses px as its basic measure, the notion of optical size is usually talked about in “points”, and all user agents know about CSS pt. As you say, it’s much more intuitive to authors if the default is 1. They will, it may be hoped, get a sense of what it means to make the value larger than 1 or less than 1.

dberlow commented 4 years ago

While I agree 1/2-way with: As @twardoch said: "When in doubt, it's better to user the lower opsz value. Choosing a “too low” opsz value will get you slightly clunkier text but it will be readable. Choosing a “too high” opsz value will get you unreadable text that’ll defeat the purpose of font-optical-sizing."

The importance of size can cast doubt on that doubt, if it does not entirely reverse it. So, when in doubt at small sizes, it's better to use the smaller opsz value, as more readable text is likely while choosing a “too high” opsz value is likely more economical, and likely less readable text. And, when in doubt at large sizes, it's better to user the larger opsz value, as more economical text is likely while choosing a “too low” opsz value is likely to have less economical text. (Verdana headlines anyone?)

In some other words, it is not my belief that some vague sense of aesthetic improvement was, or should be today, the motive for the variation to larger optical sizes. It's got economic purpose in print and online. What I think this means to the implementation of opsz in css is that it should not end up cheating "down" everywhere, if possible.

On Wed, May 20, 2020 at 5:48 AM Laurence Penney notifications@github.com wrote:

Thanks for this, @arrowtype https://github.com/arrowtype. It’s a good suggestion. Even though CSS uses px as its basic measure, the notion of optical size is usually talked about in “points”, and all user agents know about CSS pt. As you say, it’s much more intuitive to authors if the default is 1. They will, it may be hoped, get a sense of what it means to make the value larger than 1 or less than 1.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/w3c/csswg-drafts/issues/4430#issuecomment-631368853, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAO5VDQ7N55CTEGTPVZ6HEDRSORP7ANCNFSM4JBXYCMQ .

arrowtype commented 4 years ago

That’s a good point, @dberlow. The ideal is obviously that opsz should be predictable and accurate, not cheated up or down.

My main point was that in the current implementation, the inaccuracy is bad for text on two levels: 12pt text on (my Mac & iOS) screens is already physically smaller than 12pt on paper, BUT it is given a higher optical size.

But yes, it is true that too-low-opsz headlines would not be a useful outcome.

VivaRado commented 4 years ago

I think optical size is an "Effect" just like responsive CSS. I don't think it should be embedded in the font structure. You should just be able to state in CSS you want something "optical-size:5px pt em whatever measurement", and then if you animate the size or transition: optical-size, it should deal with it. Maybe one should provide the optical size axis array to CSS when loading a fontface just like one would embed it to OPS when compiling a variable font. Or maybe CSS should read the OPS from a variable font to retrieve such details and all you need to do is just activate the functionality. In the meantime i think one could achieve better optical sizing if he explicitly coded it in CSS and JS than the current state of variable interpolation that seems to miss hell of a lot because of some hard-coded threshold in size.

tiroj commented 4 years ago

The variable opsz axis provides a means for the font maker to tune the design of glyphs for specific sizes and size ranges (with a lot of flexibility in terms of how much or how little interpolation to rely on between size instance delta sets) and to deliver that size-specific design variation to users. How downstream clients interpret the opsz axis is in some respects up to them, but in order for everyone involved to be able to predict what the others are doing and provide the most useful and highest quality typographic tools to users, there needs to be some respect for an agreed and standardised scale. The scale unit defined in the OpenType Font Format specification is the typographic point, i.e. 1/72 physical inch. How that gets interpreted in e.g. applications that deal with visual angle and distance in VR/AR, is going to be different from how it gets interpreted in physical page layout software, but the point is that the standard scale needs to be interpreted, and pretending that the scale is px instead of typographic points isn't interpreting the scale: it's throwing it out and doing something unpredictable.

@davelab6 :

How about a new opsx axis that is specified to pixels not points?

That's relatively easy to add to the OT axis registry, and reasonably easy to add to existing fonts with optical sizes axes — much of it could be done using the same source masters and different mapping of design space units to axis units —, but re-reading everything above I'm not sure whether it would solve the problem or not. I mean, when someone makes a reasonable case that 1/72 inch and 1/96 inch are the same thing and anyway an inch isn't an inch, I lose all certainty about anything. 😬

davelab6 commented 4 years ago

@tiroj :

How about a new opsx axis that is specified to pixels not points?

I'm not sure whether it would solve the problem or not.

Right, because as @drott says in https://bugs.chromium.org/p/chromium/issues/detail?id=773697#c17, the real problem is now that,

We can't make a change in Chrome that breaks existing usage and introduces interoperability issues while currently all browsers are aligned.

So when you say,

the standard scale needs to be interpreted, and pretending that the scale is px instead of typographic points isn't interpreting the scale: it's throwing it out and doing something unpredictable.

it seems to me you are using the wrong tense: The reality here in May 2020 is that it WAS thrown out, because today all browsers (plus Apple's OSes) are indeed doing something "predictable" with opsz values – treating them as pixel sizes.

And therefore for MS to add a new opsx axis to the OT spec, that is specified to pixels not points, would not help, because it will take a couple of years for that to happen and be implemented, and opsz will still be treating the values as pixel values in browsers and Apple OSes.

So, it seems to me that given how little font-optical-sizing:auto has been implemented outside of browsers and Apple OS, rather than add an opsx axis, the only practical solution here apart from a new font-optical-sizing property, is for MS to update the OT spec to clarify that actually the opsz values are pixels, not points.

As far as I know (and I'll be happy to be corrected on this!) there are not yet any fonts widely adopted that use the opsz axis; not even the San Francisco or New York families in macOS, which can be downloaded from https://developer.apple.com/fonts – they are distributed as dozens of OTF files.

In fact, I would guess that the number of fonts ever made publicly known with an opsz axis is under 1,000, and therefore it is entirely practical to let everyone who has made opsz fonts know that the OT spec is about to change in this way, and allow them to recalibrate and prepare to re-release their fonts in advance of the change.

arrowtype commented 4 years ago

What if the new axis were Optical Point Sizing, (e.g. oppt or ptsz)?

The main problems, as I see them, are:

  1. Print-based applications set type in points, and this probably won’t change. Certainly, average word processors won’t add a choice of pt/px units, because average users would be perplexed by this. Further, professional designers are extremely unlikely to change their font sizes to px. So, simply changing opsz to px without a way to make this work in print would be bad for these users.
  2. The web is obviously very centered on px units, and this probably won’t change, either. It is understandable that we wouldn’t want to change this & burden CSS writers with understanding that their font px sizing is converted to pts in the opsz axis. It’s still early, but treating opsz in px is already fairly established in browsers & macOS and may be hard to change (and not necessarily beneficial to change).

And yet, if there is no way to predictably design fonts that act in the same way, it will be confusing for everyone (as is the case now). Type designers will have to create different axes for print vs web, which would add additional complexity and chance for error, and additional burden on users to know what to select. This would also cause issues for platforms like Google Fonts & Adobe Fonts, as they too would be faced with the challenge of helping users navigate this complexity.

However, if there were axes for both opsz (in px) and ptsz (in pt), this all might be resolvable.

Browsers could request opsz at the px size as they currently do, but could implicity also request ptsz at px*0.75. Print-based apps could request ptsz at the pt size, but could implicitly also request opsz at pt*4/3.

If a CSS user requests font-variation-settings: 'opsz' 16;, I believe this should also implicitly request 'ptsz' 12, unless for some reason the user passes a different value for ptsz.

Then, in the OpenType spec, these two axes would refer to one another, making it clear to font designers that only one or the other of these axes should be used in the same font. It should also make it clear that software should make the implicit requests, with the suggested conversion of 3:4, pt:px.

Caveat: potentially, a type designer would want different behavior between optical sizing in web vs print and so might reach for opsz+ptsz in the same font, but I believe this would be a very good case for them to actually release two different fonts.

tiroj commented 4 years ago

Browsers could request opsz at the px size as they currently do, but could implicitly also request ptsz at px0.75. Print-based apps could request ptsz at the pt size, but could implicitly also request opsz at pt4/3.

If scaling is implicit, why do we need two axes?

My main concern about the proposal to redefine the scale unit of the opsz axis to px — apart from grumpiness about rewarding people for ignoring the spec — is that as type designers we have accumulated knowledge and experience about designing for and with the two sets of units — font units per em and typographic points — that are the common currency of our work. I know and can form mental pictures of 6pt type and how it differs from 12pt type, and my font development tools and most of my proofing environments are all built around the same units. I don't have a mental image of 6px or 12px type.

So I'm trying to imagine how, as a type designer, I would approach designing for an opsz axis in px units, and what kinds of tools I would want for that task that differ from my current tools. Probably, I want to continue to design point size masters, and have a px axis scale calculated on export.

Then there's the page layout apps, word processors, etc. that will have the job of interpreting (scaling) the px opsz axis to points and other units used internally. And what is the likelihood that some big player will decide 'Oh, we're just going to interpret the scale as typographic points, because that's easier for us and fits with some knot that we've previously tied ourselves up in'?

behdad commented 4 years ago

And what is the likelihood that some big player will decide 'Oh, we're just going to interpret the scale as typographic points, because that's easier for us and fits with some knot that we've previously tied ourselves up in'?

The likelihood is 1.0. That's a fact.

davelab6 commented 4 years ago

In @lorp's OP here, he wrote,

font-optical-sizing: auto; use the font-optical-sizing ratio defined in the user agent stylesheet

@arrowtype :

Print-based applications set type in points, and this probably won’t change. Certainly, average word processors won’t add a choice of pt/px units, because average users would be perplexed by this. Further, professional designers are extremely unlikely to change their font sizes to px. So, simply changing opsz to px without a way to make this work in print would be bad for these users.

The consequence of updating OT opsz from pt to px for the print-focused applications that use pt, would be that the app should have to convert px to pt, and not require users to do it by hand all the time.

Afterall, since we are talking only about applications which auto-apply opsz, then those applications must have some equivalent to a "user agent stylesheet," even if it is just their code that says $TEXT_SIZE_VALUE == $OPSZ_VALUE and now has to say $TEXT_SIZE_VALUE == $OPSZ_VALUE * 1.25

So, average word processors don't need to add a choice of pt/px units, and average users don't have to do anything – and if the OT spec is NOT updated, then the average users WILL be perplexed by hugely inconsistent font styles.

Similarly, professional designers don't change their font sizes to px and remain in pt.

davelab6 commented 4 years ago

I'm trying to imagine how, as a type designer, I would approach designing for an opsz axis in px units

You have to do the 4/3 (or 0.75) math when at the very end of your process you configure your axis values. This is trivial.

behdad commented 4 years ago

I thought I showed in #4430 (comment) that 1 CSS px in all browsers on macOS = 1 point in all native apps on macOS (for some definition of “all”). It seems to me that opsz values fall out naturally from this.

That's a very passive way of saying "Safari screwed up". As long as there's such denial I don't think we can come up with a better proposal.

Lorp commented 4 years ago

Aren’t we counting angels on pins? We seem to be blissfully assuming that we all know what “Actual Size” or “100% zoom” means. The scale factor of so-called “actual size” to “real distance measured off the screen with a ruler” varies tremendously and is barely documented. Where can I find a table which states this scale for all iOS devices, or all Macs, or all Samsung phones, or all Surfaces? Why isn’t data so fundamental included in widely published “tech specs”?

A personal vent:

On the built in screen of my MacBook Pro, “Actual Size” increases significantly when I attach an external display, unmirrored. Possibly this new scale depends on the resolution of that display, possibly it always does that with external displays. I have no idea how to keep it at its native “Actual size”. How opsz is supposed to cope with this, I have no idea :-(

davelab6 commented 4 years ago

Aren’t we counting angels on pins?

I think this is why your OP proposal is good. But since we need to support optical size in a simple way, I believe we need to

  1. redefine the unit of opsz, AND
  2. add a 2nd oppt axis (same deltas, very small filesize impact to have both opsz and oppt in the same font), AND
  3. allow the CSS font-optical-sizing property to have numerical values, are all needed.

Perhaps for (1) it needs to be redefined from Typographic Points to CSS Points, not CSS Pixels, and then (2) is not needed. Or (2) has to be CSS Points.

davelab6 commented 4 years ago

@Lorp you proposed

  • font-optical-sizing: 0.5; custom behaviour where 2px = 1 opsz unit, to “beef up” the text (e.g. in an accessibility mode for visually impaired end-users)

But if this "beefs up" the text, and

  • font-optical-sizing: 2.0; custom behaviour where 1px = 2 opsz units, to reduce the “beefiness” of the text (suitable for large devices)

is "to reduce", then should this be instead of an opsz:px ratio, a px:opsz ratio, eg

  • font-optical-sizing: 0.5; custom behaviour where 1px = 2 opsz units, to reduce the “beefiness” of the text (suitable for large devices)
  • font-optical-sizing: 2.0; custom behaviour where 2px = 1 opsz unit, to “beef up” the text (e.g. in an accessibility mode for visually impaired end-users)

0.5 for me is intuitive as "1px = 2 opsz" as 1/2

2.0 for me is intuitive as "2px = 1 opsz" as 2/1

Lorp commented 4 years ago

Inverting the value is fine by me. I think my rationale for orientation was that 0.75 looks nicer than 1.333333333 :)

My “angels on pins” comment is mainly intended to remind us how much this stuff varies. I don’t mean to dump on device manufacturers. They’ve chosen these scales with good intentions, based on expected subtended visual angles. The lack of documentation is just a darn shame.

davelab6 commented 4 years ago

0.75 looks nicer

Fair enough, since its a very common value - arguably, the best default - then that is not just about looks.

I suppose that a value below 1.0 is more useful for 'small' text (where visually impaired end-users can be helped) also has some intuitive value! :)

arrowtype commented 4 years ago

@davelab6, I wanted to test a suggestion you made here:

add a 2nd oppt axis (same deltas, very small filesize impact to have both opsz and oppt in the same font)

I made a simple test of this approach, at https://github.com/arrowtype/overlapping-axis-test.

If I understood your suggestion correctly, you were suggesting that a font might be given two axes that controlled the same deltas, but with different scales. However, I believe my test shows that a variable font cannot currently do this. With either a simple or a complex approach, the two axes will have interdependencies with unintended results.

Therefore, I still believe that if we wish for one optical-sizing axis that can be defined in px and another that can be defined in pt, we would have to recommend type designers use one or the other, but not both. Additionally, the fact that several smart people in this thread are having challenges understanding the implications of conversion between these values indicates that this conversion should be handled in platforms rather than in all fonts, as there will be more fonts in the long term, and therefore more possibility for mistakes by the font creators.

tiroj commented 4 years ago

If I understood your suggestion correctly, you were suggesting that a font might be given two axes that controlled the same deltas, but with different scales. However, I believe my test shows that a variable font cannot currently do this. With either a simple or a complex approach, the two axes will have interdependencies with unintended results.

That would be addressed with avar2.

arrowtype commented 4 years ago

That would be addressed with avar2.

Thanks, that was my conclusion. (avar2 is the new name for xvar, correct?) Any guess at when this might this be implemented?

To @davelab6's comment:

So, average word processors don't need to add a choice of pt/px units, and average users don't have to do anything – and if the OT spec is NOT updated, then the average users WILL be perplexed by hugely inconsistent font styles.

Similarly, professional designers don't change their font sizes to px and remain in pt.

I am concerned that professional designers (or designers using pro tools, e.g. InDesign, Illustrator, Sketch, etc) will still want to have confidence that they are using the correct optical sizing. If they enter font size "10" and they allow opsz to be automatically set, won’t they be confused that their variable axis UI shows opsz at "13.333"? Presumably, this would lead to errors – I trust CSS devs to generally have a better grasp that font sizing can inherently have multiple different values, as this is core to the use of CSS (e.g. CSS authors use em, rem, vw, %, depending on their goals, whereas a print designer would very seldom stray from font sizing in points).

Maybe a good argument in favor of opsz in px is that print apps tend to base font selection on named instances, so users wouldn’t normally be confronted with the conversion. Most print designers still haven’t encountered the opsz axis yet, so they probably would just accept that its scale wasn’t set to match pts, even if they never quite understood the conversion. And, those that really wanted to understand conversion could figure it out.


To @litherum's comment:

Thus, if you open a number of apps - Word, Pages, Text Edit, and Safari, with documents that specify 12pt in the documents coordinate system, and render at 100% zoom, Safari will render with opsz=16 and all others will use opsz=12.

I thought I showed in #4430 (comment) that 1 CSS px in all browsers on macOS = 1 point in all native apps on macOS (for some definition of “all”). It seems to me that opsz values fall out naturally from this.

When text is at 12px in Safari, that indeed matches the font sizing of 12pt in macOS Pages at 100% scaling. Because Pages does not yet allow for custom variable axis settings and does not select opsz automatically based on size (it currently just allows selection of instances within a VF), I can’t say what opsz it might use for 12pt text, were it to support opsz in a more automatic way in the future.

However, if the OpenType spec remains the same, I would hope that Pages would set opsz=12 for 12pt text, so that printed documents would use the accurate opsz setting. If the opsz value were changed between what was shown on screen and what was printed to paper, then it might allow reflow to happen, which would be a pretty bad outcome.

And so, it would be better for Pages to preview opsz in points, regardless of the physical size on screen.


To @Lorp’s comment and others about not being able to predict real size:

I have no idea how to keep it at its native “Actual size”. How opsz is supposed to cope with this, I have no idea

I think this is the best case for the original proposal here, adding scaling numbers. Site owners who are really trying to get close to correct physical optical sizing could probably do so with some JS + CSS.

But, as you say, there is no clear documentation around what devices have what physical scaling, so this would basically require someone to do a lot of testing, and may need something like an NPM package to handle decently.

In the end, it’s hard to even be confident in knowing what paths there are forward on this. I think the options I see are:

  1. Browsers change opsz to use pt values, disrupting existing implementations and requiring CSS devs to understand conversion if they want predictable results.
  2. The OpenType spec changes opsz to use px values, requiring print designers to understand the scale conversion if they want predictable results.
  3. OpenType makes the oppx & oppt axes, and apps query for both with the conversions done implicitly. The main drawback here is that probably not all apps would adopt this, and users & type designers might be confused at the related but mutually-exclusive axes.

Maybe "the web way" just wins this one and we end up with route 2, simply because the web was the faster platform to adopt & support this axis?

In any case, I still think the original proposal here would be a helpful way devs could patch the fact that physical size varies by device.

tiroj commented 4 years ago

(avar2 is the new name for xvar, correct?) Any guess at when this might this be implemented?

avar2 refers to what seemed, as of the last face-to-face meetings in 2019, to be the most likely implementation of virtual/meta axis mapping, which would be a new major version of the avar table. So it's not finalised by any means, and I suppose xvar or some other new table could eventually win out, but for now I am calling it avar2.

As to implementation ... no idea. There's no one formally responsible for the OT spec at MS any more, so trying to move anything forward is frustrated.

davelab6 commented 4 years ago

@tiroj And what is the likelihood that some big player will decide 'Oh, we're just going to interpret the scale as typographic points, because that's easier for us and fits with some knot that we've previously tied ourselves up in'?

@behdad The likelihood is 1.0. That's a fact.

Kindly, yes, now all browser developers have made this issue entrenched. It is now a serious problem.

But I think we are still in the window of opportunity to address it, before it gets out of hand! :)

So, please lets take this seriously – a danger that is clear and present – and not weigh speculation about what some 'other big player' might do.

Such a player will be saying "we do not have existing usage to break, but we are willfully introducing interoperability issues with all browsers." It is a risk, not an actual and serious problem.

@litherum I thought I showed in #4430 (comment) that 1 CSS px in all browsers on macOS = 1 point in all native apps on macOS (for some definition of “all”). It seems to me that opsz values fall out naturally from this.

@behdad That's a very passive way of saying "Safari screwed up". As long as there's such denial I don't think we can come up with a better proposal.

Well, hang on, Behdad :)

Miles' comment 543315394 is followed by comment 543319478 where he says emphatically,

We are absolutely applying [opsz values] correctly.

But then in comment 543408963 Miles says, emphasis mine,

From this result, it appears that the size of a typographical point is different between Windows and macOS / iOS. This is a very interesting result, and I didn't realize it or try on Windows when implementing this. Thanks @davelab6 for the suggestion!

That doesn't seem like 'denial' to me :)

So then in comment 547560995 Miles reaffirms that this platform consistency is desirable:

If Safari matched CSS points, it would be incorrect on macOS and iOS. In fact, we used to do it wrong, and I fixed it in https://bugs.webkit.org/show_bug.cgi?id=197528

@robmck-ms made this proposal, recognizing this desirability as its first poinit:

First, we must not make any changes to the fundamental assumptions that have already been made for text sizing. Macos will still have 1 CSS px = 1 CT px = 1 macos typo pt, as it should be, and analogously in other platforms.

Second, the implementation recommendation would be that browser set the value of opsz to 4/3 of CSS px. As I understand it, the CSS px is the fundamental, common unit, so we relate the recommendation to it and not "point" as it is too varied in definition and implementation (CSS point, macos point, windows point, UK point, European point, ...).

By doing this, print matches the web; legibility is maintained; and the CSS specification and OpenType specifications are in harmony (as opposed to dissonance we are experiencing in this thread).

Failing that, then we still need some other solution. W3C could adopt @Lorp and @twardoch's proposal, as it's a lovely compromise. But, I know I'd have to recommend everyone set font-optical-sizing to 0.75 to make fonts work, and the engineer in me cringes at the idea of having a solution in which everyone sets X to Y to work well. But perhaps there is another solution?

So, I believe the 'other solution' is simply making font-optical-sizing accept a ratio value, and making the CSS Fonts module recommend a default 0.75.

It seems clear that since "if Safari matched CSS points, it would be incorrect on macOS and iOS" then Apple is likely to retain a default of 1.0.

And therefore not everyone sets X to Y to work well, but only people who care about Apple's platforms.

So, I think really the big question here is for Miles – Miles, is this correct? Would you be willing to support font-optical-sizing values, and if so, what default would you use?

davelab6 commented 4 years ago

With either a simple or a complex approach, the two axes will have interdependencies with unintended results.

Only if you use both at the same time. Just don't do that.

tiroj commented 4 years ago

We're talking about optical design variation, i.e. tuning design to specific optical size. I could easily make the case for defining degrees of visual angle as being the most appropriate unit for opsz, but the point is that in order to be something targetable in design the unit needs to be an absolute physical measurement because we have — better or worse — absolute physical eyes.

So type designers and, I believe, the authors of the opsz axis specification, understood ‘typographic point’ to be 1/72 of a physical inch. So Miles' observation that

it appears that the size of a typographical point is different between Windows and macOS / iOS

suggests to me that a) the spec fails to explicitly state what is meant by ‘typographic point’, and b) different people are using the term in different ways.

I think I understand Miles’ explanation of why there are CSS points, and Cocoa points, and probably other points, but there needs to be one term that refers explicitly to 1/72 of a physical inch, because that's the unit that type designers are targeting.

I'm not enthused about redefining opsz as having a px unit scale, because I suspect from what I have read here that everything that has been said about pt is also true for px: it isn't an absolute measurement, there are different kinds of px, there are different sizes of px, there are different numbers of px in different kinds of points, inches, etc..

The issue here isn't just of consistency in implementation — of getting the same opsz instance for the same nominal type size in different platforms —, but getting the opsz instance that the type designer has created for an actual size. Otherwise there's no point in calling this optical.

davelab6 commented 4 years ago

The issue here isn't just of consistency in implementation — of getting the same opsz instance for the same nominal type size in different platforms —, but getting the opsz instance that the type designer has created for an actual size. Otherwise there's no point in calling this optical.

I think that's the opposing position to the one @lorp staked out today, which boils down to that the "actual" size ship sailed a long time ago, and attempting to fix that is way out of reach for us bunch of nerds ;) And in fact, it's gone with good reason - the design ideology of CSS is device independence and easy end user overrides, and users can set their "100% zoom" to 120% or whatever and there's no way to know.

The CSS pixel isn't a physical unit, but it's the anchor for all other CSS units, including CSS points, so it's the best unit for the web.

I think if the MS opsz definition had said the opsz values are CSS px units, this issue's proposal would still exist.

So! Fixing the OT Spec is urgent, because more and more opsz fonts are becoming widely available, and the entrenchment of the problem is only going to get worse.

And today I experienced exactly that falling feeling on this topic, as I read that Apple San Francisco is finally available as an opsz VF:

https://web.dev/more-variable-font-options-in-chromium-83/

I was surprised to see that there are just 2 masters, not set up with a continuous range, as in Amstelvar or Roboto Flex, but as a step function at a break point, like Sitka. However, this offers the "Compress" benefit with backwards compatibility to the pre VF fonts, so fair enough.

All of Amstelvar, Roboto Flex, and San Francisco are using the GRAD axis tag, but SF is using a completely different set of min/default/max range or scale values. As a "custom" axis outside of the 5 in the OT spec, this is from one point of view fine, but given the extensive documentation about why @dberlow has GRAD the way it is in the former 2 fonts, it seems to me like it might be a missed opportunity to build momentum towards seeing a Grade axis be included in the OT spec.

I'm perfectly happy to advocate for all opsz fonts to include a OPPT axis, but this risks the same kind of calamity as we now see with GRAD.

I hope we can come into consensus on how to resolve this issue :)

davelab6 commented 4 years ago

The issue here isn't just of consistency in implementation — of getting the same opsz instance for the same nominal type size in different platforms —, but getting the opsz instance that the type designer has created for an actual size. Otherwise there's no point in calling this optical.

Oh wow, I am amazed to see @robmck-ms actually NAILED this back in December 2016 in #807:

One could also look at using physical, rendered size on screen, but that too has many problems. ... In the end, the approach we found worked best was that optical style was a function of the text size within the document. E.g. If the user selected 10pt type in Word or in CSS, then that is used to select the optical size, regardless of how big the letters end up in the real world. I.e. Pinch-zoom and other zoom actions (accessibility, ctrl-+, etc) happen after style selection. ... So, for HTML/CSS, I'd propose the value of the font-size parameter, converted to points, would be used for optical style selection.

And I see @litherum agreeing at that time with this, and me and @dberlow warning about this 4/3 issue. And here we are.

tiroj commented 4 years ago

I think that's the opposing position to the one @Lorp staked out today, which boils down to that the "actual" size ship sailed a long time ago, and attempting to fix that is way out of reach for us bunch of nerds

I don't think it's an opposing position. I agree with Laurence that the relationship between physical size, nominal size, and applied size in our digital environments is basically uncertain. I'm saying that type design can't address uncertainty, so if you want optically tuned design for different sizes of type, you need to start from an absolute physical unit, even if where you go from there in implementation of type sizing is relative and flexible. Then it becomes a job for text display to figure out the best conversion from the size of text actually displayed, in the circumstances in which it is displayed*, to the physical scale of the design axis to select an appropriate optically sized instance.

*Which might be e.g. on an electronic sign where the nominal size of type is huge, but is viewed from a long distance.

davelab6 commented 4 years ago

I think that's the opposing position to the one @Lorp staked out today, which boils down to that the "actual" size ship sailed a long time ago, and attempting to fix that is way out of reach for us bunch of nerds

I don't think it's an opposing position. I agree with Laurence that the relationship between physical size, nominal size, and applied size in our digital environments is basically uncertain.

Okay good :)

I'm saying that type design can't address uncertainty, so if you want optically tuned design for different sizes of type, you need to start from an absolute physical unit, even if where you go from there in implementation of type sizing is relative and flexible.

What's wrong with using CSS px (aka Device Independent Pixels, dips) as that unit?

1 CSS px = 1/96th of 1in, more or less, but that's as good as it gets.

1 CSS pt = 1/72 of 1in, more or less, but that's as good as it gets.

Now browsers are entrenched with mapping opsz values to the former.

That's the fact. It isn't going to change

The ot spec needs to be updated to match this reality.

Non dips systems need to convert opsz values to pt; they don't exist yet and aren't entrenched.

tiroj commented 4 years ago

What's wrong with using CSS px (aka Device Independent Pixels, dips) as that unit? 1 CSS px = 1/96th of 1in, more or less, but that's as good as it gets.

According to what Miles wrote above, 1 CSS px does not equal 1 inch. Rather, 1 CSS inch = 96 px, and px ‘are not defined to have any physical length’. So from my perspective that is not as good as it gets, because a typographic point that is 1/72 of a standard physical inch is an absolute size that type designers can target. If the conversion from that to CSS or other non-physical units is approximate and sometimes lossy, that's something I recognise is beyond my control as a type designer. But please don't push that uncertainty down to the foundation level where we're trying to make fine optical size adjustments for text sizes.

VivaRado commented 4 years ago

I like whats happening here, sounds important ) almost damn scientific )

davelab6 commented 4 years ago

1 CSS inch = 96 px, and px ‘are not defined to have any physical length’

If opsz is a CSS px unit, because we know that rasterization of a 1000 UPM grid space to a 12 dips-px grid space means a set of constraints that are different to rasterizing it to a 16 dips-px grid.

Why can't type designers target that?

For the purposes of type design, this works fine!

tiroj commented 4 years ago

Rasterisation is a whole other topic. I'm talking about glyph outline design for specific optical sizes, which has to target an ideal physical size. Targeting outlines to specific ppem sizes is a different task—what we used to do with hinting. For this discussion, I'd like to leave rasterisation out of it, not least because the pixels involved in ppem raster sizes are real pixels, not CSS pixels.

In this thread, it is clearly stated that CSS px 'are not defined to have any physical length', and that relationship of a CSS inch to a physical inch is, hence, variable. Unless you can demonstrate that this is not the case—that CSS pixels are an absolute physical measurement—there is no point proposing them as a unit for optical size design, because it isn't possible to make size-specific design adjustments if they may be displayed up to ±33% different size in different places. That's the difference between 9pt and 12pt, which is precisely the range of optical size where very significant design variation occurs.

It seems to me, the best one could do in redefining the opsz scale to use 'px' as a unit would be to apply a special definition of that unit as being 1/96 of a physical inch, which I suppose would address what some browsers are doing now while still providing type designers with an absolute size target. But that would have to be very clearly stated in the spec, and would mean that some environments should really be differentiating their internal CSS px sizes from the px size used in the opsz scale if the former were different from a physical inch.

dberlow commented 4 years ago

Then if that’s the best it can be done, that an actual inch is 96 device pixels, I agree.

davelab6 commented 4 years ago

Rasterisation is a whole other topic.

Sure, in the details. Perhaps I should say 'quantization' rather than 'rasterization' as the point is that the glyph outline design (what I just called the '1000 UPM grid') is resolved to a 'css px' grid, that has a varying "resolution", and that grid, not a physical size, is what MUST be targeted - because the actual physical size has been abstracted away, along with ppem raster sizes and real pixels.

And hey, I am not "proposing" CSS px as a unit for optical size design, I am stating the fact that it is now already that unit, and this is unlikely to ever change.

The opsz scale HAS ALREADY been redefined to use 'px' as a unit.

There is a difference between 9pt and 12pt, but it is constant; and on the same computer running macOS or running Windows 10x, there is the very same difference between the macOS 9px and the Windows 9px. But the macOS is the "oddity," and the general assumption is that there are 96 dips to a physical inch.

Therefore, the point of the font-optical-sizing: FLOAT proposal is to allow CSS authors to account for that difference between 9px's, for the "oddity" casesl and to allow environments to differentiate their internal CSS px sizes from the px size used in the opsz scale, by documenting the font-optical-sizing ratio defined in the user agent stylesheet for font-optical-sizing: auto;.