CSS の em と rem の違い


CSS でモバイルやタブレット端末にも対応したレスポンシブデザインするとき重要な役割を持つけれども, どちらを使えばいいのか混乱しがちな 2 つのユニット em と rem の違いをできるだけ簡単に説明します.

em の場合

まず em は font-size の値として指定されるか, 他の値として指定されるかで意味合い変わってきます.

font-size の値として使われる場合

もし font-size の値として指定されると, その font-size が定義されている要素の親要素の font-size から相対的なフォントサイズになります.

もしどれだけ上層の親要素にも font-size が定義されていない場合 (html 要素にも), ブラウザデフォルトの 16px が暗黙的に html 要素の font-size として定義されます.

つまりは html 要素の子要素で定義された font-size: 1em;16 * 116px となります.

もし font-size: 1.2em; なら 16 * 1.219.2px となります.

See the Pen MBzREw by 濱田悠 (@yu8mada) on CodePen.

もし font-size: 0.8em; が定義された要素が入れ子になった場合, 入れ子の子要素の font-size は, html 要素の font-size: 16px; と入れ子の親要素の font-size: 0.8em と入れ子の子要素の font-size: 0.8em16 * 0.8 * 0.8 となり 10.24px となります.

See the Pen RBqmrd by 濱田悠 (@yu8mada) on CodePen.

このように em で指定される font-size というのは親要素の font-size の影響を段階的に受ける相対的なフォントサイズになります.

font-size が定義された要素を入れ子にしたら入れ子にした分だけ, 相対値が適用されていきます.

font-size 以外の値として使われる場合

今度は emfont-size 以外の値として使われた場合を見てみます.

例えば padding の値として使われる場合を想定してみます.

empadding の値として使われると, font-size の時と同じように, 親要素の font-size の相対的なパディングサイズになります.

なので padding: 1em; が定義された子要素のパディングサイズは html 要素のデフォルトの font-size16px なので, 16 * 116px になります.

See the Pen 2018/08/09/the-difference-between-em-and-rem-in-css #3 by 濱田悠 (@yu8mada) on CodePen.

親要素の font-size0.8em で子要素の padding0.8em の入れ子の場合, その子要素のパディングサイズは, 親要素と html 要素の font-size の影響を受けるので, 16 * 0.8 * 0.810.24px となります.

See the Pen 2018/08/09/the-difference-between-em-and-rem-in-css #4 by 濱田悠 (@yu8mada) on CodePen.

ただ注意すべきことがあります.

それは子要素でも font-size が定義された場合です.

例えば font-size: 0.8em; と入れ子の子要素でも定義された場合, その子要素のバディングサイズは, その子要素に定義された font-size との相対的なパディングサイズなります.

その子要素の font-size は親要素と html 要素の font-size の相対値なので, つまりは 16 * 0.8 * 0.8 * 0.8 で子要素のバディングサイズは 8.192px となるわけです.

See the Pen 2018/08/09/the-difference-between-em-and-rem-in-css #5 by 濱田悠 (@yu8mada) on CodePen.

少し直感に反するので注意が必要です.

rem の場合

今度は rem の場合です.

remem 同様, font-size から相対的なサイズを得るためのユニットですが, どの要素の font-size から相対的なサイズを計算するかというのが決定的な違いになります.

rem は常に html 要素の font-size からの相対値になります.

なので親要素が html 要素でない限り, 親要素にどれだけ font-size が定義されていようと, その親要素の font-size の影響は受けません.

常に html 要素の font-size からの相対値となります.

なので remr は Root (html 要素) の r なのです.

font-size の値として使われる場合

なので次のように子要素に font-size: 0.8rem; と定義した場合, その子要素の親要素の font-size1.2em16 * 1.219.2px であっても, 19.2 * 0.815.36px とはならず, html 要素の font-size からの相対値となるので 16 * 0.812.8px となるわけです.

See the Pen 2018/08/09/the-difference-between-em-and-rem-in-css #6 by 濱田悠 (@yu8mada) on CodePen.

font-size 以外の値として使われる場合

このように rem は常に html 要素の font-size からの相対値となるので, 例えば padding: 0.8rem; が定義されている子要素に font-size: 1.2em; が定義されていようと em の場合と異なり, 同要素内の font-size の影響は全く受けません.

つまりは 16 * 1.2 * 0.815.36px とならず, 16 * 0.812.8px となります.

See the Pen 2018/08/09/the-difference-between-em-and-rem-in-css #7 by 濱田悠 (@yu8mada) on CodePen.

まとめ

まとめますと次のようになります:

  • emfont-size の値として使われると, 親要素の font-size との相対値になります.
  • emfont-size 以外の値として使われると, 同要素内の font-size との相対値になります.
  • remfont-size の値として使われると, html 要素の font-size との相対値になります.
  • remfont-size 以外の値として使われても, 同様に html 要素の font-size との相対値になります.

このことから em は, 親要素の font-size や, 同要素内の font-size に応じてパディングなどのサイズを変化させたい場合に使われ, rem は親要素や同要素内のfont-size がどんな値に定義されていても常に一貫したサイズを提供したいような場合に使われます.

ちなみに html 要素に font-size を定義する場合, デフォルトで 16px ですが, だからと言って次のように font-size: 16px; のような固定値を設定してしまうのはよくないと言われています:

/* Bad practice */
html {
  font-size: 16px;
}

というのもユーザがブラウザのフォントサイズをお好みの値に変更したとしても, その変更が反映されず, その例の場合, 常に 16px に固定されてしまうからというものです.

なので html 要素に font-size を定義したい場合は, 固定値の px ではなく, %, em, rem といった相対値のユニットを使うことが望ましいとされています:

html {
  /* This calculates to 10px (16 * 0.625) */
  font-size: 62.5%;
}

ちなみに当ブログの html 要素の font-size@media を使って, デバイス毎の viewpoint に応じて font-size10px から 14px まで変更するようにしています:

html {
  /* 10px */
  font-size: 62.5%;
}

@media (min-width: 576px) {
  html {
    /* 11px */
    font-size: 68.75%;
  }
}

@media (min-width: 768px) {
  html {
    /* 12px */
    font-size: 75%;
  }
}

@media (min-width: 992px) {
  html {
    /* 13px */
    font-size: 81.25%;
  }
}

@media (min-width: 1200px) {
  html {
    /* 14px */
    font-size: 87.5%;
  }
}

% による指定なので, ユーザが指定するブラウザのフォントサイズに応じてスケールします.

あと Bootstrap 4 を使っているので, それぞれ xs, sm, md, lg, xl という 5 つのサイズに対応させています.

ただ僕は CSS, Web デザインに関してはあまり自信がないので, 参考程度にしていただけたらと思います.

と少し脇道に逸れてしまいましたが, emrem ってそんな違いがあるんです.

僕はどういう時に em を使うべきなのか, rem を使うべきなのかは, 正直未熟な部分もありはっきりした答えを出すことができないのですが, em を使う派と rem を使う派という二派が存在しているそうなので, 明確にこっちを使うべきと判断するのは難しいのかもしれないです.

なので僕は emrem のそれぞれの特徴をおさえて, 状況に応じて使い分けていきたいなと思ってます.