Closed LeaVerou closed 3 years ago
I added 2 comments to https://github.com/drott/csswg-drafts/commit/62cfd95a5f52604c952e4aa37be6e4d6386f88f5 asking for a note to implementors.
@drott I'm waiting for this commit to surface as a PR on conditional 4, so that I can then merge in Tab's proposal without a merge conflict
I'm waiting for this commit to surface as a PR on conditional 4, so that I can then merge in Tab's proposal without a merge conflict
Both now done.
It also might be worth saying that implementing this depends on implementing @else.
I added a pair of examples that shows how @else
is a cleaner solution for conditional @font-face
Posting what I think we should do here.
Considerations:
src
and @supports
, they should be the same.@font-face
rules combine as they cascade, fallback code needs to actually sit in its own conditional; we can't rely on later rules overwriting earlier ones.format()
micro-query syntax with nested functions that was proposed earlier was too complex.Proposal:
format()
function to take keywords after the format string. These keywords represent the various font tech features. This allows simple forking of the URL, and can ship first.@supports
to add a font-format()
function with identical syntax. This allows higher-level conditionals that can control more than just the download URL.@else
to allow fallback rules to be easily made conditional on negation of the @supports
query.<font-format> = <format-string> <ident>*
<format-string> = format type keyword registered in css-fonts or any registered MIME type keyword under the `font/` hierarchy
src: <url> format(<font-format>), ...;
@supports font-format(<font-format>) { ... }
Thanks for summarizing your remaining feedback.
- Extend the
format()
function to take keywords after the format string. These keywords represent the various font tech features. This allows simple forking of the URL, and can ship first.
That's the thing I tried to ship and received the feedback from TAG that micro-syntax is to be avoided there. Even if we flatten the grammar here to a sequence of keywords, it's still a simple grammar. The TAG's recommendation was to consider using @supports
, which we resolved on.
- Extend
@supports
to add afont-format()
function with identical syntax. This allows higher-level conditionals that can control more than just the download URL.
It was my understanding (@svgeesus and @LeaVerou 's as well, as stated in #6635 "[css-fonts] Remove [supports format()
syntax in the src: descriptor. It seems to me that that also better follows the intention of the TAG's advice on avoiding micro-syntax. Even if we reference the syntax for format() in src:
from CSS conditionals grammar, the way I interpret the TAG's feedback is not not have complex syntax in a very particular place outside @supports
.
- Add
@else
to allow fallback rules to be easily made conditional on negation of the@supports
query.
@when
and @else
were already added, per #112, https://drafts.csswg.org/css-conditional-4/#else-rule in daeb7c32425c69e63355dd2580deff41ccc4ec4c and 0a8f9f90f0095c17328dfccd9eacda77d66ba693, weren't they?
So now that we have the font-technology()
function in for @supports
, and we have @when
in the spec, it looks to me like we're in a good spot.
I also don't see any alternative font container or compression formats that strictly restrict or bring their own font features other than SFNT / OpenType and WOFF2. In other words, everything's in an OpenType container these days, optionally WOFF(2) compressed, whether it's OpenType layout, AAT, graphite, color or non color, variable or not. But we do have the flexibility of adding format keywords in the font-technology()
function as needed for alternatives if they arise.
Please note that the TAG feedback was not "You must use @supports
" but "Please exhaust the possibility of using existing mechanisms for feature support before introducing a new one" (src). The TAG does not enforce any particular design, that is not the point of a design review.
At this point, the issue has been discussed thoroughly in the CSS WG, and there are some notable practical advantages to an inline syntax. Furthermore, a list of keywords is not a microsyntax, otherwise half of CSS properties would be using microsyntaxes. The worst of all worlds is the current state of specs, with two different syntaxes for querying support for font technology, this is one we should move away from as soon as possible. Personally I think what @fantasai suggests is reasonable, assuming it's just a list of keywords and nothing else.
@fantasai with that simplification src
won't need special parsing rules, right?
I understood it was mainly a TAG recommendation / invitation to explore options. Since we arrived at a @supports
based syntax + @when
/@if
I did not see a need for a somewhat redundant solution but I agree that there is a practical advantage to the format()
syntax in src:, in particular until @when
/@if
arrives.
If a flat list of keywords is acceptable inside a format()
, and the two specs refer to the same list, no objections from my side to harmonizing the two syntaxes/keyword-lists, defining a list of keywords in CSS fonts that both spec texts refer to and renaming font-technology()
to font-format()
in CSS conditionals 4 and. I can try to prepare draft PRs.
@fantasai with that simplification src won't need special parsing rules, right?
Correct.
Agenda+ to discuss https://github.com/w3c/csswg-drafts/issues/6520#issuecomment-934811808 and discuss schedule for publication/review/shipping.
Font tech features are dependent on the font format. We do have multiple formats which are effectively interchangeable wrappers right now, and for those the wrapper format and feature tech are independent queries, but this isn't true in consideration of all font formats past and future.
That isn't really true currently, which makes it a poor fit for format
.
Agreed in the past there were
and of course we can't predict what may happen more than a few years into the future, but currently in font format terms everything is an sfnt
which could be called either TrueType or OpenType. And (also stuffed into format) there may be compression/transfer tech on top (WOFF|WOFF2|IFT) but that does not alter the font technologies available, it just compresses or subsets them.
That said I don't object to renaming font-technology()
to font-format()
if that is what works and we agree on. But it makes things less clear.
Btw if we accept @fantasai's proposal, then the format()
function would need to accept these keywords even without a format string. We don't want people to have to write things like @supports format(woff color-COLRv1)
when they really mean @supports format(color-COLRv1)
. Right now <font-format>
is mandatory.
We would also need to test what happens with
@font-face{
font-family: foo;
src: url("foo.woff") format("color-COLRv1");
}
because I suspect with an omitted actual format, the font is assumed to be an unsupported format and is not loaded. As opposed to
@font-face{
font-family: foo;
src: url("foo.woff") format("woff color-COLRv1");
}
In general the whole format()
thing is a buggy hack with huge backwards-compatible fragility; adding anything is highly constrained and we can't do good design in this space. I would be much happier with (as we originally resolved)
@font-face
src
entirelyfont-technology()
@font-format {
@svgeesus , did you mean @font-face
in those two examples?
Heh, yes. Corrected.
This issue is on the CSSWG agenda for today, and I'd like to participate, but I’m not feeling well (food poisoning?). Can we postpone it from the CSSWG agenda for 1 week?
Resolved in today's meeting to discuss in breakout right before the regular meeting time next week. @drott could you please coordinate the logistics of said breakout?
Yes, I'll send details and and invite to a Meet call to the private mailing list.
@svgeesus From your example, format("color-COLRv1") and format("woff color-COLRv1") would both fail to load because neither string is a recognized font format.
Within the comma separated list, things are supposed to be space separated. Which is why
format(opentype supports incremental)
works in a backward compat way. As you say, older browsers treat the whole thing as one unknown format that happens to contain spaces.
@fantasai's proposal in https://github.com/w3c/csswg-drafts/issues/6520#issuecomment-934811808 makes sense to me.
Regarding the question of whether or not we can avoid changing the src
descriptor, I think it comes down to how authors would implement fallback with @supports
instead. Ideally, the same fallback code should be applied in both situations: 1) you're on an old browser that doesn't understand the new @supports
syntax, and 2) You're on a new browser, but the browser doesn't actually support the font technology you're requesting. I think handling fallback for both these situations using the same code should be considered a requirement (otherwise it's too hard and authors will get it wrong).
A quick check shows that, in today's browsers (which are the first situation above),
@supports not font-format(truetype variations) {
div {
background: blue;
}
}
does not cause <div>
s to get blue
backgrounds.
On the other hand,
@supports not ( font-format(truetype variations) ) {
div {
background: blue;
}
}
does cause <div>
s to get blue
backgrounds. Maybe the solution is to change <supports-decl>
's definition from ( <declaration> )
to ( <declaration> | font-format(<font-format>) )
? I'm not sure we can actually use this, though, because I think it was an intentional choice to make the thing between the parentheses a <declaration>
.
If we can come up with a solution that satisfies these constraints, we can leave the src
descriptor alone. However, if we can't, then I think we need to add expressiveness to the src
descriptor because that's how authors would achieve correct fallback behavior.
Of course, another way to solve this problem is to wait to implement (but not necessarily spec) this fancy new @supports
nesting stuff until after @else
is implemented. That way, we would encourage authors to write code like
@supports font-format(truetype variations) {
@font-face {
/* variation font stuff */
}
} @else {
@font-face {
/* fallback stuff */
}
}
If these two features (@else
, then @font-face
nesting) were implemented in-order, we wouldn't need to modify the src
descriptor. But, if they were implemented in reverse order, that would be bad unless we come up with some way of solving the problem described above (above the -----------).
@litherum My understanding of the @supports
grammar is that any negated condition needs to be in parens. If that's correct, that would explain why your first rule didn't work: because it's invalid syntax. Perhaps @tabatkins could confirm.
I tend to agree with @LeaVerou here, with
<supports-condition> = not <supports-in-parens>
<supports-in-parens> = ( <supports-condition> ) …
(https://drafts.csswg.org/css-conditional-3/#at-supports)
only the second part of your example is valid syntax.
@supports not ( font-format(truetype variations) ) {
div {
background: blue;
}
}
I am assuming the intent in your examples is to get blue background, or in other words: "use this block for fallback" is the intention.
It seems to me we we can conclude this syntax (with condition in parentheses) would fulfil your expectation of code a) working in old browsers without font-technology
/font-format
support, as well as b) in browsers that do understand the condition function.
The CSS Working Group just discussed fonts, continued (beginning of log missing)
, and agreed to the following:
RESOLVED: Modify src to allow for font-tech detection per URL
RESOLVED: Same syntax available in src, will be available also in @supports, possibly with a font- prefix
RESOLVED: remove "supports <font-technology>#"
RESOLVED: add technology() and open bikeshedding issue
RESOLVED: Add font-technology() and font-format() to @supports
Full minutes posted here: https://www.w3.org/2021/10/20-css-minutes.html
Since this issue thread is really long and pulls in a lot of related topics, please consider opening new focused issues based on the resolutions above and/or the spec edits that will be made soon. For instance, if we need to bikeshed the technology()
term it would be better to have a new issue just for that. Or if the keywords edited in for the new function need changes, that would be excellent as a separate issue.
Edits made to CSS Conditional 4, CSS Fonts 4, and CSS Fonts 5.
Extensions to the @supports rule Parsing the src descriptor (4) and Parsing the src descriptor (5) Font formats Font technologies
I thought we could get rid of the parsing weirdness around src
now?
I thought we could get rid of the parsing weirdness around src now?
We got rid of the weirdness around format supports whatever
. We still have a descriptor wchich is a comma-separated list of items, where each item is a url()
followed by an optional format()
and an optional technology()
so we still need to describe how to work out the winning item.
This is related to #633 and this part of css-fonts-4: https://drafts.csswg.org/css-fonts-4/#font-face-src-parsing
A bit late to the party, but I wondered: what if, instead of adding yet another microsyntax for feature detection, we use
@supports
with an appropriatefont-technology()
function (or whatever we want to name it)?We recently resolved to allow nesting of conditional rules inside regular rules, so that authors can do things like:
What if this was allowed in
@font-face
as well? That way, authors could do something like:or
instead of:
Benefits:
src
that this microsyntax has introducedCSS.supports()
API (current syntax also allows programmatic detectability but in a much clunkier wayformat()
is a list of keywords, with no hierarchy. Also, the syntax makes it unclear whether this is a feature query for the browser, or informing the browser what the font file supports.Downsides:
Unlike conditional rules in general, feature queries do not change during the lifetime of the page load, and thus this should not trigger re-interpretation of the
@font-face
rule or be more heavyweight in any other substantial way.If such syntax is used with today's browsers, they drop the
@supports
rule but keep the@font-face
rule, so it does appear forwards compatible. testcaseThere are no implementations of the current syntax, so it may not be too late for the change.
Thoughts, @svgeesus @litherum @fantasai @tabatkins?