Google Fonts の英字フォントをローカルに格納する
CATEGORIES HTML/CSS PHP WORDPRESS / TAGS

Google Fonts から読み込んでいる英字フォントを、テーマに格納したファイルから読み込むようにする方法。Google Fonts の「Download」で取得したフォントを、英数字と記号だけに絞って WOFF に変換し、テーマに格納する。CSS で指定しているフォント名はそのまま使える。

ローカルに格納するメリット

  • ブラウザのキャッシュは、ほかのサイトと共有されない。今のブラウザはキャッシュをサイトごとに分けているので、Google Fonts から読み込んでも、ほかのサイトで読み込み済みのフォントは使われない(Chrome は Chrome 86 から)。「どこかのサイトで読み込み済みなら速い」という Google Fonts の利点は、今は成り立たない。
  • 接続先が自分のサーバーだけになる。Google Fonts は CSS(fonts.googleapis.com)とフォント(fonts.gstatic.com)の2つのサーバーに接続するので、接続の時間がかからなくなる。
  • 先読み(preload)を指定できる。フォントのファイル名が決まっているので、ページを開いてすぐにフォントを読み込める。代わりのフォントから Montserrat に切り替わるまでの時間が短くなる。
  • Google Fonts 側の障害や仕様の変更の影響を受けない。
  • 閲覧者の IP アドレスなどが Google に送られない。

TTFからWOFFへの変換

Google Fonts の「Download」で取得できるのは、PC にインストールして使う TTF。全部の言語の文字が入っていて圧縮もされていないので、Web で読み込むには大きい。

WOFF(Web Open Font Format)は、Web ページで使うために作られたフォントの形式。中身は TTF などのフォントのデータで、ブラウザが読み込みやすいように圧縮されている。文字の形のデータは TTF と同じなので、表示されるデザインは変わらない。今のブラウザはすべて WOFF を表示できる。

TTF と変換後の WOFF の違い(Montserrat Regular の場合)

項目TTFWOFF(変換後)
用途PC にインストールWeb ページ
入っている文字全部(2,654文字)英数字と記号(約560文字)
圧縮なしあり
ファイルの大きさ約330KB約37KB

変換で行うのは、使わない文字を外すことと圧縮の2つだけ。文字のデザインは変わらない。

変換は Mac のターミナルで行う。Python 3 と pip3 を利用できる場合の手順。

  1. Google Fonts で Montserrat を開き、「Download」で zip を取得する。zip の中に、太さごとの TTF(Montserrat-Regular.ttf・Montserrat-Bold.ttf など)とライセンスの OFL.txt が入っている。
  2. ターミナルで fonttools をインストールする。
pip3 install fonttools
  1. TTF のあるフォルダに移動し、使う太さごとに変換する。Regular(400)の場合
pyftsubset Montserrat-Regular.ttf \
  --unicodes="U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD" \
  --layout-features='*' \
  --flavor=woff \
  --output-file=montserrat-400.woff
  1. Bold(700)なども同じコマンドで変換する。TTF のファイル名と、書き出すファイル名の数字を太さに合わせて変える。
  • --unicodes:残す文字の範囲。Google Fonts が英語用(latin)に使っている範囲と同じ
  • --layout-features='*':文字の間隔の調整(カーニング)などを全部残す。指定しないと文字の詰まり方が変わる
  • --flavor=woff:WOFF で書き出す。WOFF2 にする場合は woff2(pip3 install brotli も必要)
  • --output-file:書き出すファイル名
  1. テーマのフォルダに webfonts/montserrat/ を作り、変換した WOFF と OFL.txt を格納する。
テーマのフォルダ/
├ css/
│ └ fonts.css
└ webfonts/
└ montserrat/
├ montserrat-400.woff
├ montserrat-700.woff
└ OFL.txt

※ Montserrat のライセンスは SIL Open Font License。フォントを配布するときはライセンスを同梱する決まりがあるので、OFL.txt も一緒に格納する。

CSS

テーマの css/ に fonts.css として格納する。太さごとに @font-face を1つずつ記述する。

/* =====================================================================
   テーマに格納した Web フォント(Montserrat)
   ・webfonts/montserrat/ の WOFF(英数字と記号だけに絞ったもの)
   ・太さを足すときは、WOFF を格納して @font-face を1つ追記する
   ===================================================================== */

/* 400(Regular) */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../webfonts/montserrat/montserrat-400.woff') format('woff');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* 700(Bold) */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../webfonts/montserrat/montserrat-700.woff') format('woff');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

※ テーマの CSS の font-family: 'Montserrat'; は変えなくていい。読み込み先だけが変わる。
※ unicode-range の範囲の文字だけを Montserrat で表示し、日本語など範囲外の文字は次に指定したフォントで表示する。範囲外の文字だけのページでは、フォントを読み込まない。
※ font-display: swap は、フォントを読み込むまで代わりのフォントで文字を先に表示する指定。読み込み中に文字が表示されない時間をなくすために指定する。

functions.php

unctions.php に記述する理由

  • テーマの header.php の書き方に関係なく、追記するだけで使える。
  • enqueue_block_assets で読み込むので、編集画面でも Montserrat で表示される。header.php に直接記述した CSS は、公開画面にしか効かない。
  • get_theme_file_uri() は子テーマにファイルがあれば子テーマ、なければ親テーマから読み込む。子テーマに追記すれば、親テーマを更新しても設定が消えない。

functions.php を使わずに header.php に直接記述する場合は、<head> 内の <?php wp_head(); ?> より上に下記を記述する。

<link rel="preload" href="<?php echo esc_url( get_theme_file_uri( 'webfonts/montserrat/montserrat-400.woff' ) ); ?>" as="font" type="font/woff" crossorigin>
<link rel="preload" href="<?php echo esc_url( get_theme_file_uri( 'webfonts/montserrat/montserrat-700.woff' ) ); ?>" as="font" type="font/woff" crossorigin>
<link rel="stylesheet" href="<?php echo esc_url( get_theme_file_uri( 'css/fonts.css' ) ); ?>">

functions.php に追記する場合は、テーマ(子テーマ)の functions.php の最後に追記。<?php は記述していない。

/* =====================================================================
   Web フォント(Montserrat)をテーマの中から読み込む
   ・フォント:webfonts/montserrat/montserrat-400.woff・montserrat-700.woff
   ・@font-face:css/fonts.css
   ===================================================================== */

/**
 * css/fonts.css を読み込む
 * ・enqueue_block_assets は公開画面と編集画面(ブロックエディタ)の両方で動く
 * ・優先度 1:ほかの CSS より先に読み込む
 */
function myfont_enqueue_fonts() {
	wp_enqueue_style(
		'myfont-fonts',
		get_theme_file_uri( 'css/fonts.css' ),
		array(),
		filemtime( get_theme_file_path( 'css/fonts.css' ) ) // 更新したら自動でキャッシュを読み直す
	);
}
add_action( 'enqueue_block_assets', 'myfont_enqueue_fonts', 1 );

/**
 * フォントの先読み(preload)
 * ・wp_head の優先度 1:CSS の読み込みより先に <head> に出力する
 * ・crossorigin はフォントの先読みに必須(同じサイトのファイルでも、指定しないと2回読み込まれる)
 */
function myfont_preload_fonts() {
	foreach ( array( 400, 700 ) as $weight ) { // ★ 先読みする太さ
		printf(
			'<link rel="preload" href="%s" as="font" type="font/woff" crossorigin>' . "\n",
			esc_url( get_theme_file_uri( 'webfonts/montserrat/montserrat-' . $weight . '.woff' ) )
		);
	}
}
add_action( 'wp_head', 'myfont_preload_fonts', 1 );

functions.php に追記すると、wp_head() で <head> に下記が出力される。header.php に直接記述した場合と同じ内容で、CSS の URL の ?ver= にはファイルの更新日時が自動で入る。?ver= があると、CSS を更新したときにブラウザが新しい CSS を読み込む。

<link rel="preload" href="https://example.com/wp-content/themes/テーマ名/webfonts/montserrat/montserrat-400.woff" as="font" type="font/woff" crossorigin>
<link rel="preload" href="https://example.com/wp-content/themes/テーマ名/webfonts/montserrat/montserrat-700.woff" as="font" type="font/woff" crossorigin>
<link rel='stylesheet' id='myfont-fonts-css' href='https://example.com/wp-content/themes/テーマ名/css/fonts.css?ver=1794025707' media='all' />

※ functions.php に追記した場合、header.php には何も追記しなくていい。ただし header.php の <head> 内に <?php wp_head(); ?> があることが条件。WordPress は wp_head() の位置に、functions.php で登録した先読みと CSS を出力する。
※ 先読みは、CSS より先に <head> に出力しないと効果が小さくなる。ほかのプラグインの CSS より先に出力するために、wp_head の優先度を 1 にしている。
※ 先読みする太さは、よく使うものだけにする。全部の太さを先読みすると、表示しているページで使わない太さまで最初に読み込む。
※ css/fonts.css を格納しないまま追記すると、filemtime() の Warning が表示される。先に CSS を格納すること。

Google Fonts の読み込みを外す

テーマで読み込んでいる Google Fonts の Montserrat を削除する。header.php に直接記述している場合は <link> の行、functions.php の wp_enqueue_style で読み込んでいる場合は該当する行。

<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" rel="stylesheet">

※ 外さないと、同じフォントを Google Fonts とテーマの両方から読み込む。 ※ ほかのフォントと1行にまとめて読み込んでいる場合(family=Montserrat:…&family=…)は、family=Montserrat:…& の部分だけを削除する。

読み込みの確認

  1. ブラウザの開発者ツールを開き、「ネットワーク」で「フォント」に絞り込む。
  2. ページを再読み込みする。
  3. montserrat-400.woff などがテーマのフォルダから1回ずつ読み込まれていて、fonts.gstatic.com の Montserrat がなければ設定できている。

変更する場合

項目変更箇所
太さを足すTTF を変換して webfonts/montserrat/ に格納し、fonts.css に @font-face を1つ追記
先読みする太さfunctions.php の array( 400, 700 )
フォントの格納先fonts.css の src と functions.php の webfonts/montserrat/
残す文字の範囲変換の --unicodes と fonts.css の unicode-range(同じ範囲にする)
WOFF2 にする変換の --flavor=woff2・ファイル名の .woff2、fonts.css の format('woff2')、functions.php の .woff と type="font/woff2"

日本語フォントの場合

日本語のフォントは、ひらがな・カタカナ・漢字で1万文字以上ある。1ファイルにまとめると大きくなり、ページを開くたびにフォント全部を読み込むことになる。

Google Fonts は日本語のフォントを多数のファイルに分けていて、ページで使っている文字が入ったファイルだけを読み込む。ローカルに格納する場合は、分けたファイルのまま格納して、Google Fonts と同じ unicode-range を指定する必要がある。手間が大きいので、日本語のフォントは Google Fonts のまま読み込むのがお手軽。

表示環境によって動きの見え方が異なる場合があるため、本番に反映する前に確認してね。

NOTICES

  • 記事内容は実装させたものがほとんどですが自己責任で参考にしてください。