📝

「font-sizeの指定はpxとremどちらを使うべきか?」問題に対する回答

2020/12/14に公開
6

こんにちは。TAK(@tak_dcxi)です。

今回は SNS で頻繁に話題になる「font-size の指定はpxremどちらを使うべきか?」問題について。

自分が観測している限りだと、

  • font-size の指定は px と rem どちらを使うべきか?
  • Web デザイナーはコーディングの知識があったほうがいいか?
  • jQuery はオワコンなのか?
  • 実装者はピクセルパーフェクトに拘らないとダメか?
  • h1 タグはどこに使うべきか?

あたりは四半期に一度は話題になっている感覚がありますね。

おそらくこの記事を読んでいる方や、もしくはタイムラインにこの記事の Twitter カードなんかが流れてきてウンザリしている方も多いことでしょう。僕も正直「またこの話題か…」という感想ですが、頻繁に話題になるということはそれだけ意見が割れているということなので、自分なりの見解をまとめるためにもこの記事を投稿することにしました。

結論

まず先に僕の中での結論から話すと「どっちでもいい」です。

と言うのも px と rem どちらが向いているかというのは案件によってまちまちだからです。その案件が px が向いているなら px を、rem が向いているなら rem を使えばいいのです。

Web の世界には「font-size は rem でなければならない」とかそういったルールはありません。あるのはそれぞれの現場です。px と rem、それぞれの特性を理解して向いている方を選択しましょう。

もっと言えば font-size の種類には px と rem の他にも em や vw などがあり、どれにもメリットとデメリットはあります。要は使い分けではないでしょうか

CSS の主な単位についてのおさらい

「font-size の指定は px と rem どちらを使うべきか?」問題に対する具体的な見解に入る前に一旦 CSS の主な単位についておさらいしておきましょう。というのもこの手の話題が出ると「そもそも rem って何だよ」ってコメントを見かけるような気がするので。

原則的に font-size に用いられる単位は「<length>データ型」と呼ばれるもので、これは長さの値を表す際に用いられる単位です。長さの単位なのでwidth, height, margin, padding, border-widthなどでも用いられます。<length>データ型は主に絶対指定と相対指定の 2 つのジャンルに分かれます。

絶対指定

どんな環境でも一定な物理的な長さ。例えば「30cm」は絶対指定ですが、日本にいようが宇宙にいようがその長さは「30cm」に変わりはありません。

相対指定

他の長さを基準として長さを指定することです。例えば同じ「70%」でも東京タワーの高さの 70%と僕の身長の高さの 70%では全然違いますよね。

よく見かける単位は以下の通りでしょうか。

単位 区分 説明
px 絶対 ディスプレイの画素「ピクセル」を 1 とする単位です。Retina などの高解像度モニターでは 1px が端末の複数ピクセルに変わることもあります。
pt 絶対 Web 知らないデザイナーがイラレでカンプ作った時に見かけて困るやつ。 1pt は 1 インチの 1/72 相当で、1px=0.75pt です。
em 相対 font-size 自身に使われる場合は親要素から継承されたフォントの大きさを表します。font-size 以外で使われる場合はその要素が持つ font-size を基準とします。
rem 相対 「root em」の略でルート要素(html 要素)の font-size を基準とする単位です。原則的にはルート要素のフォントサイズの既定値は 16px なので、ルートの font-size を弄っていない場合は 1rem=16px となります。
% 相対 親要素の幅 or 高さを基準とする単位です。font-size 自身に使われる場合は挙動は em と同じになります。
vw 相対 画面の横幅を基準とした単位です。1vw は画面の横幅の長さの 1%。スクロールバーを含むので width に指定する時は気をつけること。
vh 相対 画面の縦幅を基準とした単位です。1vh は画面の縦幅の長さの 1%。font-size ではあまり使われることのない単位です。iOS ではアドレスバーの高さを考慮していないので 100vh で画面の高さいっぱいに用いる時は気をつけましょう。
vmin 相対 画面の横幅と縦幅、どちらか狭い方を基準とした単位です。スマートフォンの縦持ちの場合は vw、横持ちの場合は vh と同じです。画面いっぱいのメインビジュアルの真ん中にロゴなどを配置する際にスマートフォンの縦向き・横向きで丁度よい大きさに調整するときなどに使います。
vmax 相対 画面の横幅と縦幅、どちらか広い方を基準とした単位です。スマートフォンの縦持ちの場合は vh、横持ちの場合は vw と同じです。利用用途は vmin と同じです。
ch 相対 その要素に指定されているフォントの0の幅を基準とした単位です。CSS で 1 文字分余白を空けたりする時に使うかも。

rem を使えばレスポンシブ対応が楽になる?

rem 推奨派の意見で多いのが「rem を使えばレスポンシブ対応が楽になる」というものです。実際、今回の話題のキッカケとなるツイートでは以下のようなことが語られていました。

フォントサイズをレスポンシブにしたい時に、 rem を使えばメディアクエリでルートのフォントサイズを変更すればいいだけなのでかなり管理が楽です。 px を使うと該当箇所を全部書かないといけないので、メンテナンス性もコードサイズも悪くなる。それでもちゃんと全部かけば「不自然」にはならないです笑

言いたいことは分かります。つまりはこういうことでしょう。

base.css
html {
  /* デフォルト(モバイルビュー)ではベースのfont-sizeは12px相当 */
  font-size: 75%;
}

@media screen and (min-width:768px) {
  html {
    /* タブレットビューではベースのfont-sizeは14px相当 */
    font-size: 87.5%;
  }
}

@media screen and (min-width:1200px) {
  html {
    /* デスクトップビューではベースのfont-sizeは16px相当 */
    font-size: 100%;
  }
}

レスポンシブの時にいい感じに調整したい箇所を rem で指定し、ルートのフォントサイズを変えれば rem で指定した箇所も意図したように変わるためレスポンシブ対応が楽だということでしょう。確かに、ルートのフォントサイズを弄っただけで font-size や font-size を基準としたmarginpaddingがいい感じに変わる案件なら作業効率的にもコードの簡潔さ的にもベストな選択肢だと思います。

でも、ルートのフォントサイズを弄っただけでレスポンシブでも文字調整が済むデザインってそこまでありますか?

例えば見出しのジャンプ率を考慮しても僕が過去に携わってきた案件でデスクトップビューとモバイルビューでそれらが同じだった案件の数は 0 です。僕の見ている世界が狭いだけかもしれませんが、ルートのフォントサイズを調整すれば完結するような一律のフォントの設計になってる案件ってほぼほぼ無いと思います。

デフォルトのフォントサイズを弄るだけなら body の font-size の変更でも十分ですし、px でも rem でも結局の所レスポンシブで font-size 調整のコストは同じような印象です。

もっと言えば、レスポンシブで font-size を調整したい場合はルートのフォントサイズを弄るよりもSass の変数や CSS カスタムプロパティを使って管理したほうが小回りも効いてメンテナンス性に優れているのではないでしょうか?

base.css
:root {
  /* デフォルト(モバイルビュー)ではベースのfont-sizeは12px相当、見出しのfont-sizeは16px相当に */
  --font-size-default: 12px;
  --font-size-headline: 16px;
}

@media screen and (min-width:768px) {
  :root {
    /* タブレットビューではベースのfont-sizeは14px相当、見出しのfont-sizeは20px相当に */
    --font-size-default: 14px;
    --font-size-headline: 20px;
  }
}

@media screen and (min-width:1200px) {
  :root {
    /* デスクトップビューではベースのfont-sizeは16px相当、見出しのfont-sizeは24px相当に */
    --font-size-default: 16px;
    --font-size-headline: 24px;
  }
}

body {
  font-size: var(--font-size-default);
}

.headline {
  font-size: var(--font-size-headline);
}

ただ、動的にルートのフォントサイズを解釈するという rem 独自の機能を活かす点においてはレスポンシブでルートの font-size を調整するというのはとても理に適った行為ではあります。「レスポンシブを楽にする」ためにルートの font-size を調節するというのは疑問がありますが、「rem を動的な変数として扱い、レスポンシブでそれぞれベースとなる単位を rem に代入して、それを基に CSS を設計する」とするのなら優れたプラクティスだとは思います。(ただ、現実はそこまで意識できないことが多い)

ひとつ注意点としてはルートの font-size を調整する際は%なりを使ったほうが良いです。px で指定すると後述する「ブラウザの文字サイズ調節機能が作動しない」問題が起こってしまうので…。

font-size を px で指定するとブラウザの文字サイズ調節機能が作動しない

font-size を px で指定しないほうが良いと言われる理由のひとつに「font-size を px で指定するとブラウザの文字調節機能が作動しない」というものがあります。Chrome だと「設定 → デザイン → フォントサイズ」の項目ですね。

font-size に px を用いてしまうとユーザーが上記の設定で選択したフォントサイズは無視されて CSS で指定した文字サイズが適用されてしまいます。もし訪れてくださるユーザーが視力的な都合で文字サイズを拡大するように設定している場合、px だとそういったユーザーに優しくないサイトになってしまう可能性もあるでしょう。

👆 ブラウザの文字調節機能を使って比較してみよう

「文字調節機能を利用しているユーザーってレアじゃない?」って意見もよく聞きますが、2 年前の古いデータにはなってしまうものの Internet Archive の調査ではブラウザの文字サイズ調節機能を利用している人は約 3%だそうです。現在の日本における割合は分からないものの、もし 3%のユーザーが利用しているとなると想像以上に多い気はしますね。

■ 参考文献:Pixels vs. Ems: Users DO Change Font Size
https://medium.com/@vamptvo/pixels-vs-ems-users-do-change-font-size-5cfb20831773

ただ、拡大したい場合は文字サイズ調節機能よりも画面ズーム機能を使うって方も多いでしょうし、実際著名なサービス(GAFA に加えて Microsoft の自社サイトや Airbnb も)は px を使っています。先進国のほとんどでは Web アクセシビリティの確保が法律で義務付けられており、特に米国では Web アクセシビリティに関する提訴件数が非常に多いのにも関わらずです。なので、font-size が px で指定されているからと言って「アクセシビリティ的に悪い!」とは言えないのでは?とも思います。

ただ、ユーザーの取れる選択肢は多いほうが良いので、現在メジャーなブラウザの持つ機能を無視するかどうかは各々の価値観に依るとは思います。

CSS 設計完全ガイド著者の半田さんの px or rem に対するツイートですが、僕はこちらの意見に全面的に同意しています。

rem だと案件によっては困る可能性も…?

アクセシビリティを意識すると px で指定しないほうが良いというのはありますが、案件や現場の環境によっては px で指定したほうが良いって場合もあります。

具体的には、

  • 納品後にクライアント側で CSS を弄る可能性がある場合
  • 大規模案件などで CSS の知識が乏しい方がアサインされる可能性がある場合

など。

実際、px の方が慣れ親しんでいるのか直感的だという意見も確かで、ローンチ後の改修の作業効率性を意識すると px の方が良い場合もあります。実際問題、CSS をよく知らない人にとっては「rem って何だよ」って感じでしょうし、そこで作業効率が落ちるのなら rem がどうとか言ってられないです。

また、CSS に精通している人でも 1rem=16px 相当の計算で rem を使っている場合、電卓がないと計算が煩わしくなって余計な時間を費やしてしまうというのも聞いたことのある話です。(もしクライアントや CSS の知識が乏しい人が弄る場合、発狂してしまうかもしれません)

こういった場合はおとなしく px を使うか、rem を使う場合は後述する2つの方法を試してみるのも手かと。

解決策その 1: ルートのフォントサイズを 62.5%にして 1rem=10px 相当にする

よくあるパターンです。

base.css
html {
  font-size: 62.5%;
}

ルートにfont-size: 62.5%を指定して、1rem=10px 相当にすれば計算も簡単になります。

ただ、このパターンだとfont-size: 62.5%を指定していない外部の CSS をマージする時にその CSS で em とか rem とか使われていると崩れたりする可能性はあります。(逆に言えばfont-size: 62.5%を指定していない場合も、外部の CSS がfont-size: 62.5%で計算されているかどうか気をつけたほうがいいかもしれない)

正直ハック的なやり方であることは否めないものの、デメリットとしてはそれくらいで、やや直感的になるという点では効率的な方法ではないでしょうか。

(僕個人の感想としてはfont-size: 62.5%はハードコーディング感が出るやり方に感じてしまうのであまり好きではないです)

解決策その 2: Sass の function を使う

僕はこのやり方で記述しています。

tools/function/_rem.scss
@function rem($px) {
  @return ($px / 16) * 1rem;
}

この function をグローバルで用意しておき、

component/_button.scss
.my-button {
  font-size: rem(14); /* font-sizeは14px相当にする */
}

のように呼び出せばコンパイル後は0.875remと自動計算してくれます。

デメリットとしては Sass を利用しているのでコンパイル後の CSS をクライアントが触るって場合は辛くなるということでしょうか。ただ、コンパイル後のファイルを知見のない方が弄る事自体、色々と問題を抱えているので別の議論が必要な気がしますね…。

px → rem に自動計算してくれる PostCSS のプラグインもありますが、使ったこと無いのでコメントできません。

自分なりの font-size 指定方法

個人的な見解としては現場で rem が使えるようなら、何を使うか迷ったら思考停止で rem を使ったらいいとは思います。理由としては rem のデメリットは開発的都合しか無いからです。

僕は BEM でいう Block の font-size は rem、Element の font-size は em で指定するようにしています。Block の font-size はページ全体を基準にして、Element はコンポーネントを基準にするという考え方ですね。

だから自分が案件で最も利用する font-size の単位は rem でも px でもなく em かもしれないです。

まとめ

以上が「font-size の指定は px と rem どちらを使うべきか?」問題に対する僕なりの回答です。

基本的には px も rem も変わらないです。ブラウザの文字サイズ調節機能を意識するか、開発の効率性を意識するかの違いだと思います。どちらを尊重するかは現場によって異なるので「どちらでもいい」です。

あと、初学者の方は難しいこと考えないで px を使いましょう。こういった発展的なことはある程度知識がついてからで十分です。それと「rem を使えばレスポンシブ対応が楽になる」という意見に参考になったとコメントする前に、どうして rem を使えばレスポンシブ対応が楽になるのかを考えてから判断してみると良いと思います…。(この記事に対しても同じことが言えますね)

Discussion

アカベコアカベコ

私はアクセシビリティー (Web に限る話ではないのであえて「Web」はつけません) の観点から特別な理由がない限り相対値を利用したほうがよいと考えています。

ユーザーが可読性を向上させるために Web ブラウザーのフォントを大きくしていても、絶対値にすることで無視されます。巨大なディスプレイの解像度を OS 設定でスケーリングさせず Dot by Dot で利用してみるとわかりやすいです。固定値で 1.0 (100%) 未満のサイズを指定すると文字は豆粒のようになります。これは視力に問題を抱えていなくとも可読性を損ねます。

pxpt が特別な意味を持つ場合は指定するのもよいでしょう。画像を専門的に扱うグラフィック系のサービスでは厳密に px を一致させたスケーリングが重要となります。また CSS 組版系で PDF を生成する際に pt が必須となるかもしれません。

しかしこれらは特殊なケースです。

基本的にユーザー指定を無視する点で絶対値は避け、相対値であっても 1.0 (100%) 以上を念頭に指定するほうが多くの場合、好ましいのではないでしょうか。

「レスポンシブ対応が楽になる」は狭義の Media Queries としては本文で指定されているとおり「楽」にはなりません。一方、広義である多くの解像度やユーザー向けならば少なくとも明示的なユーザー指定や環境の標準設定を尊重するため「楽 = 安全 = 事故になりにくい」のだと思います。

現代的な Web ブラウザーであればサイト単位で拡大率を記録してくれるため、これに頼る手もあるでしょう。実際、私もよく訪問するサイトで絶対値が小さすぎる場合はそうしています。しかしこれはラスター画像も同時に拡縮するため好ましくないですし、なによりユーザーに 1 手順を煩わせている時点で設計の問題だと考えています。

TAKTAK

コメントありがとうございます。

ユーザーが可読性を向上させるために Web ブラウザーのフォントを大きくしていても、絶対値にすることで無視されます。巨大なディスプレイの解像度を OS 設定でスケーリングさせず Dot by Dot で利用してみるとわかりやすいです。固定値で 1.0 (100%) 未満のサイズを指定すると文字は豆粒のようになります。これは視力に問題を抱えていなくとも可読性を損ねます。

基本的にユーザー指定を無視する点で絶対値は避け、相対値であっても 1.0 (100%) 以上を念頭に指定するほうが多くの場合、好ましいのではないでしょうか。

絶対値指定のデメリットは本文中で述べたとおりです。実際、フォロワーにも文字サイズ調整機能を利用している方々はいらっしゃいますし、開発側の都合だけを考えてそういった方々を蔑ろにするのは非推奨だと感じています。半田さんのツイートでも触れられていましたが全実装者は「誰のためにWebサイトが存在するか」は考えたほうがいいと思います。

ただ、実際問題remの利用が足枷になってしまう現場というのも確かに存在しており(古いシステムを捨てられない現場や、パフォーマンスを考えたらjQueryは使わないほうがいいけど中々捨てられない制作現場があるのと同じようなものです)、そういった環境の方々に「pxはアクセシビリティに悪いからremを使え」と異を唱えるのは酷です。また、納期が極端に短い案件でもスピード重視で仕方なくpxを使ったというパターンも考えられます。「何かを得るためには何かを捨てなければならない」というのはこの業界あるあるですし、そこは察することも大切だとは思います。

「相対値であっても 1.0 (100%) 以上を念頭に指定する」に関してはデザインおよびターゲット層に依るものかと考えます。年配や高齢者をターゲットにしたWebサイトであれば文字サイズは大きいほうが良いでしょう。もっと言えば、それらの年代の方は新聞レイアウトに慣れ親しんでいるため余白は詰めたデザインのほうが好まれる傾向になるという自分なりの経験則もあります。一方、若者をターゲットにしたWebサイトの場合は文字サイズが小さめのほうが好まれる傾向にあります(SNSの文字サイズが小さめで慣れ親しんでいるとか電車などで覗き見されることを嫌がるとかそういった背景もあるそうです)。また、若者向けでない場合も高級感を重視するWebサイトの場合は文字サイズが小さめのほうが高級感が出やすいという事情から小さめに設定されることもあります(高級ブランドのサイトのテキストが小さめが多いのはそういった理由)。

僕も視力は酷い方(矯正器具を外すと5cm前の文字すら読めないレベル)なので気持ちは分かりますが、文字サイズの大小は会社やサービスのイメージ作りにも影響されるため「視力の悪い人に考慮して文字サイズは一律16px以上にしろ!」とも言えず、そこは仕方がないんじゃないかとは思っています。

アカベコアカベコ

返信ありがとうございます。

私も業務では TAK さんが書かれているとおり、サイトや顧客に応じて固定値も採用します。装飾として小さいサイズを指定することも否定しません。

あと、初学者の方は難しいこと考えないでpxを使いましょう。こういった発展的なことはある程度知識がついてからで十分です。

ここが気になったのでコメントしたのですが px 統一している分には BEM のように定義がユニークで破綻しにくいため、初学者にはむしろよいのかもしれませんね。初学者がずっと px を使い続けたり、相対値と混在させて事故になることを懸念していました。

それと私の想定はテキスト中心のサイトでした。これは私のコメントに前書きしておくべきでしたね。

アカベコアカベコ

初学者について。私は初学であればこそ「おまじない」的な方法を避けたほうがよい考えています。

Web ブラウザーはテキスト ビューアーとして発展した歴史があり、現在もテキスト中心のサイトは多数あるため font-size は非常に重要です。またサイズ指定そのものはレイアウト全般に関わります。そのためここは「難しいこと」ではあるのですが「初学者のうちに学んだほうがよい基礎」ではないでしょうか。

というのを前述のコメントを書いた後に動機として思い出したので補足しておきます。

アカベコアカベコ

px が「おまじない」として機能していたのは

であるためだと認識しています。かつては主要なディスプレイ解像度を調べて「今年は 〜px にしておくのが無難」みたいな記事が散見されました。しかし多種多様なディスプレイ解像度のある現在では px のような固定値を採用することで解像度の差へ本格的に向き合う必要があります。

また固定値は子要素にも影響を与えるため、あらゆる font-sizepx で統一する分にはよいのですが em% のような相対指定が交じると破綻しやすくなります。親からの伝搬を回避するためだけに非直感的な em%!important を定義する羽目になるでしょう。

「おまじない」にも時期 (旬) があるのではないでしょうか。そして現代は px などの固定値は上記のような懸念から「おまじない」として採用するとかえって苦労しますし em、それよりも更に基準が単純な rem を採用するほうが悩まなくて済むのでは?と考えています。

それと初学者の想定がわからないですね。

初学者から挫折する人のこと考えたことありますか?

px にすると挫折しないのですか?逆に rem だと挫折するのですか?初学者のレベルをどこまでも低く見積もるならどんな単位系にしても挫折するでしょうし、想定が高ければ前述のような懸念を踏まえて rem で教えたほうが問題へ遭遇しにくいでしょう。

なぜ取り扱いが難しい px が初学者向けなのですかね。これまで多用されてきたから以外の理由はあるのでしょうか。「とりあえず font-size: 14px とする」ことが「おまじない」ならば「とりあえず font-size: 1rem」もまた「おまじない」ではないでしょうか?どちらも「とりあえず登場時点の解説は割愛」するという点で「おまじない」です。学習における「おまじない」はそういうものではないですか?例えばプログラミングにおける C 言語の入門記事において #include はこうした「おまじない」として扱われるのをよく目にしました。

「とりあえず登場時点の解説を割愛」するのであれば pxrem のどちらでもよいわけです。そして「おまじない」だったものをいよいよ解説する段となったなら前述の懸念も含めて px より rem のほうが解説しやすいはずです。雑に 14px14px という説明はトートロジーです。ちゃんと説明するなら解像度、ピクセル密度 (Retina や Windows などのスケーリングも含む)、前述の懸念 (子要素への伝搬) など相当の文量を要します。

一方 rem は MDN 日本語版の説明を借りるなら「ルート要素のフォントサイズ」ですし、もう少し噛み砕くとしても「閲覧環境に設定されているフォントサイズ」でほぼ説明できます。そのため

最初からremで行けというのであればremの初学者向け解説をお願いしたいです

すら必要ないと思います。

そして初心者向けの本にどれほど「おまじない」で乗り越えろと書かれているかもご存知ですか?
最近は減ってきましたけども

むしろ一昔前までのプログラマは「おまじない」解説で乗り越えられた人達が成れたものなんじゃないでしょうかと僻む部分がありますよ

これも意味がよくわかりません。なぜ僻むのでしょう?「おまじない」解説のおかげで乗り越えられた割合の統計はありますか?

全体的に「初学者」と「おまじない」が曖昧なため生産的な議論をするには認識のすり合わせが必要ですね。これらについて私の認識と見解は本コメントに書いたとおりです。

アカベコアカベコ

このまま議論を続けてもあなたを不快にさせてしまうだけのようですので、コメントはこれで最後にします。お付き合いいただき、ありがとうございました。