سایتهایی که فونتها را با نمایش فونت بارگیری میکنند: swap اغلب از تغییر طرح ( CLS ) رنج میبرند که فونت وب بارگیری میشود و با فونت جایگزین جایگزین میشود.
می توانید با تنظیم ابعاد فونت بازگشتی برای مطابقت با فونت اصلی از CLS جلوگیری کنید. ویژگیهایی مانند size-adjust
، ascent-override
، descent-override
و line-gap-override
در قانون @font-face
میتواند به نادیده گرفتن معیارهای یک فونت بازگشتی کمک کند و به توسعهدهندگان اجازه میدهد کنترل بیشتری بر نحوه نمایش فونتها داشته باشند. میتوانید در این پست درباره فونتهای بازگشتی و ویژگیهای لغو بیشتر بخوانید. همچنین می توانید پیاده سازی کاری این تکنیک را در این دمو مشاهده کنید.
این مقاله به بررسی این موضوع میپردازد که چگونه تنظیمات اندازه فونت در چارچوبهای Next.js و Nuxt.js برای تولید فونت بازگشتی CSS و کاهش CLS پیادهسازی میشوند. همچنین نشان می دهد که چگونه می توانید فونت های بازگشتی را با استفاده از ابزارهای مقطعی مانند Fontaine و Capsize تولید کنید.
پس زمینه
font-display: swap عموماً برای جلوگیری از FOIT (فلش متن نامرئی) و نمایش سریعتر مطالب روی صفحه استفاده می شود. مقدار swap
به مرورگر می گوید که متن با استفاده از فونت باید فوراً با استفاده از فونت سیستم نمایش داده شود و فقط زمانی که فونت سفارشی آماده است، فونت سیستم را جایگزین کند.
بزرگترین مشکل swap
، افکت jarring است، جایی که تفاوت در اندازه کاراکترهای دو فونت منجر به تغییر محتوای صفحه می شود. این منجر به نمرات ضعیف CLS، به ویژه برای وب سایت های متنی سنگین می شود.
تصاویر زیر نمونه ای از این موضوع را نشان می دهد. تصویر اول از font-display: swap
. دومی نشان می دهد که چگونه تنظیم اندازه با استفاده از قانون CSS @font-face
تجربه بارگذاری را بهبود می بخشد.
بدون تنظیم اندازه فونت
body {
font-family: Inter, serif;
}
پس از تنظیم اندازه فونت
body {
font-family: Inter, fallback-inter, serif;
}
@font-face {
font-family: "fallback-inter";
ascent-override: 90.20%;
descent-override: 22.48%;
line-gap-override: 0.00%;
size-adjust: 107.40%;
src: local("Arial");
}
تنظیم اندازه فونت بازگشتی می تواند یک استراتژی موثر برای جلوگیری از تغییر طرح بارگذاری فونت باشد، اما پیاده سازی منطق از ابتدا می تواند مشکل باشد، همانطور که در این پست درباره بازگشت فونت ها توضیح داده شده است. خوشبختانه، چندین گزینه ابزار در حال حاضر در دسترس هستند تا این کار را هنگام توسعه برنامهها آسانتر کنند.
نحوه بهینه سازی فونت های جایگزین با Next.js
Next.js یک روش داخلی برای فعال کردن بهینه سازی فونت بازگشتی ارائه می دهد. هنگامی که فونت ها را با استفاده از مولفه @next/font بارگیری می کنید، این ویژگی به طور پیش فرض فعال می شود.
مؤلفه @next/font در نسخه 13 Next.js معرفی شد. این مؤلفه یک API برای وارد کردن فونت های Google یا فونت های سفارشی به صفحات شما ارائه می دهد و شامل میزبانی خودکار داخلی فایل های فونت است.
هنگام استفاده، معیارهای فونت بازگشتی به طور خودکار محاسبه و به فایل CSS تزریق می شود.
به عنوان مثال، اگر از فونت Roboto استفاده می کنید، معمولاً آن را در CSS به صورت زیر تعریف می کنید:
@font-face {
font-family: 'Roboto';
font-display: swap;
src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff');
font-weight: 700;
}
body {
font-family: Roboto;
}
برای انتقال به next/font:
با وارد کردن تابع 'Roboto' از 'next/font'، اعلان فونت Roboto را به جاوا اسکریپت خود منتقل کنید. مقدار بازگشتی تابع یک نام کلاسی خواهد بود که می توانید در قالب جزء خود استفاده کنید. به یاد داشته باشید که
display: swap
.import { Roboto } from '@next/font/google'; const roboto = Roboto({ weight: '400', subsets: ['latin'], display: 'swap' // Using display swap automatically enables the feature })
در کامپوننت خود، از نام کلاس تولید شده استفاده کنید:
javascript export default function RootLayout({ children }: { children: React.ReactNode; }) { return ( <html lang="en" className={roboto.className}> <body>{children}</body> </html> ); }
گزینه پیکربندی adjustFontFallback :
برای @next/font/google
: یک مقدار بولی که تعیین میکند برای کاهش جابجایی طرحبندی تجمعی از فونت بازگشتی خودکار استفاده شود یا خیر. پیش فرض درست است. Next.js بسته به نوع فونت (به ترتیب serif در مقابل sans-serif) به طور خودکار فونت بازگشتی شما را روی Arial
یا Times New Roman
تنظیم می کند.
برای @next/font/local
: یک رشته یا مقدار نادرست بولی که تعیین میکند برای کاهش جابجایی طرحبندی تجمعی از فونت بازگشتی خودکار استفاده شود یا خیر. مقادیر ممکن Arial
, Times New Roman
یا false
هستند . پیش فرض Arial
است. اگر می خواهید از فونت سریف استفاده کنید، این مقدار را روی Times New Roman
تنظیم کنید.
گزینه دیگری برای فونت های گوگل
اگر استفاده از مؤلفه next/font
گزینه ای نیست، روش دیگری برای استفاده از این ویژگی با فونت های Google از طریق پرچم optimizeFonts
است. Next.js دارای ویژگی optimizeFonts است که قبلاً به طور پیش فرض فعال شده است. این ویژگی CSS فونت گوگل را در پاسخ HTML قرار می دهد. علاوه بر این، میتوانید با تنظیم پرچم experimental.adjustFontFallbacksWithSizeAdjust
در next.config.js، ویژگی تنظیم بازگشت فونت را فعال کنید، همانطور که در قطعه زیر نشان داده شده است:
// In next.config.js
module.exports = {
experimental: {
adjustFontFallbacksWithSizeAdjust: true,
},
}
توجه : هیچ برنامه ای برای پشتیبانی از این ویژگی با app
تازه معرفی شده dir وجود ندارد. در دراز مدت، استفاده از next/font
ایده آل است.
نحوه تنظیم مجدد فونت ها با Nuxt
@nuxtjs/fontaine یک ماژول برای چارچوب Nuxt.js است که به طور خودکار مقادیر متریک فونت بازگشتی را محاسبه کرده و CSS @font-face
را ایجاد می کند.
با افزودن @nuxtjs/fontaine
به پیکربندی ماژولها، ماژول را فعال کنید:
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['@nuxtjs/fontaine'],
})
اگر از فونتهای Google استفاده میکنید یا برای یک فونت تعریف @font-face
ندارید، میتوانید آنها را به عنوان گزینههای اضافی اعلام کنید.
در بیشتر موارد، ماژول میتواند قوانین @font-face
را از CSS شما بخواند و به طور خودکار جزئیاتی مانند خانواده فونت، خانواده فونت بازگشتی و نوع نمایش را استنباط کند.
اگر فونت در مکانی تعریف شده است که توسط ماژول قابل شناسایی نیست، می توانید اطلاعات معیارها را همانطور که در قطعه کد زیر نشان داده شده است، ارسال کنید.
export default defineNuxtConfig({
modules: ['@nuxtjs/fontaine'],
fontMetrics: {
fonts: ['Inter', { family: 'Some Custom Font', src: '/path/to/custom/font.woff2' }],
},
})
ماژول به طور خودکار CSS شما را برای خواندن اعلانهای @font-face اسکن میکند و قوانین بازگشتی @font-face را ایجاد میکند.
@font-face {
font-family: 'Roboto';
font-display: swap;
src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff');
font-weight: 700;
}
/* This will be generated. */
@font-face {
font-family: 'Roboto override';
src: local('BlinkMacSystemFont'), local('Segoe UI'), local('Roboto'), local('Helvetica Neue'),
local('Arial'), local('Noto Sans');
ascent-override: 92.7734375%;
descent-override: 24.4140625%;
line-gap-override: 0%;
}
همانطور که در مثال زیر نشان داده شده است، اکنون می توانید Roboto override
به عنوان فونت بازگشتی در CSS خود استفاده کنید.
:root {
font-family: 'Roboto';
/* This becomes */
font-family: 'Roboto', 'Roboto override';
}
خودتان CSS را تولید کنید
کتابخانههای مستقل همچنین میتوانند به شما در ایجاد CSS برای تنظیم اندازه فونت کمک کنند.
با استفاده از کتابخانه فونتین
اگر از Nuxt یا Next.js استفاده نمی کنید، می توانید از Fontaine استفاده کنید. Fontaine کتابخانه زیربنایی است که @nuxtjs/fontaine را تامین می کند. می توانید از این کتابخانه در پروژه خود برای تزریق خودکار فونت CSS با استفاده از پلاگین Vite یا Webpack استفاده کنید.
تصور کنید که یک فونت Roboto در فایل CSS تعریف شده است:
@font-face {
font-family: 'Roboto';
font-display: swap;
src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff');
font-weight: 700;
}
Fontaine ترانسفورماتور Vite و Webpack را فراهم می کند تا به راحتی به زنجیره ساخت وصل شود، افزونه را همانطور که در جاوا اسکریپت زیر نشان داده شده است فعال کنید.
import { FontaineTransform } from 'fontaine'
const options = {
fallbacks: ['BlinkMacSystemFont', 'Segoe UI', 'Helvetica Neue', 'Arial', 'Noto Sans'],
// You may need to resolve assets like `/fonts/Roboto.woff2` to a particular directory
resolvePath: (id) => 'file:///path/to/public/dir' + id,
// overrideName: (originalName) => `${name} override`
// sourcemap: false
}
اگر از Vite استفاده می کنید، افزونه را مانند این اضافه کنید: javascript // Vite export default { plugins: [FontaineTransform.vite(options)] }
اگر از Webpack استفاده می کنید، آن را به صورت زیر فعال کنید:
// Webpack
export default {
plugins: [FontaineTransform.webpack(options)]
}
ماژول به طور خودکار فایل های شما را اسکن می کند تا قوانین font-face@ را تغییر دهد: css @font-face { font-family: 'Roboto'; font-display: swap; src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff'); font-weight: 700; } /* This will be generated. */ @font-face { font-family: 'Roboto override'; src: local('BlinkMacSystemFont'), local('Segoe UI'), local('Roboto'), local('Helvetica Neue'), local('Arial'), local('Noto Sans'); ascent-override: 92.7734375%; descent-override: 24.4140625%; line-gap-override: 0%; }
اکنون می توانید Roboto override
به عنوان فونت بازگشتی خود در CSS استفاده کنید. css :root { font-family: 'Roboto'; /* This becomes */ font-family: 'Roboto', 'Roboto override'; }
استفاده از کتابخانه Capsize
اگر از Next.js، Nuxt، Webpack یا Vite استفاده نمی کنید، گزینه دیگر استفاده از کتابخانه Capsize برای تولید CSS بازگشتی است.
api جدید createFontStack
API بخشی از بسته @capsize/core به نام createFontStack
است که آرایهای از معیارهای فونت را به همان ترتیبی که پشته فونت خود را مشخص میکنید (ویژگی font-family
) میپذیرد.
می توانید به مستندات استفاده از Capsize در اینجا مراجعه کنید.
مثال
مثال زیر را در نظر بگیرید: فونت وب مورد نظر Lobster است که به Helvetica Neue و سپس Arial باز می گردد. در CSS، font-family: Lobster, 'Helvetica Neue', Arial
.
CreativeFontStack را از بسته اصلی وارد کنید:
import { createFontStack } from '@capsizecss/core';
معیارهای فونت را برای هر یک از فونتهای مورد نظر وارد کنید (به متریک فونت در بالا مراجعه کنید):
javascript import lobster from '@capsizecss/metrics/lobster'; import helveticaNeue from '@capsizecss/metrics/helveticaNeue'; import arial from '@capsizecss/metrics/arial';`
پشته قلم خود را ایجاد کنید، معیارها را به عنوان یک آرایه ارسال کنید، با همان ترتیبی که از طریق ویژگی font-family CSS انجام می دهید.
javascript const { fontFamily, fontFaces } = createFontStack([ lobster, helveticaNeue, arial, ]);
این موارد زیر را برمی گرداند:
{
fontFamily: Lobster, 'Lobster Fallback: Helvetica Neue', 'Lobster Fallback: Arial',
fontFaces: [
{
'@font-face' {
'font-family': '"Lobster Fallback: Helvetica Neue"';
src: local('Helvetica Neue');
'ascent-override': '115.1741%';
'descent-override': '28.7935%';
'size-adjust': '86.8251%';
}
'@font-face' {
'font-family': '"Lobster Fallback: Arial"';
src: local('Arial');
'ascent-override': 113.5679%;
'descent-override': 28.392%;
'size-adjust': 88.053%;
}
}
]
}
باید کد fontFamily و fontFaces را به CSS خود اضافه کنید. کد زیر نحوه پیاده سازی آن را در یک شیوه نامه CSS یا در یک بلوک <style>
نشان می دهد.
<style type="text/css">
.heading {
font-family:
}
</style>
این CSS زیر را تولید می کند:
.heading {
font-family: Lobster, 'Lobster Fallback: Helvetica Neue',
'Lobster Fallback: Arial';
}
@font-face {
font-family: 'Lobster Fallback: Helvetica Neue';
src: local('Helvetica Neue');
ascent-override: 115.1741%;
descent-override: 28.7935%;
size-adjust: 86.8251%;
}
@font-face {
font-family: 'Lobster Fallback: Arial';
src: local('Arial');
ascent-override: 113.5679%;
descent-override: 28.392%;
size-adjust: 88.053%;
}
همچنین میتوانید از بسته @capsize/metrics برای محاسبه مقادیر override استفاده کنید و خودتان آنها را در CSS اعمال کنید.
const fontMetrics = require(`@capsizecss/metrics/inter`);
const fallbackFontMetrics = require(`@capsizecss/metrics/arial`);
const mainFontAvgWidth = fontMetrics.xAvgWidth / fontMetrics.unitsPerEm;
const fallbackFontAvgWidth = fallbackFontMetrics.xAvgWidth / fallbackFontMetrics.unitsPerEm;
let sizeAdjust = mainFontAvgWidth / fallbackFontAvgWidth;
let ascent = fontMetrics.ascent / (unitsPerEm * fontMetrics.sizeAdjust));
let descent = fontMetrics.descent / (unitsPerEm * fontMetrics.sizeAdjust));
let lineGap = fontMetrics.lineGap / (unitsPerEm * fontMetrics.sizeAdjust));