3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScript 2Advent Calendar 2019

Day 10

font-family: serifのみの指定で日本語明朝体が表示されるかチェックする

Last updated at Posted at 2019-12-12

canvasにsans-serifとserifで「あ」を描画して差異があるかどうかを見るという方法です。

デモ

hasJapSerif
function hasJapSerif () {
	const size = 16
	const canvas = document.createElement('canvas')
	const ctx = canvas.getContext('2d')

	canvas.width = size
	canvas.height = size

	ctx.fillStyle = '#000'
	ctx.textAlign = 'start'
	ctx.textBaseline = 'top'

	ctx.font = size + 'px sans-serif'
	ctx.fillText('', 0, 0);
	const pixels1 = ctx.getImageData(0, 0, size, size).data

	ctx.clearRect(0, 0, size, size)
	ctx.font = size + 'px serif'
	ctx.fillText('', 0, 0);
	const pixels2 = ctx.getImageData(0, 0, size, size).data

	for (let i = 0, ii = size*size*4; i < ii; i++) {
		if (pixels1[i] !== pixels2[i]) {
			return true
		}
	}
	return false
}

これを利用して、Androidなど日本語明朝体がバンドルされてないデバイスのみ、日本語明朝体のウェブフォントを読み込むということができます。

if (!hasJapSerif()) {
	const link = document.createElement('link')
	link.rel = 'stylesheet'
	link.href = 'https://fonts.googleapis.com/css?family=Noto+Serif+JP'
	document.head.appendChild(link)
}

去年のAdvent Calendarでシンプルにfont-familyを指定したい記事を書きました。

その記事で全ての主要なデバイスで日本語明朝体を表示する方法の一つに、UserAgentを見てAndroidの場合はGoogleFontsのNotoSerifを読み込むという雑なサンプルコードを紹介しました。

その記事を書いた2018年末、そしてこの2019年末も、主要デバイスで日本語明朝体をバンドルしてないのはAndoridだけですが、この判定方法はもちろんスマートではないですし、今後、Androidで日本語明朝体がバンドルされて font-family: serif の指定だけで日本語明朝体が表示されるようになる可能性もあるので、ちゃんとしたものを投稿しました。

わざわざ日本語明朝体がバンドルされてない場合のみウェブフォントを読み込み適用させる方法をとりたいのは、読み込むリソースの容量をできるだけ小さくしたいだけでなく、ウェブサイトのフォントはどのデバイスでもできるだけ同じにするのではなく、そのデバイスにバンドルされてる標準なフォントをできるだけ使う、という考え方をしてるのもあります。

3
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?