自己紹介

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

この記事の目的

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

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

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

MDNを調べてみると・・・

MDNを調べると、次のような説明がありました。

(em や ex などの) フォント相対単位のほとんどは、親要素のフォントサイズに対する相対値です

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

(引用元:font-size - CSS: カスケーディングスタイルシート | MDN

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

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

「em」とは ・・・ 親要素のフォントサイズを基準とする相対単位
「rem」とは ・・・ ルート要素(html要素)のフォントサイズを基準とする相対単位

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

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

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


「1rem」・・・16pxの1倍、すなわち16px
「2rem」・・・16pxの2倍、すなわち32px
「3rem」・・・16pxの3倍、すなわち48px 
(以下略)

では、em・remを体感してみよう

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

というのも、「わかったつもり」が一番怖いからです(汗)

HTMLとCSSを書いてみる

まず、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は次の通りです。

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;
}

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

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

remの基準となるフォントサイズを考える(【a-2】【b-2】)

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

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

emの基準となるフォントサイズを考える(【a-1】【b-1】)

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

【a-1】の親要素は?

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

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

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

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

【b-1】の親要素は?

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

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

実行画面で確認!
em_rem_1.png

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

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

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

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

おわりに

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

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