em, rem によるフォントサイズ指定を体感してみる

<h2>自己紹介

今年の8月末からプログラミングを勉強し始めた初心者です。
たまたま黒澤さん(@kurosawa_kuro)のウェビナー「会津ワロ法則」を受講したことがきっかけとなり、少しずつプログラミングにハマっています。
現在は、HTML/CSSについて学習しているところです。
まるで黒澤さんの弟子にでもなったような気分で、Udemyによる動画学習を楽しんでいます（笑）

<h2>この記事の目的

黒澤さんが提唱されている「Qiitaへのアウトプット」を実践するのが、この記事の目的です。
Udemyを受け身で受講するだけでなく、<strong>「学んだことを記事として発信する」というプロセス</strong>を経ることで、より着実にプログラミングを体得しようという試みです。

<h2>今回のテーマ：フォントサイズの単位「em、rem」

今回の記事のテーマは、<strong>HTML/CSSにおけるフォントサイズの相対指定</strong>です。
というのも、直感的に理解しやすいpxの絶対指定に比べると、<strong>em・remを用いた相対指定</strong>は、どうしても難しく感じます。
そこで、em・rem について自分なりに整理することで、より深い理解につなげようと考えました。

<h3>MDNを調べてみると・・・

MDNを調べると、次のような説明がありました。
> (em や ex などの) フォント相対単位のほとんどは、<strong>親要素</strong>のフォントサイズに対する相対値です

>(rem などの) <strong>ルート</strong>を基準としたフォント相対単位では、フォントサイズは <html> (ルート) 要素で使われているフォントのサイズからの相対値です。

（引用元：<a href="https://developer.mozilla.org/ja/docs/Web/CSS/font-size">font-size - CSS: カスケーディングスタイルシート | MDN<a>）

<h3>ポイントは「大きさの基準」をどこにおくか

つまり、次のように定義できるのだと思います。

<strong>「em」とは ・・・ 親要素のフォントサイズを基準とする相対単位</strong>
<strong>「rem」とは ・・・ ルート要素（html要素）のフォントサイズを基準とする相対単位</strong>

なお、html要素のフォントサイズは、多くのブラウザで<strong>16px</strong>と設定されているようです。

したがって、次のように考えておけばよさそうです。


```
「1em」・・・親要素のフォントサイズの1倍
「2em」・・・親要素のフォントサイズの2倍
「3em」・・・親要素のフォントサイズの3倍　
（以下略）


「1rem」・・・16pxの1倍、すなわち16px
「2rem」・・・16pxの2倍、すなわち32px
「3rem」・・・16pxの3倍、すなわち48px　
（以下略）
```
<h2>では、em・remを体感してみよう

ここからは実際にコードを書いて、それがブラウザでどう反映されるか見ていきたいと思います。

というのも、<strong>「わかったつもり」が一番怖いからです（汗）</strong>

<h3>HTMLとCSSを書いてみる


まず、HTMLには次のように記述します。

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>emとremを体感する</title>
    <link rel="stylesheet" href="css/html5reset.css">
    <link rel="stylesheet" href="css/em_rem.css">
  </head>
  <body><!--body要素のfont-sizeを16pxと指定-->
    <p>body要素のfont-sizeを「16px」と指定しています</p>
    <hr>
    <p id="a-1">【a-1】 font-sizeを「1em」と指定したp要素です</p>
    <p id="a-2">【a-2】 font-sizeを「1rem」と指定したp要素です</p>
    <hr>
    <div> <!--div要素のfont-sizeを32pxと指定-->
      <p>ここからは32pxに指定したdiv要素の中です</p>
      <p id="b-1">【b-1】 font-sizeを「1em」と指定したp要素です</p>
      <p id="b-2">【b-2】 font-sizeを「1rem」と指定したp要素です</p>
    </div>
    <hr>
  </body>
</html>
```
一方、CSSは次の通りです。

```css
body {
  margin: 2rem;
  font-size: 16px;
  line-height: 2;
}

#a-1 {
  font-size: 1em;
}

#a-2 {
  font-size: 1rem;
}

div {
  font-size: 32px;
}

#b-1 {
  font-size: 1em;
}

#b-2 {
  font-size: 1rem;
}
```

このように記述した場合、<strong>【a-1】【a-2】【b-1】【b-2】とラベリングした4つのp要素は、それぞれ何pxでブラウザに表示されるでしょうか？</strong>

実際に実行画面を確認する前に、コードを見ながら考えてみることにします。

<h3>remの基準となるフォントサイズを考える（【a-2】【b-2】）

なお、html要素のフォントサイズは、多くのブラウザと同様に16pxとしましょう。

この時点で、「rem」を使ってサイズ指定したフォントの大きさが確定します。
なぜなら、<strong>単純に16pxを基準に考えればよい</strong>からです。
つまり【a-2】【b-2】は、いずれも「1rem＝16px」となるはずです。

<h3>emの基準となるフォントサイズを考える（【a-1】【b-1】）

一方、「em」を使ってサイズ指定した【a-1】【b-1】については、もう少し考える必要があります。
なぜなら、<strong>基準となる親要素を確認しなければならない</strong>からです。

<h4>【a-1】の親要素は？

順を追って見ていきます。

まず、ルートにあたるhtml要素のフォントサイズは、先ほども触れたように16pxです。

そのひとつ下には、body要素があります。body要素のフォントサイズは、CSSで16pxに指定しています。

ここで、【a-1】のフォントサイズが確定します。なぜなら、<strong>【a-1】の親要素はbody要素</strong>だからです。
つまり、【a-1】で使った「em」については、<strong>body要素の16pxを基準にすればよい</strong>ことになります。
したがって、【a-1】では「1em＝16px」となるはずです。

<h4>【b-1】の親要素は？

これに対して、<strong>【b-1】はdiv要素に囲まれています</strong>。つまり【b-1】で使った「em」は、親要素であるdiv要素のフォントサイズが基準になります。

div要素のフォントサイズは、CSSで32pxに指定しています。したがって、その子要素である【b-1】では、「1em＝32px」となるはずです。

<h3>実行画面で確認！
![em_rem_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696316/d1011623-7bba-fac0-9a41-302bb69714b8.png)

いちばん上の16pxで絶対指定した行を基準にして確認すると、考えたとおりのフォントサイズになっていることがわかります。

「1em」の大きさは、親要素のフォントサイズによって変わっています。同じ「1em」という記述なのに、書く場所によって大きさが変わっちゃうんですね。 <strong>なかなか柔軟性のあるやつだな（笑）</strong>

一方「1rem」の大きさは、常に16pxのままです。<strong>お堅いというか、安定感があるというか。。。</strong>

こうしてみると、<strong>それぞれまったく違う性格を持っているんだな～</strong>と思えてくるから不思議です。

<h2>おわりに

さて、今回は実際にコードを書いてみることで、「em」と「rem」の性格がいかに違うか、ひしひしと実感することができました。
<strong>やはりプログラミングは、手を動かしてナンボですね！</strong>

最後まで読んでいただき、どうもありがとうございました！