Help us understand the problem. What is going on with this article?

CSSの単位remの正しい使い方

CSS Advent Calendar 201918日目に空きがあったので埋めます。
最終日も私です。

QiitaやGoogleでremと検索すると、間違った使い方をしている記事がたくさん出てきます。

remはroot emの略!

って分かってるならRootを潰すな!
rootはユーザー設定により変動するかもしれないものです。
ユーザビリティを考えるなら、きちんとユーザーの設定に対応出来るようにしましょう。

よく見る間違った使い方

html {
  font-size: 10px;
  // または
  font-size: 62.5%;
}

p {
  font-size: 1.5rem;
}

間違った使い方の言い分

モダンブラウザの初期値は16pxです。
だからrootを62.5%10px)にすれば1rem = 10pxで分かりやすいです。
15px1.5remと書きましょう!

[疑問] 全部pxじゃだめなの?

1rem = 10pxより全部pxで書くほう分かりやすい。
15pxと書いたほうが楽だし。

なぜこんな変な書き方が流行ったのでしょうか?

IE9以前(だったかな)はfont-sizepxで指定するとIEの機能「文字拡大」が機能しなくなるという不具合があったため、remを使って対処する」という使い方をしていました。
IE9が出た頃はCSS3が利用されて間もなく、SASSも今ほど流行ってなく、「計算が大変だから1rem = 10pxとして計算をしやすくしましょう。」という広まり方でした。
もうIE9以下を対応することはほとんど無いはずです。
現在では過去に考えられたものを、みんなコピペして紹介して、紹介されているものを見た人が鵜呑みにしているのでしょう。

なんでブラウザのfont-sizeが16pxだと思っているの?

過去には16pxでないものもありました。
また、モダンブラウザはデフォルトfont-sizeを簡単に変更できるようになっています。

root(html)に指定すると何が問題か

%での問題

html {
  font-size: 62.5%;
}

p {
  font-size: 1.5rem;
}

ユーザーがブラウザのfont-size20pxに変更したとします。
この場合にブラウザに表示されるpfont-size18.75pxです。
なぜこんな数字になるのか?20px * 62.5% * 1.5rem18.75pxとなるわけです。

「良いんじゃん!」と思った方、本来p20px * 1.5rem30pxとなるべきです。
ユーザー設定20pxなんて極端な数値で紹介していますが、17px15pxなどで設定している方はザラに居るはずです。
そうなったときに値の変動が小さい問題が発生します。。

pxでの問題

html {
  font-size: 10px;
}

p {
  font-size: 1.5rem;
}

ユーザーがブラウザのfont-size20pxに変更したとします。
この場合にブラウザに表示されるpfont-size15pxです。
ユーザーの設定を無視する最低な書き方になります。
今はユーザーファーストな時代です。
ユーザーの設定にも負けない、デザインにpx単位で忠実なものが美徳な時代もありましたが...

解決策

正しい書き方は以下

p {
  font-size: 0.9375rem;
}

以上です。
正しい書き方はhtmlfont-sizeを指定してはいけません。

分かりにくい問題

0.9375remが瞬時に15pxだと分かる人がどれだけいるでしょうか?
この場合はSassを使いましょう。

@mixin font-size($size, $base: 16) {
  font-size: $size / $base + rem;
}

p {
  @include font-size(15);
}

参考:font-size指定にremを使うmixin - Qiita

IE8以前を対応する予定がないならpxと併用して表記する必要はありません。
remを使うのはfont-sizeだけではありません、marginpaddingなどなどremで指定しなければいけませんね。

app.css
p {
  font-size: 0.9375rem;
  margin-top: 10px;
  margin-bottom: 10px;
}

こんな書き方をするとユーザー設定が影響して、文字サイズだけ変更できたのに余白が変更できないのでチグハグなことになっちゃいます。ちゃんと適切にremで指定しましょう。
borderなどは、remで指定すると1px以下になってしまい、見えなくなってしまうのでpxで指定するような例外的なプロパティもあるので注意してください。

追記

function.scss
@function rem($value) {
  @return #{$value / 16}rem;
}

p {
  font-size: rem(15);
  margin: rem(10) 0;
}

こんなScssも良いかもしれません。

終わり

CSS Advent Calendar 2019最終日も私です。よろしくおねがいします。

← 17日『CSS設計で気をつけること
→ 19日『HTML/CSSで書籍の図を作ってみた

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away