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

Parse font faces and consider font weight #53

Open
kilobyte2007 opened this issue Dec 1, 2022 · 10 comments
Open

Parse font faces and consider font weight #53

kilobyte2007 opened this issue Dec 1, 2022 · 10 comments
Assignees
Labels
enhancement New feature or request

Comments

@kilobyte2007
Copy link

🆒 Your use case

Sometimes we have this setup:

@font-face {
    font-family: 'Biennale';
    font-weight: 400;
    font-style: normal;
    font-display: swap;
    src: url('~/assets/fonts/Biennale-Book.woff2') format('woff2'),
    url('~/assets/fonts/Biennale-Book.woff') format('woff');
}

@font-face {
    font-family: 'Biennale';
    font-weight: 500;
    font-display: swap;
    src: url('~/assets/fonts/Biennale-Medium.woff2') format('woff2'),
    url('~/assets/fonts/Biennale-Medium.woff') format('woff');
}

When fontaine is parsing the font-face it creates the override/fallback font-face without accounting for the weight.

@font-face {
  font-family: "Biennale override";
  src: local("BlinkMacSystemFont"),local("Segoe UI"),local("Roboto"),local("Helvetica Neue"),local("Arial"),local("Noto Sans");
  ascent-override: 94.4%;
  descent-override: 24.5%;
  line-gap-override: 0%;
}
@font-face {
    font-family: 'Biennale';
    font-weight: 400;
    font-style: normal;
    font-display: swap;
    src: url('/_nuxt/assets/fonts/Biennale-Book.woff2') format('woff2'),
    url('/_nuxt/assets/fonts/Biennale-Book.woff') format('woff');
}
@font-face {
  font-family: "Biennale override";
  src: local("BlinkMacSystemFont"),local("Segoe UI"),local("Roboto"),local("Helvetica Neue"),local("Arial"),local("Noto Sans");
  ascent-override: 96.7%;
  descent-override: 26.5%;
  line-gap-override: 0%;
}
@font-face {
    font-family: 'Biennale';
    font-weight: 500;
    font-display: swap;
    src: url('/_nuxt/assets/fonts/Biennale-Medium.woff2') format('woff2'),
    url('/_nuxt/assets/fonts/Biennale-Medium.woff') format('woff');
}

🆕 The solution you'd like

We should probably add weight parsing, we should just probably parse it with regexp and add it on the created weight/override.

Expected result would be:

@font-face {
    font-family: "Biennale override";
    font-weight: 400;
    font-style: normal;
    src: local("BlinkMacSystemFont"),local("Segoe UI"),local("Roboto"),local("Helvetica Neue"),local("Arial"),local("Noto Sans");
    ascent-override: 94.4%;
    descent-override: 24.5%;
    line-gap-override: 0%;
}
@font-face {
    font-family: 'Biennale';
    font-weight: 400;
    font-style: normal;
    font-display: swap;
    src: url('/_nuxt/assets/fonts/Biennale-Book.woff2') format('woff2'),
    url('/_nuxt/assets/fonts/Biennale-Book.woff') format('woff');
}
@font-face {
    font-family: "Biennale override";
    font-weight: 500;
    font-display: swap;
    src: local("BlinkMacSystemFont"),local("Segoe UI"),local("Roboto"),local("Helvetica Neue"),local("Arial"),local("Noto Sans");
    ascent-override: 96.7%;
    descent-override: 26.5%;
    line-gap-override: 0%;
}
@font-face {
    font-family: 'Biennale';
    font-weight: 500;
    font-display: swap;
    src: url('/_nuxt/assets/fonts/Biennale-Medium.woff2') format('woff2'),
    url('/_nuxt/assets/fonts/Biennale-Medium.woff') format('woff');
}

🔍 Alternatives you've considered

No response

ℹ️ Additional info

No response

@kilobyte2007 kilobyte2007 added the enhancement New feature or request label Dec 1, 2022
@kilobyte2007 kilobyte2007 changed the title Parse font faces with weights Parse font faces and consider font weight Dec 1, 2022
@lewisakura
Copy link

Encountered this myself, funnily enough. Using Inter with weights 400/700, but Fontaine doesn't have a weight specifier so whilst it works for the body content, there are still significant layout shifts for headers.

@kilobyte2007
Copy link
Author

I've actually played with it and made it work locally, so can make a PR. @danielroe what do you think about this?

@danielroe
Copy link
Member

@kilobyte2007 Would love that!

@sermagnus
Copy link

+1

@kilobyte2007
Copy link
Author

@sermagnus there is an open PR #264 and it works but it seems like it won't work like we expected it to work because capsize doesn't provide the metrics needed here.

@DamianGlowala
Copy link

@kilobyte2007, what do you think of tweaking a PR in a way which would allow adding missing metrics on our own? I would love to be able to do that. It's certainly an extra effort without capsize providing these for us, but it has to be done only once :)

@michaeltaranto
Copy link
Contributor

Capsize is about to land support for character subsets other than basic Latin, e.g. Thai. The previous xWidthAvg metric was a weighted average based solely on character frequencies in English.

This overhaul is enabling us to expose metrics for different character sets, e.g.:

import lobster from '@capsizecss/metrics/lobster'; // Same as today, latin regular
import { latin as lobsterLatin } from '@capsizecss/metrics/lobster'; // Same as today, latin regular
import { thai as lobsterThai } from '@capsizecss/metrics/lobster'; // New, thai regular

Once this is done, we planned to look at modelling variants, following Google Fonts variants data structure, e.g.:

export const latin = {
  familyName: 'ABeeZee',
  category: 'sans-serif',
  capHeight: 700,
  ascent: 920,
  descent: -262,
  lineGap: 0,
  unitsPerEm: 1000,
  xHeight: 520,
  xWidthAvg: 517, // latin regular (backwards compat)
  xWidthAvgByVariant: {
    "regular": 517,
    "700": 537,
    "italic": 527,
    "700italic": 547,
  }
}

Still not settled on the naming (xWidthAvgByVariant) so will bike shed it, but this allows cutting the metrics by unicode subset and font variants.

The intention is that the lookup would be opaque, so when passing additional declaration properties, Capsize would use the correct metric when generating the fallback:

const { fontFamily, fontFaces } = createFontStack(
  [ lobster, arial ],
  {
    fontFaceProperties: {
      fontWeight: 700,
      fontStyle: 'italic'
    }
  }
);

Hope that adds some clarity to our direction.

@danielroe
Copy link
Member

@michaeltaranto We would prefer to have access to the underlying metrics rather than using the createFontStack API, which allows us more flexibility for the declarations we generate. Would that be possible?

@michaeltaranto
Copy link
Contributor

@danielroe Yeah they would be available on the metrics to lookup, as mentioned there's bike shedding to happening.

I have been wanting to come back to Capsize 🤝 Fontaine, as I think you may be able to use the createFontStack API to simplify things on your end a bit.

@danielroe
Copy link
Member

That would be amazing!

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

No branches or pull requests

6 participants