フォントのこだわり

この記事はNext.js版の内容です。現在はAstroで構築し直して、カスタムフォントは廃止しました。 当時のリポジトリは こちらあるので参考にしてください。

このWebサイトで使用している5種類のフォントについて書き連ねていく。 フォントを変えるだけでサイトの雰囲気は大きく変わるため、選ぶのはとても楽しかった。

ただ、フォントはあくまでもコンテンツを引き立てる役割なので、あまり派手なフォントは選ばずにベーシックなものをチョイスした。

Noto Sans JP

Google Fontsで日本語フォントを選ぶとなったらまず第一候補に上がるのがNoto Sans JPである。 文字のバランスが素晴らしく、非の打ち所がない。逆に言えば、いろんなサイトで使われているので個性に欠ける点がデメリットではある。

No more tofuからNotoと命名されたらしく、□(確かに豆腐に見える)はもうない = 全ての文字を網羅しているため、安心感があるのも大きい。

また、英数字も綺麗に表示されるため、このフォントだけでも十分なくらいだ。 そのため、フォント名を明示的に指定しなければNoto Sans JPが使われる設定にしてある。

Inter

英字フォントで一番好きなフォントがInter。 フォントを小さくしても可読性が高いのが特徴である。小さくコンパクトなデザインが好きな私にとっては非常に扱いやすい。

このサイトでは英数字であることが確定している箇所で使用している。 例えば、公開日時とかフッターのコピーライトとか。

ちなみにNoto Sans JPと意外に似ているので注意して見ないとわからないかも。

Newsreader

このサイトではほとんど使っていないが、セリフ体を指定した場合に表示されるフォントである。 イタリックにするとカッコ良いので使う機会がないか伺っているところだ。

JetBrains Mono

普段から JetBrains 製のIDEを愛用している。 このサイトの開発であればTypeScriptがメインなので WebStormいった具合に。

そんなJetBrainsがオープンソースとして開発した等幅フォントが JetBrains Mono である。 開発者には嬉しい特徴が満載なので、好みはあると思うがかなりおすすめ。

特徴的なのはリガチャ(合字)に対応していることだ。 例えば =/= は=/=になり、=> は=>になる。 初めて見る人は混乱するだろうが、慣れれば見やすいと思う。

このサイトではJetBrains Monoをコードブロックやインラインコードで使用している。

Noto Emoji

記事のアイキャッチには絵文字を使用している。 そのままではポップ過ぎてこのサイトのモノクロなイメージに合わないので、良い感じの絵文字がないか探していたときに見つけたのがNoto Emojiである。

ただ、SafariやiOSで見た場合になぜかフォントが反映されない。 代わりにAppleデフォルトの絵文字を表示させるようにしている。 原因は調査中。早いうちに解決したい。

20240519追記

こちらの記事解決方法を記載。

Next.jsとTailwindで使う

Next.jsというフレームワークでこのサイトは作られているが、Next.jsには Font Optimizationいう機能がある。

この機能を使うことでビルド時にフォントファイルをダウンロードし、他の静的アセットとともにホストできる。 そうすることでユーザがWebサイトにアクセスしたときに、パフォーマンスに影響を与えるような、フォントに対する追加のネットワーク要求を行わない。

また、読み込み時のフォントのずれを防止してくれるので、CLS低下も見込める。

簡単に導入方法を説明する。

まずは使用するフォントを定義する。 何個でもカスタムフォントを定義できるが、使えば使うほどパフォーマンスが落ちるため注意。

lib/nextjs/fonts.ts
import { Inter, JetBrains_Mono, Newsreader, Noto_Emoji, Noto_Sans_JP } from 'next/font/google';
export const notoSansJP = Noto_Sans_JP({
subsets: ['latin'],
display: 'swap',
weight: ['400', '500'],
});
export const inter = Inter({ subsets: ['latin'], weight: ['400', '500'], display: 'swap', variable: '--font-inter' });
export const newsreader = Newsreader({
subsets: ['latin'],
display: 'swap',
weight: ['400'],
style: 'italic',
variable: '--font-newsreader',
});
export const jetBrainsMono = JetBrains_Mono({
subsets: ['latin'],
display: 'swap',
weight: ['400'],
style: 'normal',
variable: '--font-jetbrains-mono',
});
export const notoEmoji = Noto_Emoji({
subsets: ['emoji'],
display: 'swap',
weight: '600',
style: 'normal',
variable: '--font-noto-emoji',
});

variable設定するとCSS変数として利用できる。

次に<html>要素にフォントを追加する。 そうすることでサイト全体に反映される。

app/layout.tsx
import { inter, jetBrainsMono, newsreader, notoEmoji, notoSansJP } from '#/lib/nextjs/fonts';
const RootLayout = ({ children }: { children: React.ReactNode }) => (
<html
className={`${notoSansJP.className} ${inter.variable} ${newsreader.variable} ${jetBrainsMono.variable} ${notoEmoji.variable}`}
>
...
</html>
)

プライマリフォントであるNoto Sans JPだけclassName呼び出していることに注意。 それ以外は先ほど設定したvariable(CSS変数)を指定する。

最後にTailwind CSSの設定を行う。

tailwind.config.ts
import type { Config } from 'tailwindcss';
import defaultTheme from 'tailwindcss/defaultTheme';
export default {
theme: {
extend: {
fontFamily: {
sans: ['var(--font-inter)', ...defaultTheme.fontFamily.sans],
serif: ['var(--font-newsreader)', ...defaultTheme.fontFamily.serif],
mono: ['var(--font-jetbrains-mono)', ...defaultTheme.fontFamily.mono],
emoji: ['var(--font-noto-emoji)', 'Apple Color Emoji'],
},
},
},
} satisfies Config;

もしカスタムフォントの読み込みに失敗したときのためにTailwind CSSのデフォルトフォントを設定しておく。 これでフォントの設定は完了した。

個別にフォントを呼び出したいときは以下のようにclassName指定するだけで良い。

<p className='font-mono'>Whereas disregard and contempt for human rights have resulted.</p>

フォントについては以上になる。 他にも知らないフォントが数えきれないほどあるので、ビビッときたフォントがあれば衝動的に変えるかもしれない。 そのときは追記する。