vercel / next.js

The React Framework
https://nextjs.org
MIT License
122.96k stars 26.27k forks source link

Clarification Needed: Using `axes` Property with Variable Fonts in `next/font/google` #64960

Open BaileySimrell opened 2 months ago

BaileySimrell commented 2 months ago

What is the improvement or update you wish to see?

The current documentation for next/font/google lacks examples or explanations on how to utilize the axes property with variable fonts. Specifically, it is not clear how to set values for font variation axes such as width ('wdth'). A clear example and explanation in the documentation would be beneficial.

Is there any context that might help us understand?

In the type definition for Bricolage_Grotesque, there is an axes property that suggests the ability to control font variation axes. However, there are no details on how to specify the values for these axes. For developers looking to optimize font loading with specific variable font settings, this information is crucial.

Does the docs page already exist? Please link to it.

https://nextjs.org/docs/basic-features/font-optimization

Where I'm currently at

I'm working on integrating the Bricolage_Grotesque variable font into my Next.js application using next/font/google. However, I'm having trouble understanding how to set specific values for the font's axes, such as width ('wdth'). The type definitions seem to indicate that axes is an array, but there's no clear way to assign values to each axis.

Additional information

// This does not specify a value for 'wdth'
export const bricolage = Bricolage_Grotesque({
  subsets: ['latin'],
  axes: ['wdth']
});

// Expected usage (or similar), which does not work:
export const bricolage = Bricolage_Grotesque({
  subsets: ['latin'],
  axes: {
    'wdth': 80.7
  }
});

The following will compile, but I don't know how to change the actual width value:

Screenshot 2024-04-24 at 4 25 41 AM

Things I tried that didn't work:

Screenshot 2024-04-24 at 3 55 44 AM Screenshot 2024-04-24 at 4 04 03 AM Screenshot 2024-04-24 at 4 03 57 AM Screenshot 2024-04-24 at 3 58 53 AM Screenshot 2024-04-24 at 3 55 51 AM

Another random thing I tried:

I also tried seeing if the wdth axes value would be configurable on the exported object, but that didn't work or lead me to anything... Based on the type definition of Bricolage_Grotesque, I am pretty confused on this one tbh.

Screenshot 2024-04-24 at 4 10 23 AM
BaileySimrell commented 2 months ago

Ported this this from Discussion 64959

DeJayDev commented 2 months ago

I've stumbled upon this with the font Sono, it appears next/font makes the assumption that axes are all or nothing?

Sono is a little special in that it's MONO defaults to 1, so this font's default state in the current implementation of axes is a Monospaced font. Obviously, makes using Sono as a proportional font impossible - next/font gives us no control of the axes values. In this case, we get monospacing by defining axes: ["MONO"] explicitly, or we can not define it and still get a monospaced font.

It seems that controlling this value is actually entirely impossible, and maybe that's cause for another issue?

Everything below is informational (my workaround), and is unrelated to the issue requesting more documentation.


To have actual control of the MONO value, I decided to get creative. But this should apply to any axes field or font variation.

We'll first need to explicitly ask Google Fonts for the version of this font that has a MONO defined.

const sono = Sono({
  weight: "variable",
  subsets: ["latin"],
  variable: "--font-sono",
  axes: ["MONO"]
});

image

Then, using Tailwind we can override this value.

theme: {
    extend: {
      fontFamily: {
        heading: [
          'var(--font-sono)',
          {
            fontVariationSettings: '"MONO" 0'
          }
        ]
      }
    }
}    

Another one of those with "MONO" 1 (and a different variable name!) finally gives us control:

image

If I chose not to use Tailwind here this would be much harder (impossible?) but hopefully anyone with this issue who stumbles upon this comment finds a solution in the meantime.

BaileySimrell commented 1 month ago

I've stumbled upon this with the font Sono, it appears next/font makes the assumption that axes are all or nothing?

Sono is a little special in that it's MONO defaults to 1, so this font's default state in the current implementation of axes is a Monospaced font. Obviously, makes using Sono as a proportional font impossible - next/font gives us no control of the axes values. In this case, we get monospacing by defining axes: ["MONO"] explicitly, or we can not define it and still get a monospaced font.

It seems that controlling this value is actually entirely impossible, and maybe that's cause for another issue?

Everything below is informational (my workaround), and is unrelated to the issue requesting more documentation.

To have actual control of the MONO value, I decided to get creative. But this should apply to any axes field or font variation.

We'll first need to explicitly ask Google Fonts for the version of this font that has a MONO defined.

const sono = Sono({
  weight: "variable",
  subsets: ["latin"],
  variable: "--font-sono",
  axes: ["MONO"]
});

image

Then, using Tailwind we can override this value.

theme: {
    extend: {
      fontFamily: {
        heading: [
          'var(--font-sono)',
          {
            fontVariationSettings: '"MONO" 0'
          }
        ]
      }
    }
}    

Another one of those with "MONO" 1 (and a different variable name!) finally gives us control:

image

If I chose not to use Tailwind here this would be much harder (impossible?) but hopefully anyone with this issue who stumbles upon this comment finds a solution in the meantime.

Thanks for sharing this workaround man