Skip to content
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] Clarify parsing of <font-face-name> for the src: local(...) function #8187

Closed
jfkthame opened this issue Dec 5, 2022 · 8 comments
Assignees
Labels

Comments

@jfkthame
Copy link
Contributor

jfkthame commented Dec 5, 2022

The src descriptor of an @font-face rule has a comma-separated list of component values.

One type of component value is a local font specified using the local() function. The <font-face-name> argument to local() is:

a unique font face name enclosed by "local(" and ")". The name can optionally be enclosed in quotes. If unquoted, the unquoted font family name processing conventions apply; the name must be a sequence of identifiers separated by whitespace which is converted to a string by joining the identifiers together separated by a single space.

Here, I presume "the unquoted font family name processing conventions" must be referring -- although not linked in the spec -- to the more detailed description of the <family-name> syntax found in the context of the font-family property.

The "unquoted font family name processing conventions" mentioned in the <font-face-name> description clearly refer to the construction of a single string name from a sequence of space-separated identifiers, as for example local(Times New Roman Bold), to identify the same face as local("Times New Roman Bold").

What's less clear to me is whether these "processing conventions" also encompass the restriction that:

Font family names that happen to be the same as a font-family keyword value (e.g. CSS-wide keywords such as inherit, or keywords such as serif) must be quoted to prevent confusion with the keywords of the same names.

In the context of the <font-face-name> argument to local() in an @font-face rule, it would not be meaningful to use a CSS generic-family (because the argument is not a font family at all, it's an individual font face), and so arguably there is no risk of confusion; a component like local(serif) must unambiguously refer to a font face whose actual name is "serif", and not to the (potentially composite and/or language-dependent) font family to which the property font-family: serif would refer.

Still, I think it is unhelpful to permit unquoted generic-family identifiers here; users have enough difficulty with the family/face distinction already. And perhaps the mention of the "family name processing conventions" should be taken to include the rule excluding such keywords.

So in short, my question -- which I do not think the spec clearly addresses -- can be boiled down to whether the rule:

    @font-face { font-family: foo; src: local("serif"); }

can equivalently (although confusingly) be written as:

    @font-face { font-family: foo; src: local(serif); }

or is the latter a parse error, resulting in a rule that lacks any valid source?

Currently, it appears that WebKit and Blink both accept the unquoted generic-family here, while Gecko does not. However, I would suggest that Gecko's behavior is preferable, and should be explicitly spec'd. In the (unlikely) event that a user really does want to refer to a local font face literally named "serif" (for example), they can do this using a quoted string. Accepting the unquoted identifier misleads users into conflating font faces and font families.

cc @svgeesus @drott @litherum

@litherum
Copy link
Contributor

litherum commented Dec 5, 2022

Wouldn't it be useful to be able to say something like

@font-face {
font-family: trimmed-system-font;
src: local(system-ui);
font-weight: 500 900;
unicode-range: U+0041;
}

(Perhaps as a member of a larger trimmed-system-font family?)

@jfkthame
Copy link
Contributor Author

jfkthame commented Dec 5, 2022

It might be, but that shouldn't be a @font-face rule as it's not attempting to define a face by reference to a specific resource; it's defining a family as a modification of another (potentially abstract/composite) family.

(I seem to remember bringing up such a suggestion some years ago, actually, but it didn't get any traction....)

@jfkthame
Copy link
Contributor Author

jfkthame commented Dec 5, 2022

So that would be better expressed as something like

@font-family {
    font-family: trimmed-system-font;
    base-family: system-ui;
    ...etc...
}

@cdoublev
Copy link
Collaborator

cdoublev commented Jan 9, 2023

I would be interested in having a basic syntax definition of <font-face-name> and <family-name>. I think the latter expands to <string> | <custom-ident>+ but if local(serif) must be invalid, it would be clearer to define src with ... | local(<family-name>) instead of ... | local(<font-face-name>).

@yisibl
Copy link
Contributor

yisibl commented Jan 12, 2023

WebKit/WebKit#8396 font-face src local() doesn't invalidate css-wide keywords

@cdoublev
Copy link
Collaborator

Thanks for the change Chris. Do you think this can be applied to CSS Fonts 5 as well?

w3c/reffy does not extract the line where local() appears because it is not a production rule, ie. <symbol> = value. If the value definition field of src was defined with this line (#7632), w3c/reffy would take the version from CSS Fonts 5 instead of CSS Fonts 4.

@svgeesus svgeesus self-assigned this Apr 27, 2023
cdoublev added a commit to cdoublev/csswg-drafts that referenced this issue Sep 4, 2023
cdoublev added a commit to cdoublev/csswg-drafts that referenced this issue Sep 4, 2023
@svgeesus
Copy link
Contributor

svgeesus commented Dec 5, 2023

I added

and thus,
<a>CSS-wide keywords</a> such as ''inherit'', and
<<generic-family>> keywords such as ''serif''
are not allowed inside <code>local()</code>.

and

<div class="invalid example">
For example, this use of <code>local()</code> would be an error:

	<pre class="lang-css">
		@font-face { 
			font-family: foo; 
			src: local(inherit);
		}
	</pre>
</div>

@svgeesus
Copy link
Contributor

Closed by 75e8082

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants