【px・em・rem・%】CSS単位の使い分けについて考察

【px・em・rem・%】CSS単位の使い分けについて考察

この記事を書いた人

だいち

PENGIN BLOGメディア編集長。Web業界とは異業種の仕事をしながら、独学でWeb制作の世界に。副業でHP制作やコーディング代行、個人ブログの運営などに取り組み、現在はPENGINにてWebライティングやディレクションをしつつ、メディア運営全般を担当しています。(個人運営ブログ:https://daib-log.com/ )

今回はWebコーディング時に迷いがちな単位の使い分けについて自分なりにまとめました。

よく議論が起こるテーマですが、先にお伝えしておくとコーディング時の単位に正解は無いです。

案件によってルールが引かれてる場合もありますし、基本的に適材適所使うことが前提です。

あくまで様々な方の意見や情報を見たうえで、一つの考え方としてまとめた形になっているということをご了承ください!

当記事の結論

  • フォントサイズ:rem
  • 要素の大きさ、marginやpadding:rem
  • 親要素にあたる包含的なcontainer要素や画面幅いっぱいに表示させたい要素:
  • letter-spacingや擬似要素との間隔:em
  • boderなどの可変させたくない要素:px
  • ヒーローイメージやモーダルウィンドウ など画面を占有して表示させる要素:vw

次からその根拠と解説を紹介していきます。

絶対値と相対値

単位には「絶対値」と「相対値」があるので、こちらから触れておきます。

絶対値

固定的な値となり、他要素の単位や大きさに影響を受けません。今回紹介する単位の中ではpxがこれに該当します。また、Web制作のコーディングで使用されることはありませんが、cmやmm、ptなどもこれに当たります。

相対値

可変的な値となり、他要素の単位や大きさに影響を受けます。emremvwは相対値ということになります。

親要素に対しての〜〜や、画面幅に対しての〜〜といった形で、その大きさを決定する元の数値によって可変する単位です。

単位(px、em、rem、%、vw)の違い

px

ピクセルの略です。画面サイズの可変や、他要素の単位や大きさに関わらずサイズが固定される絶対値です。

%

指定する要素の親要素に対する相対値です。親要素にサイズ指定がされていなければ、HTMLの階層を遡ってブラウザ幅(画面幅)が基準となります。

親要素が200pxで指定したい要素に50%と指定すれば、その大きさは100pxになります。

em

emは親要素のフォントサイズに影響を受ける単位です。

<body>
  <div class="em1">
    <p>em1で指定しています。</p>
  </div>
  <div class="em2">
    <p>em2で指定しています。</p>
    <div class="em2-child">
      <p>em2-childで指定しています。</p>
    </div>
  </div>
</body>
.em1 {
  font-size: 1em;
  /*
    基準:body
    16px * 1 = 16px 
    */
}

.em2 {
  font-size: 2.5em;
  /*
    基準:body 
    16px * 2.5 = 40px 
    */
  color: red;
}

.em2-child {
  font-size: 0.8em;
  /*
    基準:em2
    40px * 0.8 = 32px 
   */
  color: blue;
}

上のようにclass=em1やclass=em2のように親要素を遡ってもフォントサイズが指定されていない場合は、bodyのデフォルトフォントサイズ(16px)が常に基準になります。

em2-childは親要素em2のフォントサイズに影響を受けます。

emで指定したフォントサイズの違い

言い換えると、親要素にフォントサイズが指定されていなければ、単位emは一文字分の大きさという理解もできます。

rem

ルート要素のフォントサイズが基準になります。

rootに20pxと指定していた場合、1rem=20pxとなります。何も指定しない場合通常rootは16pxです。

rootのフォントサイズを変更すると、各要素に指定していたremの大きさも一括で変更されることになります。

<body>
  <div class="rem1">
    <p>rem1で指定しています。</p>
  </div>
  <div class="rem2">
    <p>rem2で指定しています。</p>
    <div class="rem2-child">
      <p>rem2-childで指定しています。</p>
    </div>
  </div>
</body>
.rem1 {
font-size: 1rem;
  /*
    基準:root
    16px * 1 = 16px 
    */
}

.rem2 {
font-size: 2.5rem;
  /*
    基準:root
    16px * 2.5 = 40px 
    */
color: red;
}

.rem2-child {
font-size: 0.8rem;
  /*
    基準:root
    16px * 1.5 = 24px 
    */
color: blue;
}

先ほどのemと数値は同じにしてます。違いはrem2-childの大きさです。

em指定の場合は親要素に影響しましたが、remの場合は親要素の影響は受けないので、rootの16pxが基準になります。

vw

vwは「viewport width」の略で、画面幅を100とした時の単位になるため、1vwであればビューポート幅の 1%ということになります。

vhはheightなので高さに対する割合を指定できます。他にもvmin(ビューポートの幅と高さのうち、値が小さい方に対する割合)、vmax(ビューポートの幅と高さのうち、値が大きい方に対する割合)もあります。

[linkcard url=”https://developer.mozilla.org/ja/docs/Learn/CSS/Building_blocks/Values_and_units”]

単位(px、em、rem、%、vw)の使い分け

ここからが本題になります。コーディングを想定した使い分けをまとめています。

フォントサイズ:rem

ブラウザにはフォントサイズを変更する機能があります。

pxで指定している要素はこの機能に影響を受けなくなる為、ユーザーの想定した拡大・縮小の挙動になりません。

この機能を使う方は少数かもしれませんが、操作で得たい挙動にならないのはユーザビリティ的な問題があります。

emや%のように親要素の大きさに左右されるのは管理上大変ですし、vwで指定するとディスプレイサイズ次第では大きさが極端になり視認性が悪くなることが多いので、ここは無難なremで指定するようにします。

知らなかった方向けにブラウザフォントサイズの変更方法が解説されてる参考記事も貼っておきます。

要素の大きさ・marginやpaddingなど:rem

remで指定しておくとブラウザのフォントサイズ設定を変えた時、要素や余白も相対的にあわせて変動します。

要はOSのズーム機能を使った時と同じような挙動になるため、レイアウトが崩れにくくなるということです。

OSのズームとは?という方に一応載せておきます。たぶん使ったことある方も多いと思いますが。。。

要素サイズはpx、フォントサイズをremで指定しているような時に、ブラウザフォントサイズを変更するとレイアウトや表示が本来のデザインから崩れることがあります。

下の写真のページはレイアウト要素がpx、フォントサイズがremで指定されていました。

ブラウザフォントサイズ変更前
ブラウザフォントサイズ変更前
ブラウザフォントサイズ変更後
ブラウザフォントサイズ変更後

要素の大きさはpx指定なので変わらないけど、フォントサイズはrem指定なので、フォントだけ拡大されることで要素の中で見切れています。

こうなることを防ぐには、特別な対策をしない限り要素サイズ・フォントサイズどちらもpxかremに統一させる必要があります。

上に書いた通りどちらもremで指定しておくと、要素とフォントサイズが相対的に拡大・縮小されるため、余白も含めた大きさの関係性は維持されます。

逆にユーザー操作で諸々のバランスを可変させたくない場合は、単位をpxで統一させる必要があります。

html {
  font-size: 16px;
}
/* ↑ここにpxでフォントサイズを指定すると */
p {
  font-size: 1rem;
  padding: 1rem;
}
/* ブラウザフォントサイズ機能をいじっても変化しない */

ただ一つ注意点ですが、html(ルート要素)に直接pxでフォントサイズを指定した場合、他要素をremで指定していても可変性は失われます。

つまり要素のサイズなどにremを使う意味は実質無くなります。

親要素にあたる包含的なcontainer要素や画面幅いっぱいに表示させたい要素:%

例えばheaderやfooterなど画面横幅いっぱいに表示させたい要素や、要素を包むためのflex containerのブロックなどです。

headerやfooter、container要素などをbody直下の子要素として指定している場合width:100%と指定すれば、body=画面幅に対して100%分広げられます。

また、containerブロックや画面幅など、包含されている要素に対して2等分、3等分といったように相対的なサイズで指定したい時なも%指定が必要になります。

逆にレイアウト要素やブロック的な要素にpxやremなど固定的な単位を設定すると、画面幅を小さく可変した際に画面から見切れたり、横スクロールが発生(レイアウト崩れ)する原因になることもあります。

これ以上小さい画面で見ることを想定しない(iphoneSEの320px以下など)要素のサイズはremで指定、それ以上の大きさを指定する時は%で可変に対応させる、という考えもありかなと思います。

letter-spacingや擬似要素との間隔:em

文字の大きさに合わせて相対的に指定したほうがキレイに整う要素にはemをあてると扱いやすいです。

共通パーツとしてフォントサイズ設定のclassを設定し、そこにletter-spacingも記述しておくのも便利です。

また、テキストの上下や左右に擬似要素でアイコンなどの装飾を加えることがあるかと思いますが、その間隔にemを使っておくと、テキストのフォントサイズに連動して相対的に間隔を保ってくれます。

上ではmarginやpaddingもrem指定と書きましたが、文字サイズに合わせた余白を設けたい時はemを使うことはアリだと思います。

個人的には、メディアクエリでフォントサイズが可変するようなレスポンシブデザインの場合は、emを頻繁に使うこもあります。

boderなどの可変させたくない要素:px

ブラウザ幅が可変しても大きさや太さを変えたくない要素、例えば枠線や図形などborderで指定するものについてはpxが適しています。

ブラウザのフォントサイズ設定をいじっても、相対的に可変させる必要の無いサイズ(10px以下程度)のもののイメージです。

ヒーローイメージやモーダルウィンドウ など画面を占有して表示させる要素:vw

画面幅に対して「何%分表示させる」ということが決まっている要素はvwが便利です。

1vw=画面幅の1%なので、100vwであれば画面横幅100%となります。

便利な単位ではあるんですが、画面幅に合わせて常に割合で可変することもあり、フォントサイズなどに指定すると極端なサイズになるなど意外と管理が難しいです。

ヒーローイメージやモーダルウィンドウなど、画面占有することが決まってるレイアウトに使用する方が良いのかなと思います。

ただブラウザ右側のスクロールバーや、iOSのSafari上下のアドレスバーなどで要素が隠れることもあるため、vwやvhを使う場合は注意して使いましょう

まとめ

今回は単位の違い、使い分けについてまとめてみました。

フォントサイズと要素サイズという、Webサイトのレイアウトを左右する大枠の部分で指定される単位はremに、それ以外は適宜使い分けましょう、というのがこの記事のザックリとしたまとめです。

ここまで書いておいてなんですが、個人的にはpx統一の方が直感的で一番スッキリはすると思っています。GAFA(Google・Amazon・Facebook・Apple)のWebサイトも現在メインの要素単位にpxを採用しています。

途中書いたブラウザフォントサイズ変更についてどう捉えるか、というところで大きく見解が変わってくるのかなと見ています。

ただ、このフォントサイズ設定を変更している人は全体の3%程度はいるようなので見逃せない数値かなと。

とにかく現時点で正解は無さそうなので、スタイリングの柔軟性も考慮しつつ、固執せずに考えることが最も重要なのかなと思います。

デザイン要件やユーザビリティを考慮して、柔軟に使いこなす意識でコーディングするようにしましょう!


また、当記事を読まれている方の中にはWeb制作初学者の方もいるかと思います。デザインやコーディングの基礎知識を学びたい方向けの記事を用意しているので是非見ていってください!

PENGIN無料コーディング課題

オススメ書籍紹介

オススメUdemy講座紹介