0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pxとremはどう使い分ける?レスポンシブ・アクセシビリティを意識したCSS設計

0
Posted at

CSSを書いていると、

font-size: 16px;

と、

font-size: 1rem;

のどちらを使うべきか迷うことがあります。

見た目だけなら同じになることも多いですが、

px
rem

は考え方が違います。

特に、

  • レスポンシブ対応
  • ユーザーの文字サイズ設定
  • デザインシステム
  • コンポーネント設計

まで考えると、単純に「全部px」で書くより、remを使った方が扱いやすい場面があります。

この記事では、pxとremの違いと、実際のCSSでどう使い分けるかを整理します。

pxは固定値として扱いやすい

pxはCSSで最も直感的な単位です。

たとえば、

.card {
  width: 320px;
  padding: 24px;
}

と書けば、

幅320px
余白24px

という意味です。

デザインツールでもpxがよく使われるため、

Figmaでは24px
↓
CSSでも24px

のようにそのまま実装しやすいメリットがあります。

remはルート要素を基準にする

remは、

root em

の略です。

HTMLのルート要素、つまり通常はhtml要素のfont-sizeを基準にします。

たとえば、

html {
  font-size: 16px;
}

なら、

1rem = 16px

です。

そのため、

.title {
  font-size: 2rem;
}

は、

32px

相当になります。

1remは必ず16pxではない

よく、

1rem = 16px

と覚えます。

これは多くのブラウザのデフォルトが16pxだからです。

しかし、必ず16pxとは限りません。

たとえば、

html {
  font-size: 20px;
}

なら、

1rem = 20px

です。

つまりremは固定値ではなく、

ルートのfont-sizeに連動する相対単位

です。

pxからremへの変換

基準が16pxなら、

rem = px ÷ 16

です。

たとえば、

16px = 1rem
24px = 1.5rem
32px = 2rem
40px = 2.5rem

となります。

逆に、

px = rem × 16

です。

よく使う換算

16px基準なら、よく使う値は次のようになります。

4px   = 0.25rem
8px   = 0.5rem
12px  = 0.75rem
16px  = 1rem
20px  = 1.25rem
24px  = 1.5rem
32px  = 2rem
40px  = 2.5rem
48px  = 3rem
64px  = 4rem

このあたりを覚えておくと、毎回計算しなくてもかなり書きやすくなります。

なぜfont-sizeにremを使うのか

remのメリットが分かりやすいのは文字サイズです。

たとえば、

body {
  font-size: 1rem;
}

h1 {
  font-size: 2rem;
}

h2 {
  font-size: 1.5rem;
}

とします。

ルートが16pxなら、

body = 16px
h1   = 32px
h2   = 24px

です。

もし基準を変更すれば、全体の文字サイズをまとめて調整できます。

ユーザー設定との相性

ブラウザでは、ユーザーがデフォルト文字サイズを変更している場合があります。

たとえば視認性のために、

16px → 20px

へ変更しているケースです。

remを使っていれば、こうした設定に連動しやすくなります。

一方、文字サイズをすべてpxで固定すると、ユーザー側の設定を反映しにくくなる場合があります。

そのため、アクセシビリティを意識する場合、

font-sizeはrem

を基本にする設計がよく使われます。

paddingやmarginにもremは使える

remは文字サイズだけではありません。

たとえば、

.card {
  padding: 1.5rem;
  margin-bottom: 2rem;
  border-radius: 0.5rem;
}

のようにも使えます。

16px基準なら、

padding       = 24px
margin-bottom = 32px
border-radius = 8px

です。

文字サイズと余白を同じスケールで管理できるため、デザインシステムとも相性が良いです。

すべてremにすればいいわけではない

ここで、

じゃあpxは使わなくていい?

と思うかもしれません。

実際には、pxの方が扱いやすい場面もあります。

たとえば、

border: 1px solid #ddd;

のような細い線です。

これを、

border: 0.0625rem solid #ddd;

と書くこともできますが、かえって読みづらくなります。

そのため、

文字・余白 → rem
細い線・細かな固定値 → px

のように使い分ける方法があります。

borderはpxの方が分かりやすい

たとえば、

.card {
  border: 1px solid #e5e7eb;
}

は非常に分かりやすいです。

一方、

.card {
  border: 0.0625rem solid #e5e7eb;
}

では、

「これは何px?」

と逆算したくなります。

こうした値まで無理にremへ変換する必要はありません。

デザイン値を全部16で割るのは大変

Figmaなどで、

padding 24px
gap 12px
font-size 18px
margin 40px

と指定されている場合、remにすると、

24px → 1.5rem
12px → 0.75rem
18px → 1.125rem
40px → 2.5rem

です。

数が増えると、毎回暗算するのは意外と面倒です。

必要な値をすぐ確認したい場合は、pxとremを相互換算すると、基準font-sizeを意識しながら値を確認しやすくなります。

CSS変数と組み合わせる

remはCSS変数とも相性が良いです。

たとえば、

:root {
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
}

としておけば、

.card {
  padding: var(--space-lg);
  margin-bottom: var(--space-xl);
}

のように使えます。

数字を直接書くより、

small
medium
large

という設計意図が分かりやすくなります。

タイポグラフィもスケール化できる

文字サイズも、

:root {
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
}

のように定義できます。

すると、

.article-title {
  font-size: var(--text-2xl);
}

.article-body {
  font-size: var(--text-base);
}

と書けます。

ページごとに、

17px
19px
23px

のような中途半端な値が増えにくくなります。

html { font-size: 62.5%; }という方法

以前からよくある方法として、

html {
  font-size: 62.5%;
}

という設定があります。

ブラウザ標準が16pxなら、

16 × 0.625 = 10px

なので、

1rem = 10px

相当になります。

すると、

1.6rem = 16px
2.4rem = 24px
3.2rem = 32px

となり、暗算しやすくなります。

62.5%方式は必須ではない

便利ではありますが、必ずこの方法を使う必要はありません。

最近は、

1rem = 16px

のまま使う設計も一般的です。

理由の一つは、

16px
24px
32px

のような値なら、

1rem
1.5rem
2rem

と比較的簡単に変換できるからです。

また、ライブラリや既存CSSとの整合性を考えると、標準値のままの方が扱いやすい場合もあります。

emとremは何が違う?

remと一緒によく出てくるのがemです。

違いは基準です。

rem:

ルート要素を基準

em:

その要素のfont-sizeを基準

たとえば、

.parent {
  font-size: 20px;
}

.child {
  font-size: 1.5em;
}

なら、

20 × 1.5 = 30px

です。

一方、1.5remなら親要素ではなく、ルートのfont-sizeを基準にします。

emは入れ子で計算が複雑になることがある

たとえば、

.parent {
  font-size: 1.2em;
}

.child {
  font-size: 1.2em;
}

とすると、親のサイズを基準に子も拡大されます。

入れ子が深くなると、

1.2 × 1.2 × ...

のようになり、実際のサイズを追いにくくなることがあります。

remなら常にルート基準なので、全体で値を予測しやすいというメリットがあります。

remを使うとレスポンシブになる?

remを使っただけで、自動的にレスポンシブサイトになるわけではありません。

たとえば、

.container {
  width: 75rem;
}

と固定すれば、画面幅によっては大きすぎることがあります。

レスポンシブでは、

%
vw
max-width
min()
max()
clamp()

などとの組み合わせも重要です。

remはあくまで、

サイズ体系を相対的に管理しやすくする単位

と考えた方がよいです。

clamp()とremを組み合わせる

最近のCSSでは、

h1 {
  font-size: clamp(2rem, 4vw, 4rem);
}

のような指定もできます。

これは、

最小 2rem
可変 4vw
最大 4rem

という意味です。

画面幅によって文字を可変にしつつ、極端に小さく・大きくなるのを防げます。

remを固定値の基準として使い、vwなどと組み合わせる方法です。

実務ではどう使い分ける?

一例として、次のようなルールにすると管理しやすくなります。

font-size
→ rem

padding / margin / gap
→ rem

コンポーネントのサイズ
→ rem / % / min() / max()

border
→ px

細かなアイコン調整
→ px または rem

レイアウト幅
→ % / rem / max-width

絶対的な正解ではありません。

大切なのは、プロジェクト内でルールを統一することです。

変換値より設計ルールが大事

pxからremへの変換自体は簡単です。

16px基準なら、

px ÷ 16

するだけです。

しかし実務では、

20pxを1.25remにする

ことそのものより、

なぜここではremを使うのか
どの値をpxのまま残すのか

という設計ルールの方が重要です。

プロジェクト全体でルールがバラバラだと、

font-size: 16px;
padding: 1.5rem;
margin: 32px;
gap: 1em;

のように単位が混在し、後から管理しにくくなります。

まとめ

pxは、

固定値として分かりやすい

というメリットがあります。

remは、

ルートのfont-sizeを基準にできる

ため、

  • タイポグラフィ
  • 余白
  • デザインシステム
  • アクセシビリティ

との相性が良い単位です。

16px基準なら、

16px = 1rem
24px = 1.5rem
32px = 2rem

です。

ただし、

すべてを無理にremへ変換する必要はありません。

文字や余白はrem、1pxの境界線はpxなど、用途ごとに使い分ける方がコードは読みやすくなります。

pxとremのどちらが正しいかではなく、

プロジェクト全体で一貫したサイズ設計になっているか

を意識すると、CSSを長期的に管理しやすくなります。

0
1
0

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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?