实验性字体 API
类型: FontFamily[]
astro@5.7.0
新
此实验性功能允许你通过统一、完全可定制且类型安全的 API,来使用这些来源的字体:本地文件系统,字体提供商(例如:Google、Fontsource、Bunny)。
网络字体会影响网页在加载时间和渲染时的性能。此 API 将通过自动化的 网页字体优化,包括预加载、自定义回退内容和强约定的默认配置来帮助你维持网站的高性能表现,同时规避常见问题,如下载不必要的字体文件。
要启用该功能,请在 experimental.fonts
对象中,配置至少一个字体:
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ experimental: { fonts: [{ provider: fontProviders.google(), name: "Roboto", cssVariable: "--font-roboto" }] }});
接着,在 <head>
部分,添加 <Font />
组件并运用于全站样式:
---import { Font } from 'astro:assets';---
<Font cssVariable='--font-roboto' preload />
<style>body { font-family: var(--font-roboto);}</style>
使用方法
段落标题 使用方法-
experimental.fonts
接受以数组类型传入字体对象。每个字体,必须指定provider
(提供商)、name
(字体名称)并定义cssVaruable
来指向所使用的字体。provider
:你可以从 内置的远程提供商 列表中挑选,构建你个人的 自定义字体提供商,或是使用 本地提供商 来注册本地字体文件。name
:选择一个提供商所支持的字体。cssVariable
:必须是一个有效的、以 CSS 变量形式的 ident(标识符)。
下面示例配置了 Google Fonts 中的 “Roboto” 字体:
astro.config.mjs import { defineConfig, fontProviders } from "astro/config";export default defineConfig({experimental: {fonts: [{provider: fontProviders.google(),name: "Roboto",cssVariable: "--font-roboto"}]}});更多可用的配置选项,例如定义 回退字体 和 下载哪种
weights
以及styles
,将会基于你所选定的提供商有所不同。查看完整的 配置参考,以了解更多。
-
使用
<Font />
组件来应用样式。该组件必须引入并添加到你页面的<head>
部分。你需要提供字体的cssVariable
,也可以选择性的 输出预加载链接:src/components/Head.astro ---import { Font } from 'astro:assets';---<Font cssVariable="--font-roboto" preload />这通常在组件中完成,而这些组件又嵌套在通用页面布局中,例如
Head.astro
。查看完整的<Font>
组件参考,以获取更多信息。因为
<Font />
组件会生成带有字体声明的 CSS,因此你可以使用cssVariable
来引用该字体:<style>body {font-family: var(--font-roboto);}</style>src/styles/global.css @import 'tailwindcss';@theme inline {--font-sans: var(--font-roboto);}tailwind.config.mjs /** @type {import("tailwindcss").Config} */export default {content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],theme: {extend: {},fontFamily: {sans: ["var(--font-roboto)"]}},plugins: []};
可用的远程字体提供商
段落标题 可用的远程字体提供商Astro 重新导出了大部分 unifont 的字体提供商模块。以下为内置支持的提供商:
要使用内置的远程提供商,请为你所选定的字体提供商选择合适的值,来配置 provider
:
provider: fontProviders.adobe({ id: process.env.ADOBE_ID })
provider: fontProviders.bunny()
provider: fontProviders.fontshare()
provider: fontProviders.fontsource()
provider: fontProviders.google()
另外,google()
字体提供商接受 unifont Google ProviderOption
的所有可用选项:
provider: fontProviders.google({ glyphs: { Roboto: ["a"] }})
你也可以使用任意的 unifont 提供商 创建自定义 Astro 字体提供商。
<Font />
组件参考
段落标题 <Font /> 组件参考该组件输出样式标签,并且能够选择性的为给定字体输出预加载链接。
该组件必须导入并添加到你页面的 <head>
部分。这通常在组件中完成,而这些组件又嵌套在例如 Head.astro
这样的通用页面布局中,从而可以全局使用,但如有需要,它也能被导入到单个页面来使用。
利用该组件,你可以控制哪些字体被运用在哪些页面,以及哪些字体需要预加载。
cssVariable
段落标题 cssVariable示例类型: "--font-roboto" | "--font-comic-sans" | ...
在 Astro 配置中注册的 cssVariable
:
---import { Font } from 'astro:assets';---
<Font cssVariable="--font-roboto" />
preload
段落标题 preload类型: boolean
默认值: false
是否输出 预加载链接:
---import { Font } from 'astro:assets';---
<Font cssVariable="--font-roboto" preload />
字体配置参考
段落标题 字体配置参考所有的字体属性都必须在 Astro 配置文件中进行配置。有些属性对于远程和本地字体来说是通用的,而其他属性则根据你选择的字体提供商提供。
通用属性
段落标题 通用属性下列属性对于远程和本地字体来说均可用。provider
、name
和 cssVariable
是必要属性。
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ experimental: { fonts: [{ provider: fontProviders.google(), name: "Roboto", cssVariable: "--font-roboto" }] }});
provider
段落标题 provider类型: AstroFontProvider | "local"
字体文件的来源。你可以使用 内置提供商 来编写你自己的 自定义提供商,或者是通过将该项设置为 "local"
来使用本地字体文件:
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ experimental: { fonts: [{ provider: fontProviders.google(), name: "Roboto", cssVariable: "--font-roboto" }] }});
name
段落标题 name类型: string
字体名称,由字体提供商所确定:
name: "Roboto"
cssVariable
段落标题 cssVariable类型: string
一个有效的、由你选定的、以 CSS 变量形式的 ident(例如:通常以 --
开头):
cssVariable: "--font-roboto"
fallbacks
段落标题 fallbacks类型: string[]
默认值: ["sans-serif"]
一个包含字体的数组,用以在选定字体不可用时进行加载。回退字体将会按照列表顺序被选用。第一个可用的字体将会被使用:
fallbacks: ["CustomFont", "serif"]
要彻底禁用回退字体,可配置一个空数组:
fallbacks: []
如果 fallbacks
数组中最后的一个字体是 通用字体族名,Astro 将会尝试使用字体度量(font metrics)来生成 优化后的字体回退。要禁用这种优化过程,可将 optimizedFallbacks
设置为 false。
optimizedFallbacks
段落标题 optimizedFallbacks类型: boolean
默认值: true
当生成回退字体时,是否启用 Astro 默认的优化过程。你可以禁用该默认的优化过程,以实现对 fallbacks
生成过程的完全掌控:
optimizedFallbacks: false
远程字体属性
段落标题 远程字体属性远程字体可使用进一步配置选项来进行配置。通过设置这些选项来自定义这些由 字体提供商 所加载的数据,例如仅下载特定的字重和字体样式。
在底层实现中,这些选项均由 unifont 处理。部分属性可能不被某些字体提供商所支持,而不同提供商对同一属性的实现方式也可能不同。
weights
段落标题 weights类型: (number | string)[]
默认值: [400]
一个包含 字重 的数组。若未在配置中指定该属性,则默认仅包含字重 400
,以避免下载未使用的字体文件。如需使用其他字重,必须显式声明此属性:
weights: [200, "400", "bold"]
如果所关联的字体为 可变字体,那么你可以指定字重的范围:
weights: ["100 900"]
styles
段落标题 styles类型: ("normal" | "italic" | "oblique")[]
默认值: ["normal", "italic"]
一个包含 字体样式 的数组:
styles: ["normal", "oblique"]
subsets
段落标题 subsets类型: string[]
默认值: ["cyrillic-ext", "cyrillic", "greek-ext", "greek", "vietnamese", "latin-ext", "latin"]
定义 字体子集,用以预加载。
subsets: ["latin"]
display
段落标题 display类型: "auto" | "block" | "swap" | "fallback" | "optional"
默认值: "swap"
定义 字体显示方式,根据字体文件下载和准备就绪的时间,控制渲染行为:
display: "block"
unicodeRange
段落标题 unicodeRange类型: string[]
默认值: undefined
该属性用于根据指定的 Unicode 字符范围 控制字体的按需下载和使用。若页面中存在字符匹配该属性的范围,那么浏览器将下载字体文件,且页面中所有字符均可使用该字体。如需为单个字体配置预装的字体子集,可参阅 subset 属性用作替代。
该属性在多语言本地化场景中尤为实用,当网站的特定部分使用其他字母时,会通过显示单独的字体来避免不必要的字体下载。例如,某网站同时提供英文和日文版本时,若当前的英文页面中不存在 unicodeRange
定义的日文字符时,浏览器将完全跳过对日文字体的下载。
unicodeRange: ["U+26"]
stretch
段落标题 stretch类型: string
默认值: undefined
字体拉伸:
stretch: "condensed"
featureSettings
段落标题 featureSettings类型: string
默认值: undefined
用以控制 字体排印特性(例如:连字,小型大写字母,或是花体字):
featureSettings: "'smcp' 2"
variationSettings
段落标题 variationSettings类型: string
默认值: undefined
字体的 可变设置:
variationSettings: "'xhgt' 0.7"
本地字体 variants
段落标题 本地字体 variants类型: LocalFontFamily["variants"]
当使用本地字体文件时,variants
属性是必要的。每个 Variant 就相当于一个 @font-face
声明,并且需要对应的 weight
、style
和 src
值。
此外,可以在每个 Variant 中指定 远程字体的某些其他属性 。
import { defineConfig } from "astro/config";
export default defineConfig({ experimental: { fonts: [{ provider: "local", name: "Custom", cssVariable: "--font-custom", variants: [ { weight: 400, style: "normal", src: ["./src/assets/fonts/custom-400.woff2"] }, { weight: 700, style: "normal", src: ["./src/assets/fonts/custom-700.woff2"] } // ... ] }] }});
weight
段落标题 weight类型: number | string
默认值: undefined
字重:
weight: 200
如果所关联的字体为 可变字体,那么你可以指定字重的范围:
weight: "100 900"
当该值未被设置时,默认情况下,Astro 将会尝试根据第一个 source
来推断该值。
style
段落标题 style类型: "normal" | "italic" | "oblique"
默认值: undefined
字体样式:
style: "normal"
当该值未被设置时,默认情况下,Astro 将会尝试根据第一个 source
来推断该值。
src
段落标题 src类型: (string | URL | { url: string | URL; tech?: string })[]
字体 来源。它可以是一条相对于根目录的相对路径,也可以来自于包的导入或是一个 URL。如果你是通过集成来注入本地字体,则 URL 特别有用:
src: ["./src/assets/fonts/MyFont.woff2", "./src/assets/fonts/MyFont.woff"]
src: [new URL("./custom.ttf", import.meta.url)]
src: ["my-package/SomeFont.ttf"]
我们不推荐将字体文件存放在 public/
目录 中。因为 Astro 会在构建时将这些文件拷贝到其中,这将会导致构建输出的结果产生重复文件。更好的做法是将其存放在项目中的其他位置,例如放置在 src/
中。
你也可以通过提供对象,来指定一个 tech:
src: [{ url:"./src/assets/fonts/MyFont.woff2", tech: "color-COLRv1" }]
其他属性
段落标题 其他属性下列来自于远程字体的可用选项,也可用于本地字体的 Variant 中:
import { defineConfig } from "astro/config";
export default defineConfig({ experimental: { fonts: [{ provider: "local", name: "Custom", cssVariable: "--font-custom", variants: [ { weight: 400, style: "normal", src: ["./src/assets/fonts/custom-400.woff2"], display: "block" } ] }] }});
创建自己的字体提供商
段落标题 创建自己的字体提供商如果你不想局限于使用任一的 内置提供商(例如:你想使用第三方 unifont 提供商,或是创建一些运用于私人仓库的内容),那么你便可以创建自己的字体提供商。
每一个 Astro 字体提供商都是由两个部分所构成:配置对象(config object)和实际实现(actual implementation)。
-
使用
defineAstroFontProvider()
类型助手函数,创建一个函数用于返回字体提供商的配置对象所含的内容:entrypoint
:可以是 URL,一个相对于根目录的相对路径,或是一个包的导入。config
:一个可选的序列化对象,它会被传入 unifont 提供商。
provider/config.ts import { defineAstroFontProvider } from 'astro/config';export function myProvider() {return defineAstroFontProvider({entrypoint: new URL('./implementation.js', import.meta.url)});};provider/config.ts import { defineAstroFontProvider } from 'astro/config';interface Config {// ...};export function myProvider(config: Config) {return defineAstroFontProvider({entrypoint: new URL('./implementation.js', import.meta.url),config});}; -
创建第二个文件,用以导入 unifont
provider
实现:implementation.ts import { defineFontProvider } from "unifont";export const provider = defineFontProvider("my-provider", async (options, ctx) => {// 获取/定义你的自定义字体// ...});你可以翻阅 unifont 提供商们的源码,从而了解如何创建一个 unifont 提供商。
-
向你的字体配置文件中,添加你自定义的提供商。
astro.config.mjs fonts: [{provider: fontProviders.myProvider(),name: "Custom Font",cssVariable: "--font-custom"}]
缓存
段落标题 缓存字体 API 的缓存实现,旨在保证开发环境的实用性和生产环境的高效率。在构建阶段,字体文件会被拷贝到 _astro/fonts
输出目录,因此他们可以从静态资源的 HTTP 缓存中受益(通常为一年时间)。
想清理开发环境中的缓存,可删除 .astro/fonts
目录。想清理构建时产生的缓存,可删除 node_modules/.astro/fonts
目录。
延伸阅读
段落标题 延伸阅读有关此实验性 API 的全部详细信息或需提供反馈,请参见 字体 RFC。
Reference