ウェブエンジニア問題集
第7章

テキスト・フォント・改行制御 — 読みやすさを設計する

18
この章の目次開く

テキストの見た目は、ページの読みやすさ・信頼感・操作しやすさに直結します。CSSで文字を整えるときは、単に「おしゃれにする」のではなく、読ませたい情報を迷わず読める状態にすることが大切です。

学習者学習者

文字まわり、なんとなく整えてるけど「読みやすい」の基準が分からない…。フォントサイズや行間って、どう決めればいいの?

結論から言うと、本文は font-size: 1remline-height: 1.61.8 を起点にし、見出し・補足・ボタンなど役割ごとに調整していくと安定します。さらに、長いURLや日本語の折り返しまで考えておくと、スマートフォンでも崩れにくいUIになります。

Tailwind CSSで同じ考え方をクラスとして使う場合は、Tailwind CSSの文字サイズ・フォント・行間text-*font-*leading-*line-clamp-* の組み合わせを整理しています。

読みやすいテキストを設計しているイメージ


タイポグラフィで調整するもの

CSSで文字を整えるときは、次のプロパティをセットで考えます。

プロパティ役割よく使う値
font-familyフォントの種類sans-serif, Noto Sans JP
font-size文字サイズ1rem, 0.875rem, clamp()
font-weight太さ400, 500, 700
line-height行間1.5, 1.7, 1.2
letter-spacing文字間隔0.02em, 0.08em
text-align揃え位置left, center, right
white-space改行・空白の扱いnormal, nowrap, pre-wrap
overflow-wrap長い単語の折り返しbreak-word, anywhere
word-break単語単位の改行ルールnormal, keep-all, break-all

文字は1つのプロパティだけで決まりません。たとえば font-size が同じでも、line-height が狭いと詰まって見えます。font-weight が太すぎると、見出しは目立ちますが本文は読みづらくなります。


font-family — フォントの種類を指定する

font-family は、表示するフォントを指定するプロパティです。カンマ区切りで複数指定すると、左から順に使えるフォントが選ばれます。

body {
  font-family: 'Noto Sans JP', sans-serif;
}
css

最後には必ず sans-serifserif のような総称ファミリーを書きます。指定したフォントが読み込めなかった場合でも、近い種類のフォントで表示できるようにするためです。

システムフォントスタック

Webフォントを読み込まず、OSに入っているフォントを使う指定もよく使われます。読み込みが不要なので高速で、管理画面やドキュメント系のUIと相性が良いです。

body {
  font-family:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans JP',
    sans-serif;
}
css

日本語サイトでは、日本語フォントもフォールバックに入れておくと安定します。

body {
  font-family:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Hiragino Sans', 'Hiragino Kaku Gothic ProN',
    Meiryo, 'Noto Sans JP', sans-serif;
}
css

Webフォントを使うときの注意

Google FontsなどのWebフォントを使う場合は、HTMLの <link> やCSSの @import で読み込みます。ただし、日本語フォントはファイルサイズが大きくなりやすいため、必要な太さだけを読み込むのが基本です。

<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;500;700&display=swap"
  rel="stylesheet"
/>
html

font-size — 文字サイズを決める

font-size は文字の大きさを指定します。本文の基準は 1rem、つまり多くのブラウザで 16px 相当です。

body {
  font-size: 1rem; /* 通常は16px相当 */
}
 
h1 {
  font-size: 2rem; /* 32px相当 */
}
 
h2 {
  font-size: 1.5rem; /* 24px相当 */
}
 
small {
  font-size: 0.875rem; /* 14px相当 */
}
css

rem はルート要素、つまり htmlfont-size に対する倍率です。ユーザーがブラウザ設定で文字を大きくしている場合、rem はその設定に追従します。

px・em・remの違い

単位基準向いている用途
px固定値ボーダー、アイコン、細かい調整
em親要素の文字サイズボタン内の余白、コンポーネント内の相対調整
remルート要素の文字サイズ本文、見出し、余白の共通スケール

基本は rem を使い、コンポーネント内で文字サイズに連動させたい余白には em を使うと扱いやすくなります。

.button {
  font-size: 1rem;
  padding: 0.6em 1em; /* 文字サイズに応じて余白も変わる */
}
 
.button-large {
  font-size: 1.125rem;
}
css

clamp()でレスポンシブな文字サイズにする

見出しは画面幅に応じて少し変化させると、スマホでもPCでも自然に見えます。clamp(最小値, 推奨値, 最大値) を使うと、メディアクエリを書かずにサイズを制御できます。

h1 {
  font-size: clamp(1.75rem, 4vw, 3rem);
  line-height: 1.2;
}
 
h2 {
  font-size: clamp(1.375rem, 2.5vw, 2rem);
  line-height: 1.3;
}
css

ただし、本文まで大きく可変にしすぎると読み心地が不安定になります。本文は 1rem1.125rem 程度を基準にし、見出しだけ clamp() を使うところから始めるのが現実的です。


font-weight — 太さで情報の強弱を作る

font-weight は文字の太さを指定します。

.text {
  font-weight: 400; /* normal */
}
 
.lead {
  font-weight: 500; /* 少し強調 */
}
 
.heading {
  font-weight: 700; /* bold */
}
css
呼び方主な用途
400normal本文
500mediumラベル、少し強めたい本文
600semibold小見出し、ボタン
700bold見出し、強い強調

日本語フォントでは、太字を多用すると画面全体が重く見えやすいです。本文は 400、UIラベルやボタンは 500600、見出しは 700 くらいにするとバランスを取りやすくなります。

先生先生

「全部太字」は強調ではなく、情報の優先順位が消えた状態になりやすいよ。太さは、見出し・ラベル・本文の役割を分けるために使おう。


line-height — 行間を整える

line-height は行の高さを指定します。本文の読みやすさに最も影響しやすいプロパティです。

p {
  line-height: 1.7;
}
 
h1 {
  line-height: 1.2;
}
css

単位なしの数値は、要素自身の font-size に対する倍率です。たとえば font-size: 16px; line-height: 1.7; なら、行の高さは 27.2px になります。

要素目安
本文1.61.8
長文記事1.71.9
見出し1.151.35
ボタン・ナビ11.4

本文は行間が狭いと目で追いづらくなり、広すぎると段落のまとまりが弱くなります。日本語の長文では 1.7 前後から調整すると失敗しにくいです。

line-heightは単位なしを使う

line-height には px% も指定できますが、基本は単位なしの数値を使います。子要素に継承されたときも、各要素の font-size に応じて自然に計算されるためです。

body {
  font-size: 1rem;
  line-height: 1.7;
}
 
.small-note {
  font-size: 0.875rem;
  /* line-heightは0.875remに対して1.7倍で計算される */
}
css

1行の長さも読みやすさに影響する

文字サイズと行間を整えても、1行が長すぎると読みづらくなります。本文エリアには max-width を設定して、行長を制御しましょう。

.article {
  max-width: 42rem;
  margin-inline: auto;
  font-size: 1rem;
  line-height: 1.8;
}
css

日本語の本文では、PC画面で横に広がりすぎないようにするだけで読みやすさが大きく改善します。カードの説明文やFAQの回答文も、幅いっぱいに広げず適度な最大幅を持たせると安定します。


letter-spacing — 文字間隔を調整する

letter-spacing は文字と文字の間隔を調整します。

h1 {
  letter-spacing: 0.02em;
}
 
.tag {
  letter-spacing: 0.08em;
}
css

少し広げると見出しや短いラベルが読みやすくなることがあります。ただし、本文に大きな letter-spacing を入れると読みにくくなります。

/* よくない例:本文全体に広い文字間隔を入れる */
p {
  letter-spacing: 0.08em;
}
css

英大文字のラベルでは広げる

英大文字だけの短いラベルは、文字が詰まって見えやすいです。少しだけ間隔を広げると読みやすくなります。

.eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
css

日本語の本文では、基本的に letter-spacingnormal のままで問題ありません。見出しやロゴ風の短いテキストだけ、必要に応じて調整しましょう。


text-align — 揃え位置を決める

text-align はテキストの横方向の揃え位置を指定します。

.center {
  text-align: center;
}
 
.right {
  text-align: right;
}
 
.left {
  text-align: left;
}
css

本文は左揃えが基本です。中央揃えは短い見出しやヒーローセクションには使えますが、長い文章では行頭の位置が毎行ずれて読みにくくなります。

/* 短い見出しならOK */
.hero-title {
  text-align: center;
}
 
/* 長文は左揃え */
.article-body {
  text-align: left;
}
css

text-decoration・text-transform — 補助的な文字装飾

リンクやラベルでは、文字装飾もよく使います。

a {
  color: #2563eb;
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
 
a:hover {
  text-decoration-thickness: 2px;
}
css

text-underline-offset を使うと、下線と文字の距離を調整できます。リンクの下線が文字に近すぎて窮屈に見えるときに便利です。

.label {
  text-transform: uppercase;
}
css

text-transform: uppercase; は英字を大文字に変換します。見た目だけの変換なので、HTML上のテキストを無理に大文字で書く必要がありません。


テキストの改行・折り返し制御

「URLが枠をはみ出す」「日本語が変なところで切れる」「ボタンの文字が2行になって崩れる」など、テキストの折り返しまわりは実務でよく問題になります。

テキストの改行制御に悩んでいるイメージ

white-space — 改行・空白の扱い

white-space は、HTML上の改行や連続空白をどう表示するか、幅が足りないときに折り返すかを制御します。

/* 通常の折り返し */
.normal {
  white-space: normal;
}
 
/* 改行を許可しない */
.nowrap {
  white-space: nowrap;
}
 
/* HTML上の改行・連続空白をそのまま表示 */
.pre {
  white-space: pre;
}
 
/* 改行はそのまま表示しつつ、幅で折り返す */
.pre-wrap {
  white-space: pre-wrap;
}
css
HTML上の改行幅による折り返し連続空白
normal反映しないする1つにまとめる
nowrap反映しないしない1つにまとめる
pre反映するしないそのまま
pre-wrap反映するするそのまま
pre-line反映するする1つにまとめる

ユーザーが入力した改行を表示したいコメント欄やプロフィール文では、pre-wrap がよく使われます。

.user-comment {
  white-space: pre-wrap;
}
css

overflow-wrap — 長い単語やURLを折り返す

overflow-wrap は、長い英単語・URL・ファイルパスなどが親要素からはみ出すのを防ぐために使います。

.content {
  overflow-wrap: break-word;
}
css

より強く「必要ならどこでも折り返してよい」としたい場合は anywhere も使えます。

.message {
  overflow-wrap: anywhere;
}
css

anywhere は強力ですが、通常の単語まで思わぬ位置で折り返されることがあります。本文全体には break-word、チャットメッセージや狭いカードなど崩れを防ぎたい場所には anywhere、という使い分けが現実的です。

word-break — 単語の区切り方を制御する

word-break は、単語の途中で改行してよいかを制御します。

.normal {
  word-break: normal;
}
 
.keep-all {
  word-break: keep-all;
}
 
.break-all {
  word-break: break-all;
}
css
特徴注意点
normalブラウザ標準の改行まずはこれでよい
keep-allCJK文字での任意改行を抑える日本語本文では詰まりやすい場合もある
break-all文字単位で強く折り返す英単語やURLが細かく切れる

日本語サイトでは、本文全体に word-break: break-all; を入れるのは避けましょう。日本語も英単語も不自然な位置で切れやすくなります。

line-break — 日本語の禁則処理

line-break は、日本語・中国語・韓国語などの禁則処理の厳しさを指定します。

.jp-text {
  line-break: strict;
}
css

日本語の本文で、句読点や括弧の位置をより自然に扱いたい場合に使えます。ただし、ブラウザやフォントによって見え方が変わることもあるため、本文全体に入れる前に実際の表示を確認しましょう。


実務でよく使う折り返しパターン

日本語メインの本文

日本語の長文では、自然な改行を保ちつつ、長いURLだけははみ出さないようにします。

.article-body {
  line-height: 1.8;
  overflow-wrap: break-word;
  word-break: normal;
}
css

URLやファイルパスが入るテキスト

URL・メールアドレス・ファイルパスは、途中で折り返せないとレイアウトを壊します。

.url-text {
  overflow-wrap: anywhere;
  word-break: normal;
}
css

ボタンやナビゲーション

短いUIテキストは、意図せず2行になると高さがずれて見えることがあります。

.nav-link,
.button {
  white-space: nowrap;
}
css

ただし、スマホで横幅が足りないのに nowrap を指定すると、今度は横にはみ出します。長いラベルが入る可能性がある場合は、ラベルを短くするか、アイコンとテキストの配置を見直しましょう。

ユーザー入力の改行を表示する

コメントやメモ欄では、ユーザーが入力した改行を反映したいことがあります。

.comment-body {
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
css

テキストの省略

表示領域が限られているカード・一覧・テーブルでは、長いテキストを省略することがあります。

1行で省略する

.truncate {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
css

text-overflow: ellipsis; だけでは省略されません。overflow: hidden;white-space: nowrap; をセットで指定する必要があります。

複数行で省略する

.clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
css

ニュースカードや商品カードの説明文では、2〜3行で揃えると一覧が見やすくなります。

.card-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
 
.card-description {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
css

<br> に頼りすぎない

見た目のためだけに <br> を大量に入れると、画面幅が変わったときに不自然な改行になります。文章の区切りは段落、レイアウト上の縦並びはCSSで表現しましょう。

<!-- よくない例:見た目のためだけにbrを入れる -->
<p>
  CSSで文字を整えると<br />
  読みやすいページになります
</p>
html
<!-- よい例:文として自然に書く -->
<p>CSSで文字を整えると、読みやすいページになります。</p>
html

縦に並べたい場合は、Flexboxやブロック要素を使います。

.profile {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
css

どうしてもCSSで改行を入れたい場合は、疑似要素と white-space を使う方法もあります。

.break-after::after {
  content: '\A';
  white-space: pre;
}
css

読みやすい本文スタイルの例

ここまでの内容を組み合わせると、基本の本文スタイルは次のように書けます。

body {
  font-family:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Hiragino Sans', 'Hiragino Kaku Gothic ProN',
    Meiryo, 'Noto Sans JP', sans-serif;
  font-size: 1rem;
  line-height: 1.7;
  color: #1f2937;
}
 
.article {
  max-width: 42rem;
  margin-inline: auto;
  padding-inline: 1rem;
}
 
.article h1 {
  font-size: clamp(1.75rem, 4vw, 3rem);
  line-height: 1.2;
  font-weight: 700;
}
 
.article h2 {
  margin-top: 2.5em;
  font-size: clamp(1.375rem, 2.5vw, 2rem);
  line-height: 1.3;
  font-weight: 700;
}
 
.article p {
  margin-block: 1em;
  overflow-wrap: break-word;
}
 
.article a {
  color: #2563eb;
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
css

管理画面やカードUIでは、本文より少し詰めたスタイルにすることもあります。

.card {
  font-size: 0.9375rem;
  line-height: 1.6;
}
 
.card-title {
  font-size: 1rem;
  line-height: 1.4;
  font-weight: 700;
}
 
.card-meta {
  font-size: 0.8125rem;
  line-height: 1.4;
  color: #6b7280;
}
css

よくある失敗と直し方

状態原因直し方
本文が詰まって見えるline-height が狭い1.61.8 にする
PCで文章が横に長すぎる本文幅に制限がないmax-width を指定する
スマホでURLがはみ出す長い文字列が折り返されないoverflow-wrap: break-word を入れる
ボタンの高さがばらつくラベルが折り返されているwhite-space: nowrap、文言調整
文章が変な位置で切れるword-break: break-all の使いすぎnormal + overflow-wrap に戻す
見出しが大きすぎるPC基準のサイズを固定しているclamp() で上限・下限を決める

ちゃんと使うためのポイント

  • 本文の font-size1rem を基準にし、ユーザーのブラウザ設定を尊重する
  • 本文の line-height1.61.8、長文では 1.7 前後から調整する
  • 1行が長すぎる本文には max-width を指定する
  • フォントスタックは必ず最後に sans-serif などの総称ファミリーを書く
  • 長いURLや英単語のはみ出しには、まず overflow-wrap: break-word を使う
  • word-break: break-all は局所的に使い、本文全体には指定しない
  • 省略表示は overflowwhite-spacetext-overflow をセットで指定する

次の章では、色と背景のスタイリングを学びます。

参考リンク

CSSクイズに挑戦するこの章で学んだCSSの知識を、4択クイズでアウトプットして定着させよう