この記事はQiita Advent Calendar 2021の12日目の記事で、Qiita株式会社 CX向上グループの綿貫(@xrxoxcxox)が担当します!
この記事の概要
Webの組版を現実的な手法で綺麗に整えるためのやり方をまとめました。
同じ内容の文章でも組版次第で読みやすさは変わります。
実は、意識していないとWebサイトの文章は余白がガタガタとかになりやすいんですね。
DTPに比べるとどうしても劣ってしまいますが、HTMLとCSSだけでできるだけ綺麗になるようにした & ステップバイステップで説明していますので良ければ真似てみてください!
ちなみに今回載せているコードは全てこちらのリポジトリにあります。
解決したいこと(≒よくあるWebの組版)
- 余白がガタガタ
- 見出しや本文のジャンプ率が適切でなく目が滑る
- 禁則処理がほぼ何も無い
あまり意識したことは無いかもしれませんが、こういったものを整えるだけでも随分印象が変わります!
実際にやっていく
まずはテキストを用意する
まずは最低限だけUser agent stylesheetをリセットしてテキストを貼り付けてみます。
幅1366pxの画面 |
---|
完全に怪文書ですが、ダミーテキスト生成サイトで用意した文章をベースに作成しました。
今のコードはこんな感じ
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./style.css">
<title>Qiita CSS Typesetting</title>
</head>
<body>
<div class="body-text">
<h1>へんも蚊のおねがい人らを鳥にちがい扉ましだ。</h1>
<p>ではどう生意気たたて写真たまし。外いただけこのねどこ拍子手へおまえ一枚のままへコップを過ぎようまいことじは、みんながもまた愉快だろてかい。</p>
<h2>何まで大物を追い払っしのだた。</h2>
<!-- 以下略 -->
</div>
</body>
</html>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
::before, ::after {
box-sizing: border-box;
}
テキストの横幅を制御する
先ほどの画像を見て分かるとおり、1行あたりの文字数があまりにも多すぎるため非常に読みづらいです。
よくある説として1行30~40文字が読みやすいとあるのでそれを採用し、35文字としてみました。
横幅の制限なし | 1行35文字に制限 |
---|---|
ページが縦には長くなりましたが、こちらの方が少しは読みやすいですね。
現在のコードはこんな感じ。(HTMLは変更無し)
.body-text {
display: grid;
grid-template-columns: min(100%, 35em);
justify-content: center;
padding: 2rem 1rem;
}
px
ではなくem
で横幅を指定したのは、和文の文字は仮想ボディと呼ばれる正方形の枠に収まっているからです。
そのため35em
とはニアリーイコールで35文字分の幅を取ります。1
それぞれのテキストのサイズにモジュラースケールを適用してバーティカルリズムも揃える
テキストのサイズを決めるときには一般的にはモジュラースケールを使います。
何かのサイズを基準にして、決まった比率を掛けていくことで均整のとれたスケールが出来上がるんですね。
今回は以下の式で計算してみます。
f_n = 16 \times 2^{\frac{n}{5}}
CSSではルートの計算が上手くできないので、実際に計算した値を四捨五入して以下のスケールとします
- 14
- 16
- 18
- 21
- 24
- 28
- 32
なお計算が面倒と思われる方もいると思いますがこちらのサイトで簡単にシミュレーションしてくれます。
適用するとこのようになりました。
デフォルトのフォントサイズ | モジュラースケールの適用 |
---|---|
コードはこちら。
.body-text h1 {
font-size: 2rem;
line-height: calc(0.25rem * 13);
}
.body-text h2 {
font-size: 1.75rem;
line-height: calc(0.25rem * 12);
}
.body-text h3 {
font-size: 1.5rem;
line-height: calc(0.25rem * 10);
}
.body-text h4 {
font-size: 1.3125rem;
line-height: calc(0.25rem * 9);
}
.body-text h5 {
font-size: 1.125rem;
line-height: calc(0.25rem * 8);
}
.body-text h6 {
font-size: 0.875rem;
line-height: calc(0.25rem * 6);
}
.body-text p {
font-size: 1rem;
line-height: calc(0.25rem * 7);
}
CSSカスタムプロパティあたりを使って上手く共通化できそうな内容ですし、その方がコードとしては綺麗だと思いますが、今回は実施しません。
しれっとline-height
の変更もしていますが、これはバーティカルリズムを整えるためです。
常に0.25remの整数倍(実質4pxの整数倍)になるようにしているので、テキストのブロックが整然と並んで見えるのではないでしょうか。
バーティカルリズムについては以下の記事が詳しいです。
また、モジュラースケールの考え方は他にもいくつかバリエーションがあります。
以下は参考記事です。
段落間の余白をあける
今のままでは段落間がぎゅうぎゅうなので、余白を設定します。
これもバーティカルリズムが綺麗になるよう、0.25remの整数倍のマージンを指定します。
余白無し | 余白有り |
---|---|
.body-text * + h2 {
margin-top: calc(0.25rem * 11);
}
.body-text * + h3 {
margin-top: calc(0.25rem * 10);
}
.body-text * + h4 {
margin-top: calc(0.25rem * 8);
}
.body-text * + h5 {
margin-top: calc(0.25rem * 7);
}
.body-text * + h6 {
margin-top: calc(0.25rem * 6);
}
.body-text * + p {
margin-top: calc(0.25rem * 5);
}
ここは特別言及するようなことも無いと思います。
font-familyを変更する
以下の2つの理由のためにWebフォントを使います。
- 和欧混植
- 約物の調整
最近は心配が少なめになってきたとは言え、Webフォントを使うとスピードが下がります。この章は基本的にはWebフォントを使わないと実現できないのですが、実際のプロジェクトの具合にあわせて採用するかを決めてください。
デフォルトのフォント | Yaku Han JP + Noto Sans + Noto Sans JP |
---|---|
コードはこのようになっています。
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <link rel="preconnect" href="https://fonts.googleapis.com">
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+ <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&family=Noto+Sans:wght@400;700&display=swap" rel="stylesheet">
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/yakuhanjp@3.4.1/dist/css/yakuhanjp_s-noto.min.css">
<link rel="stylesheet" href="./style.css" />
<title>Qiita CSS Typesetting</title>
</head>
body {
font-family: 'YakuHanJPs_Noto', 'Noto Sans', 'Noto Sans JP', sans-serif;
}
Noto Sans
をNoto Sans JP
より前に指定することで、英数字はNoto Sans
、日本語はNoto Sans JP
で表示されます。
実はNoto Sans
とNoto Sans JP
は別のフォントで、同じ文字でもタイプフェイスが違います。
個人的には英数字はNoto Sans
の方が好きなので変更しました。
また、Yaku Han JP
を使うことで間延びしがちな約物類をぎゅっとまとめています。
句読点まで半角にすると詰まりすぎに思ったのでSmall
の方を選択しました。
ちなみに有料ですがFONTPLUSというサービス経由でフォントを配信すると、約物まわりは更に綺麗になります。
見出しはツメる
私は本文はベタ組み(っぽく見える調整)が好きなのですが、見出しは文字サイズが大きいのもありますからツメ組みの方が良さそうです。
見出しそのまま | 見出しにfont-feature-settings: "palt"; |
---|---|
.body-text h1 {
+ font-feature-settings: "palt";
font-size: 2rem;
line-height: calc(0.25rem * 13);
}
.body-text h2 {
+ font-feature-settings: "palt";
font-size: 1.75rem;
line-height: calc(0.25rem * 12);
}
.body-text h3 {
+ font-feature-settings: "palt";
font-size: 1.5rem;
line-height: calc(0.25rem * 10);
}
.body-text h4 {
+ font-feature-settings: "palt";
font-size: 1.3125rem;
line-height: calc(0.25rem * 9);
}
.body-text h5 {
+ font-feature-settings: "palt";
font-size: 1.125rem;
line-height: calc(0.25rem * 8);
}
.body-text h6 {
+ font-feature-settings: "palt";
font-size: 0.875rem;
line-height: calc(0.25rem * 6);
}
若干間延びしていた印象のある見出しですが、割とすっきりしたと思います。
font-feature-settingsについてはAdobeのこのページが分かりやすいので紹介します。
禁則処理を追加する
かなり細かいので、1番分かりやすい箇所を示します。
ハイフネーション無し | ハイフネーション有り |
---|---|
pneumonoultramicroscopicsilicovolcanoconiosis
というやたら長い単語がを表示するために無理矢理改行されてしまっていたのを、音節をハイフンでつないで「1つの単語である」と分かるようにして表示できるようになりました。
もちろん余白の見え方も良くなっています。
body {
font-family: 'YakuHanJPs_Noto', 'Noto Sans', 'Noto Sans JP', sans-serif;
+ hyphens: auto;
+ line-break: strict;
+ overflow-wrap: break-word;
+ word-break: break-word;
}
改行の際にどのような挙動をするか、なのでQiitaの記事上で示すのがなかなか難しいのですが、細かく説明してくださっているサイトがありました。
図らずもというか、今回私が書いている内容とほぼ同じものになっています。
(word-wrapは、まあ良いかな……と思って省略しました笑)
まとめ
最初の状態 | 最後の状態 |
---|---|
- テキストの横幅を制御する
- 読みやすい文字数は1行30-40文字
- モジュラースケールやバーティカルリズムを整える
- 規則的に変化させたり配置したりすることで読みやすくなる
- font-familyを変更する
- 和欧混植
- 約物の調整
- 見出しはツメる
- 間延びして見えがちなのでCSSの機能でツメる
- 禁則処理を追加する
- 変な箇所で改行されたり、ボックスから文字が溢れてしまうのを防ぐ
Qiita Advent Calendar 2021 の 13 日目は、 @gilly が担当します、お楽しみに
-
もちろん途中で英単語が挟まったりカーニング設定を施したりすれば話は別です。そのためニアリーイコールと記載しました。 ↩