【CSS】letter-spacingの使い方:emの計算と中央寄せのズレ対策

css-letter-spacing

CSSのletter-spacingは、テキストの文字間隔を調整し、デザインの美しさと可読性を大きく左右する重要なプロパティです。

本記事では、基本的な使い方や推奨される単位(em)の計算方法、実務で直面する「中央寄せのズレ」を解消するテクニックを解説します。

また、CSSに関するカテゴリーページから学びたい内容を決めたい人は、以下のCSSページをご確認ください。

目次

letter-spacingとは:基本とカーニングとの違い

Webサイトのデザインにおいて、文字の読みやすさや見出しの洗練された美しさを決める重要な要素が「文字間隔」です。

letter-spacingは、文字間隔をコントロールする基本的なプロパティです。

ここでは、letter-spacingとは何か、現場で意識される「字送り」と「カーニング」の違いを解説します。

letter-spacingとは:基本とカーニングとの違い
  • 文字間隔(字送り)を調整する役割とデフォルト値
  • letter-spacingfont-kerningの違い

文字間隔(字送り)を調整する役割とデフォルト値

letter-spacingの役割は、テキスト全体に対して均等に文字と文字の間のスペース(字送り)を広げたり、狭めたりすることです。

何も指定していない状態のデフォルト値はnormalです。

これは、使用しているフォントが本来持っている標準的な文字間隔が適用される状態を指します。

ここから、empxなどの単位を使って間隔を微調整していきます。

文字間隔を指定する際は、「letter-spacingにはpxを使わず、文字サイズに連動する相対単位であるemを使うこと」です。

例えばletter-spacing: 0.1em;と指定すれば、文字サイズが大きくても小さくても、「文字の大きさの10%分の間隔」を保ってくれます。

⭕️ 文字間隔は「px」ではなく、文字サイズに連動する「em」を使え!

デフォルト (normal)
標準の詰まり具合

美しいタイポグラフィ

❌ 罠 (px指定)
文字が小さくなると間隔だけ広すぎる

美しいタイポグラフィ

⭕️ 成功 (em指定)
文字サイズに連動して美しい比率を保つ

美しいタイポグラフィ

/* ❌ px で絶対値を指定してしまう */
.text-fail {
  letter-spacing: 4px; /* 🚨 スマホで文字が小さくなった時に破綻する! */
}

/* ⭕️ em を使って文字サイズに対する「割合」で指定する */
.text-success {
  letter-spacing: 0.2em; /* 💡 常にフォントサイズの20%分の間隔を保つ */
}
HTMLコード表示
<div class="letter-spacing-basic-layout-wrapper">
  
  <p class="letter-spacing-basic-caption">⭕️ 文字間隔は「px」ではなく、文字サイズに連動する「em」を使え!</p>

  <div class="letter-spacing-basic-demo-area">
    
    <div class="letter-spacing-basic-item">
      <p class="letter-spacing-basic-label">デフォルト (normal)<br><small>標準の詰まり具合</small></p>
      <p class="spacing-box is-default">
        美しいタイポグラフィ
      </p>
    </div>

    <div class="letter-spacing-basic-item">
      <p class="letter-spacing-basic-label" style="color:#dc3545;">❌ 罠 (px指定)<br><small>文字が小さくなると間隔だけ広すぎる</small></p>
      <div class="responsive-simulator">
        <p class="spacing-box is-bad-px" style="font-size: 12px;">
          美しいタイポグラフィ
        </p>
      </div>
    </div>

    <div class="letter-spacing-basic-item">
      <p class="letter-spacing-basic-label" style="color:#0d6efd;">⭕️ 成功 (em指定)<br><small>文字サイズに連動して美しい比率を保つ</small></p>
      <div class="responsive-simulator">
        <p class="spacing-box is-good-em" style="font-size: 12px;">
          美しいタイポグラフィ
        </p>
      </div>
    </div>

  </div>

  <div class="letter-spacing-basic-code-area">
    <span class="hl-comment">/* ❌ px で絶対値を指定してしまう */</span><br>
    <span class="hl-blue">.text-fail</span> {<br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">4px;</span> <span class="hl-comment">/* 🚨 スマホで文字が小さくなった時に破綻する! */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ em を使って文字サイズに対する「割合」で指定する */</span><br>
    <span class="hl-blue">.text-success</span> {<br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">0.2em;</span> <span class="hl-comment">/* 💡 常にフォントサイズの20%分の間隔を保つ */</span><br>
    }
  </div>

</div>
CSSコード表示
.letter-spacing-basic-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.letter-spacing-basic-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.letter-spacing-basic-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.letter-spacing-basic-item {
  width: 100%;
}

.letter-spacing-basic-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.5;
}

/* テキストボックス共通設定 */
.spacing-box {
  background-color: #fff;
  padding: 15px;
  border-radius: 6px;
  border: 1px solid #dee2e6;
  font-weight: bold;
  color: #333;
  /* デフォルトは少し大きめにしておく */
  font-size: 20px; 
}

/* スマホ表示をシミュレートする箱 */
.responsive-simulator {
  background-color: #f1f3f5;
  padding: 10px;
  border-radius: 4px;
  border-left: 3px solid #ced4da;
}

/* =💡 デフォルト= */
.is-default {
  letter-spacing: normal;
}

/* =❌ 罠:px指定(フォントが小さくなると間隔が広すぎる)= */
.is-bad-px {
  letter-spacing: 5px; /* 絶対値で固定されてしまう */
}

/* =⭕️ 正解:em指定(フォントサイズに連動して綺麗に縮む)= */
.is-good-em {
  letter-spacing: 0.25em; /* 常に文字の25%の間隔 */
}

/* =コード解説エリア= */
.letter-spacing-basic-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

フォントサイズの指定について詳しく知りたい人は「【HTML】フォントサイズ(文字)の指定:px・rem・em・%の変更と自動調整」を一読ください。

letter-spacingとfont-kerningの違い

文字間隔を極める上で、重要なのが「letter-spacing」と「font-kerning」の違いです。

  • letter-spacing(字送り)
    文字の形に関係なく、「すべての文字に対して均等に」指定した分のスペースを追加します。
  • font-kerning(カーニング)
    フォント自体に組み込まれている「文字のペア(AとV、Tとoなど)」の情報を読み取り、「特定の文字の組み合わせの時だけ、不自然な隙間を自動で詰める」処理を行います。

日本語のWebデザインにおいては、特定のひらがなやカタカナ(「ト」や「ノ」など)の間にできる不自然な隙間を調整するプロパティとしてfont-feature-settings: "palt";が使われます。

美しいタイポグラフィを実現するには、「font-feature-settings: "palt";で文字の形に応じた『自動カーニング』を効かせて不自然な隙間を消し、見出しの装飾として全体を広げたい場合のみletter-spacingをプラスの値で使うこと」です。

letter-spacingにマイナスの値を使うのは、特殊なデザイン要件がない限り避けるのが安全です。

⭕️ 全体を広げる「letter-spacing」と、隙間を詰める「カーニング」

❌ 罠(マイナスのletter-spacing)
全体が詰まりすぎて文字が重なる

「トマト」のサラダ

デフォルト(何もなし)
「ト」と「マ」の間に不自然な隙間がある

「トマト」のサラダ

⭕️ 成功(paltで自動カーニング)
文字の形に合わせて綺麗に詰まる

「トマト」のサラダ

/* ❌ スカスカを直そうとしてマイナスの letter-spacing を使う */
.text-fail {
  letter-spacing: -0.1em; /* 🚨 詰まらなくていい部分まで重なって潰れる! */
}

/* ⭕️ 日本語の不自然な隙間は palt(自動カーニング)で美しく詰める */
.text-success {
  font-feature-settings: “palt” 1; /* 💡 文字の形を認識して、余分な隙間だけを自動で詰める */
}
HTMLコード表示
<div class="letter-kerning-layout-wrapper">
  
  <p class="letter-kerning-caption">⭕️ 全体を広げる「letter-spacing」と、隙間を詰める「カーニング」</p>

  <div class="letter-kerning-demo-area">
    
    <div class="letter-kerning-item">
      <p class="letter-kerning-label" style="color:#dc3545;">❌ 罠(マイナスのletter-spacing)<br><small>全体が詰まりすぎて文字が重なる</small></p>
      <p class="kerning-box is-bad-negative">
        「トマト」のサラダ
      </p>
    </div>

    <div class="letter-kerning-item">
      <p class="letter-kerning-label">デフォルト(何もなし)<br><small>「ト」と「マ」の間に不自然な隙間がある</small></p>
      <p class="kerning-box is-normal">
        「トマト」のサラダ
      </p>
    </div>

    <div class="letter-kerning-item">
      <p class="letter-kerning-label" style="color:#0d6efd;">⭕️ 成功(paltで自動カーニング)<br><small>文字の形に合わせて綺麗に詰まる</small></p>
      <p class="kerning-box is-good-palt">
        「トマト」のサラダ
      </p>
    </div>

  </div>

  <div class="letter-kerning-code-area">
    <span class="hl-comment">/* ❌ スカスカを直そうとしてマイナスの letter-spacing を使う */</span><br>
    <span class="hl-blue">.text-fail</span> {<br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">-0.1em;</span> <span class="hl-comment">/* 🚨 詰まらなくていい部分まで重なって潰れる! */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 日本語の不自然な隙間は palt(自動カーニング)で美しく詰める */</span><br>
    <span class="hl-blue">.text-success</span> {<br>
      <span class="hl-green">font-feature-settings:</span> <span class="hl-red">"palt" 1;</span> <span class="hl-comment">/* 💡 文字の形を認識して、余分な隙間だけを自動で詰める */</span><br>
    }
  </div>

</div>
CSSコード表示
.letter-kerning-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.letter-kerning-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.letter-kerning-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.letter-kerning-item {
  width: 100%;
}

.letter-kerning-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.5;
}

/* テキストボックス共通設定 */
.kerning-box {
  background-color: #fff;
  padding: 15px;
  border-radius: 6px;
  border: 1px solid #dee2e6;
  font-weight: 500;
  color: #333;
  font-size: 24px;
  font-family: "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif; /* カーニングが分かりやすいフォント */
}

/* =❌ 罠:マイナスのletter-spacing= */
.is-bad-negative {
  letter-spacing: -0.15em; /* 無理やり詰めると文字がくっつく */
}

/* =💡 デフォルト= */
.is-normal {
  letter-spacing: normal;
}

/* =⭕️ 正解:自動カーニング(palt)= */
.is-good-palt {
  font-feature-settings: "palt" 1; /* 日本語のプロポーショナルメトリクスを有効化 */
}

/* =コード解説エリア= */
.letter-kerning-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

単位の選び方とFigmaからの変換・計算

CSSで文字間隔を指定する際、単位には何を使えば良いのでしょうか?

また、デザイナーから上がってきたデザインデータの数値をCSSに記述しても見た目が一致しないことが多々あります。

ここでは、実務において推奨される単位の選び方とデザインツールの数値をCSS用に変換する計算の手法について解説します。

単位の選び方とFigmaからの変換・計算
  • pxや%ではなくemを使うべき理由とパーセント指定の可否
  • Figma・XD・Photoshopの数値をCSSに変換する計算式

pxや%ではなくemを使うべき理由とパーセント指定の可否

CSSのletter-spacingに指定できる単位にはpxemremなどがありますが、実務で圧倒的に推奨されるのがemです。

pxで指定してしまうと、レスポンシブデザインで文字サイズが変わった時に間隔の比率が狂います。

emは「現在のフォントサイズに対する倍率(1em = 1文字分)」を意味するため、文字サイズが変化しても常にバランスを保つことができます。

文字間隔の指定プロパティを書く際は、「パーセント(%)で考えた数値を『100』で割り、単位を『em』にして記述すること」です。

例えば、10%なら0.1em、5%なら0.05emと変換します。

※SWELLのCSS干渉によってデモ用は同じ状態ですが、本来は変化しています。

⭕️ %は使えない!必ず「100で割ってemにする」こと

❌ 罠(%を指定)
無効になり、間隔が空かない

デザイン

⭕️ 成功(emに変換)
10%空けたいなら 0.1em

デザイン

/* ❌ 直感で % を使ってしまう */
.text-fail {
  letter-spacing: 10%; /* 🚨 CSSでは無効な単位!無視される */
}

/* ⭕️ 10%なら 10 ÷ 100 = 0.1em */
.text-success {
  letter-spacing: 0.1em; /* 💡 これが正解 */
}
HTMLコード表示
<div class="spacing-unit-layout-wrapper">
  
  <p class="spacing-unit-caption">⭕️ %は使えない!必ず「100で割ってemにする」こと</p>

  <div class="spacing-unit-demo-area">
    
    <div class="spacing-unit-item">
      <p class="spacing-unit-label" style="color:#dc3545;">❌ 罠(%を指定)<br><small>無効になり、間隔が空かない</small></p>
      <p class="unit-box is-bad-percent">
        デザイン
      </p>
    </div>

    <div class="spacing-unit-item">
      <p class="spacing-unit-label" style="color:#0d6efd;">⭕️ 成功(emに変換)<br><small>10%空けたいなら 0.1em</small></p>
      <p class="unit-box is-good-em">
        デザイン
      </p>
    </div>

  </div>

  <div class="spacing-unit-code-area">
    <span class="hl-comment">/* ❌ 直感で % を使ってしまう */</span><br>
    <span class="hl-blue">.text-fail</span> {<br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">10%;</span> <span class="hl-comment">/* 🚨 CSSでは無効な単位!無視される */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 10%なら 10 ÷ 100 = 0.1em */</span><br>
    <span class="hl-blue">.text-success</span> {<br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">0.1em;</span> <span class="hl-comment">/* 💡 これが正解 */</span><br>
    }
  </div>

</div>
CSSコード表示
.spacing-unit-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.spacing-unit-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.spacing-unit-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.spacing-unit-item {
  width: 100%;
}

.spacing-unit-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.5;
}

/* テキストボックス共通設定 */
.unit-box {
  background-color: #fff;
  padding: 15px;
  border-radius: 6px;
  border: 1px solid #dee2e6;
  font-weight: bold;
  color: #333;
  font-size: 24px;
}

/* =❌ 罠:%指定(無効化されて詰まったままになる)= */
.is-bad-percent {
  letter-spacing: 20%; 
}

/* =⭕️ 正解:em指定(綺麗に間隔が空く)= */
.is-good-em {
  letter-spacing: 0.2em;
}

/* =コード解説エリア= */
.spacing-unit-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

Figma・XD・Photoshopの数値をCSSに変換する計算式

コーディングの現場で混乱を招くのが、デザインツールからの値の移植です。

PhotoshopやAdobe XD・Figmaでは、文字間隔を表す単位や基準がそれぞれ異なります。

これらをそのままCSSに書いても、デザイン通りの見た目にはなりません。

ツールごとの変換計算式を丸暗記(またはメモ)し、emに変換して記述するのがよいです。

  1. Photoshop / Illustrator / Adobe XD の場合
    これらのツールは「1000分の1em(パーミル)」を基準にしています。
    • 計算式:『ツールの数値 ÷ 1000 = em』
    • 例:トラッキングが50なら50 ÷ 1000 = 0.05em
  2. Figma(パーセント表示)の場合:
    • 計算式:『ツールの数値 ÷ 100 = em』
    • 例:Letter spacingが10%なら10 ÷ 100 = 0.1em
  3. Figma(ピクセル表示)の場合:
    • 計算式:『ツールの数値 ÷ フォントサイズ = em』
    • 例:Letter spacingが2px、フォントサイズが16pxなら2 ÷ 16 = 0.125em

⭕️ ツールの数値をそのまま書くな!必ず「1000」か「100」で割れ!

❌ 罠(数値をそのまま)
トラッキング「100」を100pxにする悲劇

見えない

⭕️ 成功(PS/XDの変換)
100 ÷ 1000 = 0.1em

美しい間隔

/* ❌ PhotoshopのVA(100)を見て、そのまま100pxにする */
.text-fail {
  letter-spacing: 100px; /* 🚨 文字が彼方へ吹き飛ぶ! */
}

/* ⭕️ Photoshop/XDなら 1000 で割る! */
.text-success {
  letter-spacing: 0.1em; /* 💡 100 ÷ 1000 = 0.1em */
}
HTMLコード表示
<div class="spacing-calc-layout-wrapper">
  
  <p class="spacing-calc-caption">⭕️ ツールの数値をそのまま書くな!必ず「1000」か「100」で割れ!</p>

  <div class="spacing-calc-demo-area">
    
    <div class="spacing-calc-item">
      <p class="spacing-calc-label" style="color:#dc3545;">❌ 罠(数値をそのまま)<br><small>トラッキング「100」を100pxにする悲劇</small></p>
      
      <div style="overflow: hidden; border: 1px solid #dee2e6; border-radius: 6px; padding: 10px; background: #fff;">
        <p class="calc-box is-bad-calc">
          見えない
        </p>
      </div>
    </div>

    <div class="spacing-calc-item">
      <p class="spacing-calc-label" style="color:#0d6efd;">⭕️ 成功(PS/XDの変換)<br><small>100 ÷ 1000 = 0.1em</small></p>
      
      <div style="border: 1px solid #dee2e6; border-radius: 6px; padding: 10px; background: #fff;">
        <p class="calc-box is-good-calc">
          美しい間隔
        </p>
      </div>
    </div>

  </div>

  <div class="spacing-calc-code-area">
    <span class="hl-comment">/* ❌ PhotoshopのVA(100)を見て、そのまま100pxにする */</span><br>
    <span class="hl-blue">.text-fail</span> {<br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">100px;</span> <span class="hl-comment">/* 🚨 文字が彼方へ吹き飛ぶ! */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ Photoshop/XDなら 1000 で割る! */</span><br>
    <span class="hl-blue">.text-success</span> {<br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">0.1em;</span> <span class="hl-comment">/* 💡 100 ÷ 1000 = 0.1em */</span><br>
    }
  </div>

</div>
CSSコード表示
.spacing-calc-layout-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.spacing-calc-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.spacing-calc-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.spacing-calc-item {
  width: 100%;
}

.spacing-calc-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.5;
}

/* テキストボックス共通設定 */
.calc-box {
  font-weight: bold;
  color: #333;
  font-size: 18px;
  margin: 0;
  white-space: nowrap; /* 折り返し禁止 */
}

/* =❌ 罠:数値をそのままpxにする(文字が吹き飛ぶ)= */
.is-bad-calc {
  letter-spacing: 100px; 
}

/* =⭕️ 正解:1000で割ってemにする= */
.is-good-calc {
  letter-spacing: 0.1em;
}

/* =コード解説エリア= */
.spacing-calc-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

最後の文字の余白と中央寄せがズレる問題

letter-spacingを使って見出しやボタンの文字間隔を広げた際、多くのコーダーが「あれ?なんか文字が全体的に左に寄っている気がする…」という違和感に直面します。

実は目の錯覚ではなく、CSSの仕様そのものが原因で起きている明確な「ズレ」です。

ここでは、実務で対応を迫られる「最後の文字の余白問題」と解決する必須テクニックを解説します。

最後の文字の余白と中央寄せがズレる問題
  • 文字間隔を広げると最後の文字の右側にも余白がつく仕様
  • text-indentで相殺して中央寄せのズレを直す

文字間隔を広げると最後の文字の右側にも余白がつく仕様

letter-spacingを適用した時、ブラウザは「文字と文字の間にスペースを入れる」のではなく、「それぞれの文字の右側にスペースを追加する」という処理を行います。

つまり、必然的に一番最後の文字の右側にも余白がついてしまいます。

文字間隔をデザインする際は、「letter-spacingは『文字の右側』に余白をつけるプロパティであるという事実を意識し、背景色や枠線を伴う要素ではズレを補正する前提でコーディングすること」です。

⭕️ letter-spacingは「すべての文字の右側」に余白をつける!

通常のテキスト
(一見すると気づきにくい)

MENU

❌ 罠(背景色をつける)
右側だけ余白が広く、不格好になる

MENU
/* ❌ 余白の仕様を知らずに背景色をつけてしまう */
.text-fail {
  letter-spacing: 0.5em; /* 🚨 「U」の右側にも 0.5em の余白がついてしまう! */
  background-color: #333; /* 🚨 ここで右側の余白の広さがバレる */
}
HTMLコード表示
<div class="ls-offset-wrapper">
  
  <p class="ls-offset-caption">⭕️ letter-spacingは「すべての文字の右側」に余白をつける!</p>

  <div class="ls-offset-demo-area">
    
    <div class="ls-offset-item">
      <p class="ls-offset-label">通常のテキスト<br><small>(一見すると気づきにくい)</small></p>
      <div class="ls-offset-box-transparent">
        <span class="ls-offset-text is-bad-spacing">MENU</span>
      </div>
    </div>

    <div class="ls-offset-item">
      <p class="ls-offset-label ls-label-danger">❌ 罠(背景色をつける)<br><small>右側だけ余白が広く、不格好になる</small></p>
      <div class="ls-offset-box">
        <span class="ls-offset-text is-bad-spacing has-bg">MENU</span>
      </div>
    </div>

  </div>

  <div class="ls-offset-code-area">
    <span class="hl-comment">/* ❌ 余白の仕様を知らずに背景色をつけてしまう */</span><br>
    <span class="hl-blue">.text-fail</span> {<br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">0.5em;</span> <span class="hl-comment">/* 🚨 「U」の右側にも 0.5em の余白がついてしまう! */</span><br>
      <span class="hl-green">background-color:</span> <span class="hl-red">#333;</span> <span class="hl-comment">/* 🚨 ここで右側の余白の広さがバレる */</span><br>
    }
  </div>

</div>
CSSコード表示
.ls-offset-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.ls-offset-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.ls-offset-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.ls-offset-item {
  width: 100%;
}

.ls-offset-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.5;
}

.ls-label-danger {
  color: #dc3545;
}

/* 💡 箱の設定 */
.ls-offset-wrapper .ls-offset-box-transparent,
.ls-offset-wrapper .ls-offset-box {
  padding: 20px;
  border-radius: 6px;
  text-align: left !important;
}
.ls-offset-wrapper .ls-offset-box-transparent {
  background-color: transparent;
}
.ls-offset-wrapper .ls-offset-box {
  background-color: #fff;
  border: 1px solid #dee2e6;
}

/* 💡 テキスト本体の設定 */
.ls-offset-wrapper .ls-offset-text {
  font-weight: bold;
  font-size: 24px;
  color: #333;
  margin: 0 !important;
  display: inline-block !important; /* 背景色が文字幅にフィットするように */
}

/* 背景色をつけて分かりやすくするクラス */
.ls-offset-wrapper .has-bg {
  background-color: #0dccea;
  color: #fff;
  padding: 5px; /* 上下の余白 */
}

/* =❌ 罠:最後の文字の右側に余白がついてしまう= */
.ls-offset-wrapper .is-bad-spacing {
  letter-spacing: 0.5em !important; 
}

/* =コード解説エリア= */
.ls-offset-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

text-indentで相殺して中央寄せのズレを直す

「最後の文字の右側につく余白」が最も悪さをするのが、テキストを中央寄せにしたい場面です。

右側に余分なスペースがある状態で要素を中央に配置すると、視覚的には「左に寄って(ズレて)」見えてしまいます。

これを直すために、標準的に使われている手法がtext-indentプロパティを使って左側にも同じだけの余白を作り、左右のバランスを相殺するテクニックです。

中央寄せのズレを直すには、「letter-spacingを指定した要素には、全く同じ値のtext-indent(1行目の字下げ)をセットで記述すること」です。

これにより、最初の文字の左側にも同じだけのスペースが生まれ、完全なシンメトリー(左右対称)となり、中央寄せが実現します。

⭕️ 中央寄せのズレは「letter-spacingと同値のtext-indent」で相殺しろ!

❌ 罠(補正なしの中央寄せ)
右の余白のせいで、文字全体が左にズレて見える

BUTTON

⭕️ 成功(text-indentで補正)
左右の余白が均等になり、完璧な中央配置になる

BUTTON
/* ❌ 文字間隔を広げたままボタンを中央寄せにする */
.btn-fail {
  text-align: center;
  letter-spacing: 0.5em; /* 🚨 右側の余白が邪魔をして左にズレて見える */
}

/* ⭕️ 全く同じ値の text-indent を指定して左右対称にする! */
.btn-success {
  text-align: center;
  letter-spacing: 0.5em;
  text-indent: 0.5em; /* 💡 左側にも0.5emの余白が生まれ、完璧に中央になる */
}
HTMLコード表示
<div class="ls-center-wrapper">
  
  <p class="ls-center-caption">⭕️ 中央寄せのズレは「letter-spacingと同値のtext-indent」で相殺しろ!</p>

  <div class="ls-center-demo-area">
    
    <div class="ls-center-item">
      <p class="ls-center-label ls-label-danger">❌ 罠(補正なしの中央寄せ)<br><small>右の余白のせいで、文字全体が左にズレて見える</small></p>
      <div class="ls-center-box">
        <div class="center-line"></div>
        <span class="ls-center-btn is-bad-center">BUTTON</span>
      </div>
    </div>

    <div class="ls-center-item">
      <p class="ls-center-label ls-label-primary">⭕️ 成功(text-indentで補正)<br><small>左右の余白が均等になり、完璧な中央配置になる</small></p>
      <div class="ls-center-box">
        <div class="center-line is-blue"></div>
        <span class="ls-center-btn is-good-center">BUTTON</span>
      </div>
    </div>

  </div>

  <div class="ls-center-code-area">
    <span class="hl-comment">/* ❌ 文字間隔を広げたままボタンを中央寄せにする */</span><br>
    <span class="hl-blue">.btn-fail</span> {<br>
      <span class="hl-green">text-align:</span> <span class="hl-red">center;</span><br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">0.5em;</span> <span class="hl-comment">/* 🚨 右側の余白が邪魔をして左にズレて見える */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 全く同じ値の text-indent を指定して左右対称にする! */</span><br>
    <span class="hl-blue">.btn-success</span> {<br>
      <span class="hl-green">text-align:</span> <span class="hl-red">center;</span><br>
      <span class="hl-green">letter-spacing:</span> <span class="hl-red">0.5em;</span><br>
      <span class="hl-green">text-indent:</span> <span class="hl-red">0.5em;</span> <span class="hl-comment">/* 💡 左側にも0.5emの余白が生まれ、完璧に中央になる */</span><br>
    }
  </div>

</div>
CSSコード表示
.ls-center-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.ls-center-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.ls-center-demo-area {
  display: flex;
  flex-direction: column;
  gap: 30px;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.ls-center-item {
  width: 100%;
}

.ls-center-label {
  font-size: 13px;
  font-weight: bold;
  margin-bottom: 10px;
  line-height: 1.5;
}

.ls-label-danger { color: #dc3545; }
.ls-label-primary { color: #0d6efd; }

/* 💡 コンテナの設定 */
.ls-center-wrapper .ls-center-box {
  background-color: #fff;
  padding: 30px 20px;
  border-radius: 6px;
  border: 1px solid #dee2e6;
  text-align: center !important; /* 中央寄せ */
  position: relative; /* 基準線のための指定 */
}

/* 中央を示す絶対配置の基準線(視覚的ガイド) */
.ls-center-wrapper .center-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  background-color: rgba(220, 53, 69, 0.5); /* 赤い点線 */
  border-left: 1px dashed #dc3545;
  z-index: 1;
}
.ls-center-wrapper .center-line.is-blue {
  background-color: rgba(13, 110, 253, 0.5);
  border-left: 1px dashed #0d6efd;
}

/* 💡 ボタン本体の設定 */
.ls-center-wrapper .ls-center-btn {
  position: relative;
  z-index: 2; /* 基準線より手前に表示 */
  display: inline-block !important;
  background-color: #333;
  color: #fff;
  font-weight: bold;
  font-size: 18px;
  padding: 15px 30px;
  border-radius: 30px;
  margin: 0 !important;
  white-space: nowrap !important;
}

/* =❌ 罠:補正なし(文字が左に寄って見える)= */
.ls-center-wrapper .is-bad-center {
  letter-spacing: 0.5em !important; 
  /* text-indentを指定していないため、ボタン内の文字が左にズレる */
}

/* =⭕️ 正解:text-indentで補正(完璧な中央配置)= */
.ls-center-wrapper .is-good-center {
  letter-spacing: 0.5em !important; 
  /* 💡 全く同じ値をtext-indentに指定して相殺する */
  text-indent: 0.5em !important; 
}

/* =コード解説エリア= */
.ls-center-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

まとめ

分かりやすいようにまとめを記載します。

本記事のまとめ
  • 役割
    テキスト全体の文字と文字の間隔(字送り)を均等に調整する。
  • 初期値
    normal(フォント標準の文字間隔)。
  • 推奨単位
    レスポンシブ環境で比率を保つため、pxではなくemを使用する。
  • パーセント指定
    %による指定はCSSの仕様上無効(無視される)となるため使用不可。
  • ツールの値変換
    PhotoshopやXDのトラッキング値は「1000で割る」、Figmaの%値は「100で割る」ことでemに変換できる。
  • カーニングとの違い
    均等に間隔を操作するletter-spacingに対し、不自然な隙間を文字の形に合わせて詰める場合はfont-feature-settings: "palt";を使用する。
  • 仕様上の注意
    余白は「各文字の右側」に追加されるため、最後の文字の右側にも余白が発生する。
  • 中央寄せのズレ補正
    letter-spacingを指定した要素を中央寄せにする際は、左にズレて見えるのを防ぐため、同じ値のtext-indentを指定して左右の余白を相殺する。

よくある質問(FAQ)

CSSで文字間隔を指定するにはどうすればいいですか?

CSSのletter-spacingプロパティを使用します。

例えば、letter-spacing: 0.1em;のように記述することで、テキスト全体の文字と文字の間隔を均等に広げることができます。

間隔を詰めたい場合は-0.05emのようにマイナスの値を指定することも可能ですが、文字が重なって読みづらくなることがあるため注意が必要です。

指定しない場合の初期値はnormalです。

letter-spacingの単位はpxとemのどちらを使うべきですか?

実務では「em」が推奨されます。

px は絶対値であるため、スマホ表示などでフォントサイズ(font-size)が小さくなった際にも文字間隔だけが固定されたままになり、スカスカで不格好なデザインになってしまいます。

一方emは「現在の文字サイズに対する割合」で間隔が決まるため、文字が伸縮しても常に美しい比率を保つことができます。

PhotoshopやFigmaの文字間隔をCSSに変換するにはどう計算しますか?

デザインツールによって基準となる単位が異なるため、以下の計算式でemに変換します。

  • Photoshop / Adobe XD(トラッキング)
    ツールの数値を「1000」で割ります。(例:100なら0.1em
  • Figma(%指定)
    ツールの数値を「100」で割ります。(例:10%なら0.1em
    数値をそのままpx%としてCSSに記述すると、レイアウトが崩れる原因になります。
letter-spacingを指定すると、中央寄せがズレてしまうのはなぜですか?

CSSの仕様上、letter-spacingの余白は「それぞれの文字の右側」に追加されるため、一番最後の文字の右側にも不要なスペースができてしまうからです。

この右側の余白のせいで、全体が少し左に寄って見えます。

これを直して中央寄せにするには、例えば同じ要素にtext-indent: 0.1em;を指定し、最初の文字の左側にも同じ余白を作って相殺するテクニックが必須です。

letter-spacingにパーセント(%)は使えますか?

いいえ、使えません。

CSSの仕様においてletter-spacing%はサポートされていないため、指定しても無効な値としてブラウザに無視され、文字間隔は変化しません。

Figmaなどで「10%」と指定されている場合は、そのまま書くのではなく「100で割ってemに変換(= 0.1em)」してから記述してください。

この記事を書いた人

sugiのアバター sugi Site operator

【経歴】玉川大学工学部卒業→新卒SIer企業入社→2年半後に独立→プログラミングスクール運営/受託案件→フリーランスエンジニア&SEOコンサル→Python特化のコンテンツサイトJob Code&UIコピペサイトCode Stock運営中

目次