📖

「Every Layout」読んでみた

2022/01/27に公開

はじめに

先輩エンジニアのオススメで「Every Layout」を読んでみました。
Chapter1はCSSの基礎、Chapter2では様々なレイアウトに存在する問題点とその解決策について書かれています。
この記事ではChapter1で紹介された、CSSの基礎について一部まとめてみました。
ちなみにもとになっているのはこちらのサイトです。

box-sizing

box-sizingはデフォルトではcontent-boxとなっており、ブロック要素は子要素の幅にパディングとボーダーを足したサイズになります。
例えば、

width: 10rem;
padding: 1rem

と書くと、widthで指定している10remに左右のpaddingの2remが足され、合計幅は12remになります。
border-boxを使うと、要素の幅はパディングやボーダーの分だけ縮まり、合計幅は指定されたwidthの10remとなります。
要素のサイズの計算を簡単にするため、一般的にはすべての要素に*セレクタとかでborder-boxを使うのが望ましいとされています。

widthのautoと100%

ある要素の子要素に

box-sizing: content-box;
width: 100%;
padding: 1rem;

とすると、子要素は2rem分親要素からはみでてしまいます。
width:100%は「自身の幅を親要素の幅と同じにする」ので、子要素の幅を親要素いっぱいにしたうえで、左右のパディングが足されてしまうからです。
この場合、widthをautoにすると子要素は親要素ぴったりに収まります。
自分の経験上、子要素が親要素をぶち抜く現象の原因はだいたいwidthでした。

フォントサイズ

サイトをコーディングする際、px単位でフォントサイズを設定することがあるかと思います。
しかしpx単位での設定では、ブラウザは開発者がそのフォントサイズに固定したがってると解釈してしまい、ユーザーがブラウザで設定しているサイズは無視されてしまいます。
エバン・ミント氏の調査によると、ブラウザの設定でフォントサイズを変更しているユーザーは、EdgeやIEを使ってるユーザーよりも多いとされています。
remやemといった単位にはサイズを固定する機能はなく、ユーザーが設定しているデフォルトのサイズに対して相対的な単位となっているため、ブラウザの設定やコンテキストに則した表示をしてくれます。

remとem

remはルート要素のフォントサイズを基準としますが、emはremと違いルート要素ではなく周辺のコンテキストに関係します。
例えば、h2の中にあるstrongのフォントサイズを少し大きくしたい場合は、

h2 {
  font-size: 2rem;
}
h2 strong {
  font-size: 1.5em;
}

と書くことができます。
この場合、h2のフォントサイズが基準となり、strongのフォントサイズは(1.5 * 2)remとなります。
h2のフォントサイズが変更されるとそれに伴いstrongのフォントサイズも変更されるようになります。
筆者の経験則ではremはブロック要素、emはインライン要素に適しており、SVGアイコンなどはemで設定するのが良いとされています。

メディアクエリとビューポート

本書ではメディアクエリを使用してCSSを再設定することを避けています。
画面幅に応じたレイアウトの再構成をハードコーディングで表現することとなり、要素やコンポーネントが置かれている状況と結びついていないからです。
ビューポート単位はブラウザの表示領域のサイズに対して相対的で、1vwは幅の1%、1vhは高さの1%になります。
要素のサイズは、メディアクエリでCSSを再設定してレスポンシブ対応させるのではなく、ビューポート単位やcalcを使い、表示領域に比例してスケーリングされるのが良いとされています。

自分もコーディングする際、要素の高さや幅をpxで固定し、メディアクエリを乱用してデザインを再現しようとしてきましたが、コードが複雑化し可読性が下がり、後々の修正がキツくなることが多々ありました。
本書では、min-heightやflex-basisを使い、要素の高さや幅の算出はブラウザ自身の計算に任せることで、開発者はあくまでレイアウトがどのような形であるべきかという意図の提示をするのを勧めています。

おわりに

今までいくつかサイトやWebアプリを作ってきたのですが、widthのautoと100%の違いとかあまり意識せずなんとなーくでCSSを書いていたので、今回改めて基礎を整理することができてよかったです。
紹介しきれなかったChapter2では具体的なレイアウトパターンの実装方法について書かれてますので、興味のある方は読んでみてください。

Discussion