Open alexandrebuffet opened 11 months ago
I just ran into this issue and wanted to add an additional use case that is currently impossible with the way theme.json
outputs @font-face
declarations (currently on WP 6.6): overriding specific glyphs in a font.
On a current project, the designer selected a font designed first for Japanese that includes latin characters as well. In Japanese, the ellipsis character ("…", code point U+2026) is vertically centered, which looks wrong in English. The generally accepted solution for this issue is to create a subsetted font file that only contains the ellipsis character. You then declare the subsetted font as the first font in font-family
and "fall back" to the font used for displaying all other characters. This works because browsers can follow the declared order of fonts in font-family
per glyph/character.
This technique can also be used when wanting to declare different fonts for different languages in a single font-family
declaration.
Here's a slightly simplified version of what I had.
theme.json
:
{
"$schema": "https://schemas.wp.org/wp/6.6/theme.json",
"version": 3,
"settings": {
"typography": {
"fontFamilies": [
{
"name": "DesignerFont",
"slug": "headings",
"fontFamily": "CustomEllipsisFont, DesignerFont, serif",
"fontFace": [
{
"fontFamily": "DesignerFont",
"src": [
"file:./assets/fonts/DesignerFont.woff2"
]
}
]
}
]
}
}
}
Custom CSS:
/* this font only has the "…" character in it */
@font-face {
font-family: "CustomEllipsisFont";
src: url("../fonts/custom-ellipsis-font.woff2") format("woff2");
unicode-range: U+2026;
}
I declared my font in theme.json
and was spinning in circles for an hour before I realized that the rendered output for font-family
is NOT the value of settings.typography.fontFamilies.fontFace.fontFamily
but instead the first value of settings.typography.fontFamilies.fontFamily
.
Output CSS:
@font-face {
font-family: CustomEllipsisFont;
src: url("https://my-site.local/wp-content/themes/my-theme/assets/fonts/DesignerFont.woff2")
format("woff2");
}
Note the mismatch between the intended font file and the font-family name.
My solution was to leave theme.json
alone (removing "CustomEllipsisFont" from the font-family
declaration) then redeclare the font-family
's custom property with the custom font added:
body {
--wp--preset--font-family--headings: "EllipsisFont, DesignerFont, serif";
}
I don't know what the best solution is as I certainly haven't thought about this as deeply as @hellofromtonya or @matiasbenedetto. All I know is that the current setup prevents overriding custom glyphs in a font defined in theme.json
without a workaround.
I can confirm the issue as I've also experienced it today. It is really confusing and debugging took me a while.
The confusing part also is that according to theme.json
schema the settings.typography.fontFamilies.fontFace.fontFamily
is required property although it is being ignored by WordPress when producing @font-face
CSS code.
The issue seems to be caused by the code in WP_Font_Face_Resolver::parse_settings()
. So, I'm not sure whether this issue is Gutenberg or WordPress core related issue.
BTW, the solution is simple: just replace $definition['fontFamily']
with $definition['fontFace']['fontFamily']
in WP_Font_Face_Resolver::parse_settings()
, specifically on line 59 and 63.
I just don't know where to send the PR fixing the issue. I can't find the file with the code here in Gutenberg GH repo, so I should probably create a WordPress patch - is this correct, can anyone confirm?
As the code for this is no longer part of Gutenberg, I think this issue should be dealt at WordPress trac.
I've provided a pull request fixing the issue.
Description
This issue refers to ticket 59911 on track.
WordPress 6.4 shipped an update where the
@font-face { font-family:...
value is set to the first font found in thetypography.fontFamilies.fontFamily
prop in theme.json (see PR #54615).I understand the problem initially raised in the PR but I don't understand the point of separating the values of the preset's "fontFamily" value for use in the
@font-face
when the "fontFamily" entry in the "fontFace" is specifically designed for this.I think that @matiasbenedetto proposal in PR is much more consistent with the code that needs to be generated and, above all, makes it possible to differentiate between the preset value and the font-face value in
theme.json
.In addition to having more consistency, it would also technically reduce the need to split the values to arrive at the same result for the generation of the
@font-face
as he says in a comment further on in the discussion.Here's an example below to illustrate that the value of the "fontFamily" entry in a preset should not be used to generate the value of
@font-face
, since this value can be a CSS variable and not necessarily the name of the font to be loaded.Step-by-step reproduction instructions
@font-face
with inconsistentfont-family
Screenshots, screen recording, code snippet
For various reasons, I used to declare font families in theme.json as follows:
Before WordPress 6.4, the result of the generated
@font-face
was as follows:Since WordPress 6.4, the generated
@font-face
is as follows:Environment info
Please confirm that you have searched existing issues in the repo.
Yes
Please confirm that you have tested with all plugins deactivated except Gutenberg.
Yes