タグアーカイブ letter-spacing

CSSのletter-spacingでテキスト表示を切り替える実装テクニック

CSSでテキストを一文字ずつ表示したり、特定の単語を切り替えたりする演出は、直感的には難しいものだ。::nth-letter()のような仮想的なセレクタがあれば楽だが、現状のCSS仕様には存在しない。しかし、letter-spacingプロパティの負の値とcolor: transparentを組み合わせることで、限定的ながらも文字単位の表示制御が実現できる。

CSS-Tricksの記事では、このテクニックを使ってチェックボックス操作によるラベル切り替えや、アクロニムの全文表示といった実装例が紹介されている。本記事ではその仕組みと実装手順を掘り下げ、日本国内のWeb制作現場での活用ポイントを考察する。

letter-spacingの基本と隠しテキストの仕組み

letter-spacingの基本と隠しテキストの仕組み

正の値と負の値の効果

letter-spacingプロパティは、各文字の右側に追加されるスペースを調整する。正の値では文字間隔が広がり、負の値ではグリフボックスの幅が縮まる。値を十分に小さく設定すると、隣り合う文字同士が重なり合い、最終的には一箇所に集約された状態になる。

この状態でテキストの色をtransparentに指定すれば、ユーザーからは完全に見えなくなる。逆に正の値に戻すと文字が再び分離して表示される。この性質をアニメーションと組み合わせることで、表示と非表示を切り替える演出が可能になる。

負のletter-spacingで重なる文字
サンプルテキスト
letter-spacing:-0.5ch の状態。文字同士が接近し、重なりが生じている
正の値に戻した読みやすい状態
サンプルテキスト
letter-spacing:0ch (デフォルト)。文字が分離し可読性が戻っている

上記のデモでは、負の値によって文字が詰まったビジュアルと、正の値(0)で通常表示に戻る様子を並べている。実際にはtransitionプロパティを加えることで、この変化をなめらかに動かせる。

ch単位を使う理由

文字の重なり具合を指定する負の値には、ch単位が特に相性が良い。1chは数字の「0」のグリフ幅に相当する相対単位であり、フォントファミリーやサイズに応じて自動調整される。これにより、使用する書体が変わっても一貫した重なり効果を維持しやすくなる。

例えばletter-spacing: -1chを指定すると、各文字が1文字分ずつ左に詰められ、理論上は完全に重なる。実際にはフォントのデザインやカーニングによって微妙なズレが生じることもあるが、調整の起点として扱いやすい。

チェックボックスと組み合わせたテキスト切り替え

チェックボックスと組み合わせたテキスト切り替え

HTMLとCSSのコード例

このテクニックを応用すると、チェックボックスの状態に応じてラベルテキストを動的に切り替えるUIを作成できる。以下は、クリックによって「入会する」のような案内文が「ようこそ」メッセージに変化するパターンだ。

input:checked + label .initial-text {
  letter-spacing: -2ch;
  text-indent: -1.5ch;
  transition: 0.4s letter-spacing cubic-bezier(.8, -.5, .2, 1.4), 
              0.1s text-indent;
}

input:checked + label .revealed-text {
  letter-spacing: 0ch;
  color: #1a1a2e;
  transition:
    0.4s letter-spacing cubic-bezier(.8, -.5, .2, 1.4) 0.3s, 
    0.8s color 0.4s;
}
非チェック状態(Before)
会員登録して特典を受け取る
登録完了しました
最初の案内テキストが表示され、完了メッセージは重なって見えない
チェック状態(After)
会員登録して特典を受け取る
登録完了しました
最初のテキストが左へスライドし、新しいメッセージが表示される

デモではoverflow: clipが適用されたコンテナ内で、一方のテキストがletter-spacing: -2chtext-indentで左に押し出され、もう一方が通常の間隔に戻る仕組みだ。実際の環境ではチェックボックス操作によりこれらのプロパティが切り替わる。

アニメーションの調整ポイント

CSS-Tricksの著者Carlo Daniele氏の実装例では、cubic-bezier(.8, -.5, .2, 1.4)というイージングが使われている。この曲線は、変化の途中で値が目標値を超えて戻る「バウンス」効果を生み出し、文字が勢いよく離れるような動きを演出する。

また、2つのテキストのtransition-delayをずらすことで、古いテキストが消え始めてから新しいテキストが現れるまでの間に自然なオーバーラップが作られている。この遅延調整は、ユーザーが違和感なく情報の切り替わりを認識できるようにするための工夫だ。

アクロニムの全文表示テクニック

アクロニムの全文表示テクニック

::first-letterの活用

UNICEF(United Nations International Children’s Emergency Fund)のようなアクロニムを題材に、各単語の最初の文字だけを常に表示し、ホバー時に残りの文字を出現させるテクニックが紹介されている。

.acronym-word {
  letter-spacing: -1ch;
  color: transparent;
}

.acronym-word::first-letter {
  color: #1a1a2e;
}

figure:hover + .acronym .acronym-word {
  letter-spacing: 0ch;
  color: #1a1a2e;
  transition: letter-spacing 0.4s cubic-bezier(.8, -.5, .2, 1.4);
}
未ホバー時(Before)
United Nations International Children’s Emergency Fund
U N I C E F
各単語の頭文字(U N I C E F)だけが表示されている
ホバー時(After)
United Nations International Children’s Emergency Fund
完全な単語が展開され、アクロニムの正式名称が読める

::first-letter疑似要素で頭文字だけを黒く表示し、残りの文字はcolor: transparentで不可視にしておく。ホバーイベントでletter-spacingを0に戻すと、すべての文字が可視状態で展開される仕組みだ。

実装の注意点

このパターンでは、各単語を個別の<span>で囲む必要がある。単一のテキストブロックに対して::first-letterは最初の1文字にしか適用されないからだ。UNICEFの例のように6つの単語があれば、6つの要素でマークアップすることになる。

また、スクリーンリーダーはcolor: transparentのテキストも読み上げるため、アクセシビリティ面では注意が必要だ。このテクニックはあくまでビジュアル面の演出であり、情報の一次的な伝達手段としては適さない。重要なテキストはaria-labelなどで別途提供するか、この効果を装飾的な目的に限定するのが安全だ。

実務での活用アイデア

実務での活用アイデア

このテクニックは、以下のようなシーンで効果を発揮する。

申し込みボタンのラベル切り替え
「送信する」から「送信完了」へ、ボタン内のテキストをスムーズに変化させる。ユーザーの操作完了を直感的に伝えられる。
用語集やFAQのアクロニム展開
「SEO」にカーソルを合わせると「Search Engine Optimization」が表示される仕掛け。補足情報を必要なときだけ見せられる。
ナビゲーションの状態表示
現在位置を示すテキストを他の項目と視覚的に区別し、アクティブ項目を強調する効果として使える。

いずれも、派手なアニメーションライブラリを使わずにCSSだけで完結するのが利点だ。パフォーマンス面でもJavaScriptによるDOM操作より軽量で、メインスレッドへの負荷が少ない。

制約と対応ブラウザ

制約と対応ブラウザ

letter-spacingのアニメーションは主要なモダンブラウザで広くサポートされている。ただし、cubic-bezierによるバウンス効果は、イージングの値によっては環境間で微妙な見え方の差が出ることがある。

また、ch単位はフォントの「0」の幅に依存するため、和文フォントと欧文フォントが混在する日本語サイトでは、想定よりも文字の重なり方が異なるケースがある。実装時は実際のフォントスタックで表示確認を行うことが重要だ。

この記事のポイント

  • letter-spacingの負値とcolor: transparentを組み合わせると、文字を一箇所に重ねて不可視にできる
  • チェックボックスの状態に応じたラベル切り替えは、transition-delayの調整で自然なUI演出になる
  • アクロニムの全文表示には::first-letterと単語ごとの<span>分割が必要
  • アクセシビリティに配慮し、重要な情報は視覚効果だけに依存しない設計が求められる