【フォント編】Astro + Cloudflare Workers でブログ作ってみた②

第2回 ブログ制作講座(?)、はじまります

前回に引き続き Astro を使ってブログを作ってみる回の続きです。 割と初っ端から結構な工程を端折ってしまったので、一つずつ丁寧に行こうと思います。

ただ、自分で弄ったほうが面白いところはあえて触れず、 ある程度決まり切った形で実装できるものを中心に一個一個解説していこうと思います。

ということで今回は、「フォントの軽量化と見た目に反映させるところまで」をまとめます。


フォントの軽量化を行う意味

今回、事前に用意するものはこちら。 Google Fonts からお好きなフォントをダウンロードしましょう。

読みやすいフォントの選び方について、ブログ用途目的で個人的な好みで述べておくと、 明朝体よりもゴシック体のフォントのほうが大抵の人は読みやすくていいんじゃないかなと思います。

本文は文字が小さめになるので、それに合わせて文字がつぶれて見えたり目が滑ったりしないフォントを選びます。

私は今回「Noto Sans JP」を使用させていただくことにしました。 こちらを軽量化するために、まずはサブセット用の文字を設定するファイルを用意します。


サブセット化について

軽量化といってもやることは単純で、使用したい文字だけをテキストで指定して、それ以外を削減するということです。 物凄く地味な作業ですが、コレが後々効いてくる…かもしれないですよ? 余談ですが、ゲーム制作でもUI用のフォント実装でまったく同じことをするので知識として持っておくといいですね。

自分が書くものが誰に向けてなのかを考えると、ある程度使える文字が決まります。 それを考えながら、使う漢字や記号などを取捨選択することが重要です。

今回サブセット化にあたって用意したものがこちら。

【主な構成要素】

  • JIS第1水準漢字
  • JIS第2水準漢字
  • ひらがな
  • カタカナ
  • 英数字(全角/半角)
  • 記号

絶対に使わないであろう漢字が圧倒的に多いように感じますが、創作においてこういった中二病めいた漢字を削ってしまうと、後から目視で追加することが面倒なんですよね。

まだまだ詰めれば削れるところはありますが、今回はここまでにしておきます。 キリがなくなってきて、詰めるべきところが詰められなくなってしまうので。 ほどほどに削ったら、次の工程に行きましょう。


Google Colaboratory でPythonコードを実行する

次に、Google Colaboratory を開きます。 Google Drive から .ipynb ファイルを開くことができるようになる拡張機能を導入してください。

そうしたら、コードの欄のところに以下をペーストして起動します。

import os
from google.colab import files

# 1. 準備
!pip install -q fonttools brotli

# 2. ファイルのアップロード
print("フォントファイルとテキストファイルを同時に選択してください。")
uploaded = files.upload()

font_file = next((f for f in uploaded.keys() if f.endswith(('.ttf', '.otf'))), None)
text_file = next((f for f in uploaded.keys() if f.endswith('.txt')), None)

if font_file and text_file:
    # --- プレビュー処理 ---
    with open(text_file, 'r', encoding='utf-8') as f:
        content = f.read()

    # 重複を除去してソート(プレビュー用)
    unique_chars = sorted(list(set(content.replace('\n', '').replace('\r', ''))))
    char_count = len(unique_chars)

    print("\n" + "="*30)
    print(f"【サブセット対象のプレビュー】")
    print(f"元のファイル: {text_file}")
    print(f"ユニーク文字数: {char_count} 文字")
    print(f"抽出文字(先頭100文字): {''.join(unique_chars[:100])}{'...' if char_count > 100 else ''}")
    print("="*30 + "\n")

    # 3. 実行確認(Colabの入力を利用)
    confirm = input("この内容でサブセットを作成しますか? (y/n): ")

    if confirm.lower() == 'y':
        output_file = f"subset_{os.path.splitext(font_file)[0]}.woff2"

        # fonttoolsのコマンド実行
        # --name-IDs='*' はフォント名情報を保持するオプション
        !pyftsubset "{font_file}" \
            --text-file="{text_file}" \
            --flavor="woff2" \
            --output-file="{output_file}" \
            --layout-features='*' \
            --name-IDs='*'

        if os.path.exists(output_file):
            print(f"\n成功!ファイルをダウンロードします: {output_file}")
            files.download(output_file)
    else:
        print("キャンセルしました。")
else:
    print("ファイルが足りません。フォント(.ttf/.otf)とテキスト(.txt)を選択してください。")

編集後フォント適用まで

まず、public > fonts のフォルダの中に加工したフォントを格納します。 その後、src > styles > global.css でフォントを定義しましょう。

CAUTION

著作権に関するトラブルが起きないように、改変元となったフォントのライセンスとURLを添付しておくと優しいです。ライセンスの権利範囲の確認もお忘れなく。

/*
* "Noto Sans Japanese" licensed under the SIL Open Font License 1.1
* https://fonts.google.com/specimen/Noto+Sans+JP
*/
@font-face {
  font-family: "NotoSansJP-subset";
  src: url("/fonts/subset_NotoSansJP-VariableFont_wght.woff2") format("woff2");
  font-display: swap;
}

/* 定義したフォントを、<body>に適用する */
body {
  font-family: "NotoSansJP-subset", Meiryo, sans-serif;
  color: #000;
  margin: 0;
  padding: 0;
  text-align: left;
}

preloadの設定もしておきましょう。 src > components > BaseHead.astro からフォントの preload を設定します。

---
// import や 変数 を定義するところ(...省略)
---

<!-- Font preloads -->
<link rel="preload" href="/fonts/subset_NotoSansJP-VariableFont_wght.woff2" as="font" type="font/woff2" crossorigin />

動作確認

最後に、実際にフォントが適用されているかどうかを実際の画面で確認します。 今回はゴシック体のフォントを使用したいので、草書体のフォントであれば比較がしやすいでしょう。ということで、 global.cssfont-family を弄って確認してみましょう。

body {
  font-family: "NotoSansJP-subset", Meiryo, sans-serif;
  /* (...省略) */
}

見方としては、左から優先的にフォントが割り当てられていきます。 そのため、左側からフォントがなかったら、その次のフォントを探す…というように順番になっています。

なので、一番左側にくるフォントを変えると、見た目の比較ができます。

body {
  font-family: cursive, "NotoSansJP-subset", Meiryo, sans-serif;
  /* (...省略) */
}

実際に指定したフォントが適用できているかの確認が出来たら、完成です。


おわり

今回は、フォントを軽量化しつつ見た目を整え、サイトを快適にすることを目標にしました。 次回の第3回では、 「SVG画像の作り方と編集方法」 についてをやります。

個別のUIやページの作り方等々は答えが私の Github に置いてあるので、いったんはよしとしておきつつ、見た目を整える方法についてをまとめてから、レイアウトや実装に入っていく感じにしていこうという方向性でやっていきます。

ここまで読んでいただきありがとうございます。今回もお疲れ様です。

睦月シゴロ

ゲーム制作や小説執筆などに情熱を注ぐ人。日々の技術的な発見や創作の裏話などを綴ります。