🤖

デバイス判定をしAndroidだけGoogle Fontsを読み込んで明朝体を表示させるためのあれこれ

2022/07/19に公開

Webサイトで游明朝を使いたい場合など、Androidでは明朝体が読み込まれずゴシック体で表示されてしまいます。

ただGoogle Fontsの読み込みをそのまま<head>に記述してしまうとAndroid以外のデバイスでも読み込まれてしまい、パフォーマンスが落ちてしまいます。なのでJavaScriptを使ってAndroidだけ読み込ませるようにします。

https://blahis.com/dev/android_font_mincho.html

やること

  • HTMLの<head>内でデバイス判定をする<script>を追加
  • JavaScriptでデバイスの判定をしてAndroidの場合はGoogle Fontsを読み込む<script>を追加し、<body>.ua-androidのclassを付与
  • CSSで<body class="ua-android">に対してGoogle Fontsのfont-familyを指定する

コードの一例(AndroidのみNoto Serif JPfont-weight:400を読み込む場合)

デバイスがAndroidかどうかの判定は基本的にUser Agent Client Hints(以後UA-CH)で行い、UA-CHに対応していないブラウザ(2022年7月時点でSafari,Firefoxなど)はUAParser.jsというライブラリを使用して判定をします。

https://blog.chromium.org/2022/03/chrome-100-beta-reduced-user-agent.html

HTML

<head>内に直書きしていますが、読み込み方法は適宜変更してください。

index.html
<head>
<!-- 中略 -->
  <!-- CDNでUAParser.jsを読み込む -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/UAParser.js/1.0.2/ua-parser.min.js" integrity="sha512-M/6+/Ib+r5t/hijvSPLPO76abBzT8vlMVRSJ16JDA+NV9CGCkAjq8UD4kHN6KpHncDTRRIb0oUU01yhW+yfqng==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
    (() => {
      // Androidの場合に行う処理
      // headタグにGoogle Fontsを読み込むスクリプトを動的に生成
      const setupAndroid = () => {
        const e = document.createElement("link");
        e.rel = "preconnect", e.href = "https://fonts.googleapis.com", document.head.appendChild(e);
        const t = document.createElement("link");
        t.rel = "preconnect", t.href = "https://fonts.gstatic.com", t.crossOrigin = "anonymous", document.head.appendChild(t);
        const n = document.createElement("link");
        n.rel = "stylesheet", n.href = "https://fonts.googleapis.com/css2?family=Noto+Serif+JP:wght@400&display=swap", document.head.appendChild(n);
        // bodyにクラスを付与する
        window.addEventListener('DOMContentLoaded', () => {
          document.body.classList.add('ua-android');
        });
      }

      // UA-CH に対応しているブラウザと非対応のブラウザで処理を分ける
      const userAgentData = navigator.userAgentData;
      console.log(userAgentData);

      // UA-CHで取得できた場合の処理
      if (userAgentData) {
        console.log('このブラウザはUA-CHに対応しています');
        const deviceInfo = userAgentData.platform;

        // Androidの場合 Google Fontsを読み込むスクリプトを実行
        if (deviceInfo === 'Android') {
          console.log('あなたのデバイスはAndroidです');
          setupAndroid();
        }
      }

      // UA-CHに対応していない場合はUAParser.jsを利用する
      else {
        console.log('このブラウザはUA-CHに対応していません');
        const parser = UAParser();
        const osInfo = parser.os.name; // OSの名前を取得

        // Androidの場合 Google Fontsを読み込むスクリプトを実行
        if (osInfo === 'Android') {
          console.log('あなたのデバイスはAndroidです');
          setupAndroid();
        }
      }
    })();
  </script>
</head>

https://zenn.dev/kata_n/articles/c9da7a367847f8#注意点-3%3Auaparser-と併用して-ua-ch-で取得できないブラウザの判定をする

CSS

HTMLで<body>ua-androidというクラスを付与できたので、AndroidのみNoto Serif JPを読み込むようにCSSを指定します。

main.css
/* サイトで使用しているベースフォントが游明朝の場合 */
body.ua-android {
  font-family: 'Noto Serif JP', serif;
}

ちなみに自分が担当する案件は基本的に日本語と英語でフォントが異なる場合が多いので、游明朝のユーティリティクラスを作って下記のように指定しています。

main.css
body.ua-android .u-fYumin {
  font-family: 'Noto Serif JP', serif;
}

PC上で検証してみる

Chromeの場合、検証ツールのサイズ変更のところから編集…>デバイスで適当なGalaxyなどを使えるようにすればAndroidとして認識されます。

またUA-CH非対応のブラウザを検証したい場合は、FirefoxかSafariで閲覧してください。

明朝体はNoto Serif JP 以外にも選択肢が結構ある

天下のGoogle Fontsは今やいろんな明朝体を提供してくれています。
https://www.willstyle.co.jp/blog/4166/
どの明朝体にするかはクライアントやデザイナーさんに相談するのがベターだと思います。

まとめ

明朝体とゴシック体ではイメージがガラリと変わってしまいます( ˘ω˘ )
Androidユーザーは割合的に少ないかもしれませんが、サイトの印象やデザインを正しく伝えるためにもきちんとフォールバックしたいですね。

参考サイト

https://wicg.github.io/ua-client-hints/
https://developer.mozilla.org/en-US/docs/Web/API/User-Agent_Client_Hints_API
https://www.security-next.com/131039

Discussion