font-display: change kodunu içeren yazı tipleri yükleyen sitelerde, web yazı tipi yüklendiğinde ve yerine yedek yazı tipi kullanıldığında genellikle bir düzen kayması (CLS) yaşanır.
Yedek yazı tipinin boyutlarını, birincil yazı tipinin boyutlarıyla eşleşecek şekilde ayarlayarak CLS'yi engelleyebilirsiniz. @font-face
kuralındaki size-adjust
, ascent-override
, descent-override
ve line-gap-override
gibi özellikler, yedek yazı tipi metriklerinin geçersiz kılınmasına yardımcı olabilir. Bu sayede geliştiriciler, yazı tiplerinin görüntülenme şekli üzerinde daha fazla kontrol sahibi olabilir. Yazı tipi yedekleri ve geçersiz kılma özellikleri hakkında daha fazla bilgiyi bu yayında bulabilirsiniz. Ayrıca, bu demoda bu tekniğin çalışan bir uygulamasını görebilirsiniz.
Bu makalede, yedek yazı tipi CSS'sini oluşturmak ve CLS'yi azaltmak için Next.js ve Nuxt.js çerçevelerinde yazı tipi boyutu ayarlamalarının nasıl uygulandığı açıklanmaktadır. Ayrıca Fontaine ve Capsize gibi çapraz kesme araçlarını kullanarak yedek yazı tiplerini nasıl oluşturabileceğinizi de öğrenebilirsiniz.
Arka plan
font-display: replace, genellikle FOIT'yi (görünmez metnin flaşı) önlemek ve içeriği ekranda daha hızlı görüntülemek için kullanılır. swap
değeri, tarayıcıya yazı tipini kullanan metnin bir sistem yazı tipiyle hemen görüntülenmesi ve sistem yazı tipinin yalnızca özel yazı tipi hazır olduğunda değiştirilmesi gerektiğini bildirir.
swap
ile ilgili en büyük sorun, iki yazı tipinin karakter boyutları arasındaki farkın ekran içeriğinin değişmesine neden olduğu rahatsız edici efekttir. Bu durum, özellikle çok fazla metin içeren web sitelerinde CLS puanlarının düşmesine neden olur.
Aşağıdaki resimlerde sorunun bir örneği gösterilmektedir. İlk resimde, yedek yazı tipinin boyutu ayarlanmaya çalışılmadan font-display: swap
kullanılmıştır. İkincisinde ise CSS @font-face
kuralı kullanılarak boyutun düzenlenmesinin yükleme deneyimini nasıl iyileştirdiği gösterilmektedir.
Yazı tipi boyutunu ayarlamadan
body {
font-family: Inter, serif;
}
Yazı tipi boyutunu ayarladıktan sonra
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");
}
Yedek yazı tipinin boyutunu ayarlamak, yazı tipi yükleme düzeni kaymasını önlemek için etkili bir strateji olabilir. Ancak mantığın sıfırdan uygulanması zor olabilir. Yazı tipi yedekleriyle ilgili bu gönderide açıklandığı gibi hatalar yapılabilir. Neyse ki uygulama geliştirirken bunu kolaylaştırmak için halihazırda çeşitli araç seçenekleri mevcuttur.
Next.js ile yazı tipi yedeklerini optimize etme
Next.js, yedek yazı tipi optimizasyonunu etkinleştirmek için yerleşik bir yol sağlar. @next/font bileşenini kullanarak yazı tiplerini yüklediğinizde bu özellik varsayılan olarak etkinleştirilir.
@next/font bileşeni, Next.js sürüm 13'te kullanıma sunuldu. Bileşen, Google Fonts'u veya özel yazı tiplerini sayfalarınıza aktarmak için bir API sağlar ve yazı tipi dosyalarının yerleşik, otomatik olarak barındırılmasını içerir.
Kullanıldığında yedek yazı tipi metrikleri otomatik olarak hesaplanır ve CSS dosyasına eklenir.
Örneğin, Roboto yazı tipi kullanıyorsanız yazı tipini genellikle CSS'de şu şekilde tanımlarsınız:
@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;
}
Sonrakine/yazı tipine geçmek için:
"Roboto"yu içe aktararak Roboto yazı tipi bildirimini JavaScript'inize taşıyın işlevini kullanın. İşlevin döndürdüğü değer, bileşen şablonunuzda yararlanabileceğiniz bir sınıf adı olacaktır. Özelliği etkinleştirmek için yapılandırma nesnesine
display: swap
eklemeyi unutmayın.import { Roboto } from '@next/font/google'; const roboto = Roboto({ weight: '400', subsets: ['latin'], display: 'swap' // Using display swap automatically enables the feature })
Bileşeninizde, oluşturulan sınıf adını kullanın:
javascript export default function RootLayout({ children }: { children: React.ReactNode; }) { return ( <html lang="en" className={roboto.className}> <body>{children}</body> </html> ); }
.
adjustFontFallback yapılandırma seçeneği:
@next/font/google
için: Cumulative Layout Shift'i azaltmak için otomatik yedek yazı tipinin kullanılıp kullanılmayacağını belirleyen boole değeri. Varsayılan değer, doğru değeridir. Next.js, yazı tipi türüne bağlı olarak yedek yazı tipinizi otomatik olarak Arial
veya Times New Roman
olarak ayarlar (sırasıyla serif veya sans-serif).
@next/font/local
için: Cumulative Layout Shift'i azaltmak için otomatik yedek yazı tipinin kullanılıp kullanılmayacağını belirleyen bir dize veya boole false değeri. Olası değerler: Arial
, Times New Roman
veya false
. Varsayılan değer: Arial
. Serif yazı tipi kullanmak istiyorsanız bu değeri Times New Roman
olarak ayarlayın.
Google yazı tipleri için başka bir seçenek
next/font
bileşenini kullanmak mümkün değilse bu özelliği Google Fonts ile kullanmak için başka bir yaklaşım da optimizeFonts
işaretini kullanmaktır. Next.js'de optimizeFonts özelliği varsayılan olarak etkindir. Bu özellik, HTML yanıtında Google Yazı Tipi CSS'sini satır içi yapar. Ayrıca, aşağıdaki snippet'te gösterildiği gibi next.config.js'nizde experimental.adjustFontFallbacksWithSizeAdjust
işaretini ayarlayarak yazı tipi yedeklerini ayarlama özelliğini etkinleştirebilirsiniz:
// In next.config.js
module.exports = {
experimental: {
adjustFontFallbacksWithSizeAdjust: true,
},
}
Not: Yeni kullanıma sunulan app
sürümüyle bu özelliğin desteklenmesi planlanmamaktadır. Uzun vadede next/font
kullanılması idealdir.
Nuxt ile yazı tipi yedeklerini ayarlama
@nuxtjs/fontaine, Nuxt.js çerçevesi için yedek yazı tipi metriği değerlerini otomatik olarak hesaplayan ve yedek @font-face
CSS'sini oluşturan bir modüldür.
Modül yapılandırmanıza @nuxtjs/fontaine
ekleyerek modülü etkinleştirin:
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['@nuxtjs/fontaine'],
})
Google Fonts kullanıyorsanız veya yazı tipi için @font-face
bildiriminiz yoksa bunları ek seçenek olarak tanımlayabilirsiniz.
Çoğu durumda modül, CSS'nizdeki @font-face
kurallarını okuyabilir ve yazı tipi ailesi, yedek yazı tipi ailesi ve görüntüleme türü gibi ayrıntıları otomatik olarak tahmin edebilir.
Yazı tipi, modül tarafından bulunamayan bir yerde tanımlanmışsa metrik bilgilerini aşağıdaki kod snippet'inde gösterildiği şekilde iletebilirsiniz.
export default defineNuxtConfig({
modules: ['@nuxtjs/fontaine'],
fontMetrics: {
fonts: ['Inter', { family: 'Some Custom Font', src: '/path/to/custom/font.woff2' }],
},
})
Modül, @font-face bildirimlerini okumak için CSS'nizi otomatik olarak tarar ve yedek @font-face kurallarını oluşturur.
@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%;
}
Aşağıdaki örnekte gösterildiği gibi artık CSS'nizde yedek yazı tipi olarak Roboto override
kullanabilirsiniz.
:root {
font-family: 'Roboto';
/* This becomes */
font-family: 'Roboto', 'Roboto override';
}
CSS'yi kendiniz oluşturma
Bağımsız kitaplıklar, yedek yazı tipi boyutu ayarlamaları için CSS oluşturmanıza da yardımcı olabilir.
Fontaine kitaplığını kullanma
Nuxt veya Next.js kullanmıyorsanız Fontaine kullanabilirsiniz. Fontaine, @nuxtjs/fontaine'i destekleyen temel kitaplıktır. Projenizde bu kitaplığı, Vite veya Webpack eklentilerini kullanarak yedek yazı tipi CSS'sini otomatik olarak eklemek için kullanabilirsiniz.
CSS dosyasında tanımlanmış bir Roboto yazı tipiniz olduğunu düşünün:
@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, derleme zincirine kolayca bağlanabilmeniz için Vite ve Webpack dönüştürücüleri sağlar. Eklentiyi aşağıdaki JavaScript'te gösterildiği gibi etkinleştirin.
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 kullanıyorsanız eklentiyi aşağıdaki gibi ekleyin:
javascript
// Vite
export default {
plugins: [FontaineTransform.vite(options)]
}
.
Webpack kullanıyorsanız aşağıdaki şekilde etkinleştirin:
// Webpack
export default {
plugins: [FontaineTransform.webpack(options)]
}
Modül, @font-face kurallarını değiştirmek için dosyalarınızı otomatik olarak tarar:
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%;
}
.
Artık Roboto override
'i CSS'de yedek yazı tipiniz olarak kullanabilirsiniz.
css
:root {
font-family: 'Roboto';
/* This becomes */
font-family: 'Roboto', 'Roboto override';
}
Capsize kitaplığını kullanma
Next.js, Nuxt, Webpack veya Vite kullanmıyorsanız yedek CSS'yi oluşturmak için Capsize kitaplığı'nı kullanabilirsiniz.
Yeni createFontStack API'si
API, createFontStack
adlı @capsize/core paketinin bir parçasıdır. Bu paket, yazı tipi yığınınızı belirttiğiniz sırayla (font-family
özelliği) bir dizi yazı tipi metriği kabul eder.
Capsize'ı kullanmayla ilgili belgelere buradan ulaşabilirsiniz.
Örnek
Şu örneği ele alalım: İstenen web yazı tipi Lobster'dır. Bu yazı tipinde Helvetica Neue, ardından GPC'ye geri dönülür. CSS'de, font-family: Lobster, 'Helvetica Neue', Arial
.
Temel paketten createFontStack'ı içe aktarın:
import { createFontStack } from '@capsizecss/core';
İstediğiniz yazı tiplerinin her biri için yazı tipi metriklerini içe aktarın (yukarıdaki Yazı Tipi Metrikleri'ne bakın):
javascript import lobster from '@capsizecss/metrics/lobster'; import helveticaNeue from '@capsizecss/metrics/helveticaNeue'; import arial from '@capsizecss/metrics/arial';`
.Yazı tipi ailesi CSS mülkü üzerinden yaptığınız gibi, metrikleri bir dizi olarak ileterek yazı tipi yığınınızı oluşturun.
javascript const { fontFamily, fontFaces } = createFontStack([ lobster, helveticaNeue, arial, ]);
.
Bu komut aşağıdakini döndürür:
{
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%;
}
}
]
}
CSS'nize fontFamily ve fontFaces kodunu eklemeniz gerekir. Aşağıdaki kod, bunu bir CSS stil sayfasına veya <style>
bloğuna nasıl uygulayacağınızı gösterir.
<style type="text/css">
.heading {
font-family:
}
</style>
Bu işlem, aşağıdaki CSS'yi oluşturur:
.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%;
}
Geçersiz kılma değerlerini hesaplamak ve bunları CSS'ye kendiniz uygulamak için @capsize/metrics paketini de kullanabilirsiniz.
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));
Teşekkür
Alexander Andrews'un Unsplash'teki hero resim.