ボタンやカードのタイトルなど、文字数によってレイアウトが崩れる問題はフロントエンド開発でよく発生します。文字数が多いときはフォントサイズを小さくして収めたい、というニーズに応えるテクニックを紹介します。
この記事で学べること:data属性+CSS属性セレクタによる切り替え・JavaScriptによる動的計算・CSS Container Queriesの活用
方法1:data属性とCSS属性セレクタで切り替える(純CSS)
JavaScriptで文字数を計算してdata属性にカテゴリを設定し、CSSで切り替える方法です。
<p class="title" data-len="short">短いタイトル</p> <p class="title" data-len="medium">ちょっと長めのタイトルテキスト</p> <p class="title" data-len="long">かなり長い文字数のタイトルが入ったとき用の表示</p>
.title[data-len="short"] { font-size: 1.4rem; }
.title[data-len="medium"] { font-size: 1.1rem; }
.title[data-len="long"] { font-size: 0.85rem; }
// JavaScriptでdata属性を設定
document.querySelectorAll(".title").forEach(el => {
const len = el.textContent.length;
if (len <= 15) el.dataset.len = "short";
else if (len <= 30) el.dataset.len = "medium";
else el.dataset.len = "long";
});
メリット:CSSが明確で管理しやすい。段階的な切り替えで十分なケースに最適。
方法2:JavaScriptでフォントサイズを動的に計算する
文字数に応じて連続的にフォントサイズを計算する方法です。よりきめ細かく調整できます。
function adjustFontSize(el, baseSize = 1.4, minSize = 0.7, charLimit = 20) {
const len = el.textContent.trim().length;
if (len <= charLimit) {
el.style.fontSize = baseSize + "rem";
} else {
// 文字数が増えるほど小さくなる計算
const ratio = charLimit / len;
const size = Math.max(baseSize * ratio, minSize);
el.style.fontSize = size.toFixed(2) + "rem";
}
}
// 全タイトル要素に適用
document.querySelectorAll(".auto-size").forEach(el => adjustFontSize(el));
方法3:CSS clampとvwで画面幅に応じて調整する
clamp()とvw単位を組み合わせると、画面幅に応じた流動的なフォントサイズを実現できます。文字数というよりコンテナ幅への対応に有効です。
/* 最小0.8rem・最大1.4rem・画面幅に応じて自動調整 */
.fluid-title {
font-size: clamp(0.8rem, 2.5vw, 1.4rem);
}
clamp(最小値, 推奨値, 最大値):ビューポート幅が狭いと小さく、広いと大きく、指定した範囲内で収まります。レスポンシブデザインに非常に便利な関数です。
方法4:fitText.jsなどのライブラリを使う
コンテナ幅いっぱいに文字を収めたい場合は、fitText.jsのようなライブラリを使うのも選択肢です。
// fitText.js使用例
$(".title").fitText(1.2); // 第1引数はkompressor(小さいほど大きい文字)
// バニラJSで同等の実装
function fitText(el, compressor = 1) {
function resizer() {
el.style.fontSize = (el.offsetWidth / (compressor * 10)) + "px";
}
window.addEventListener("resize", resizer);
resizer();
}
実装の選び方まとめ
| 方法 | 実装難易度 | JS必要 | 向いている場面 |
|---|---|---|---|
| data属性+CSS切り替え | 低 | 少し | 段階的な変更で十分な場合 |
| JS動的計算 | 中 | 必要 | 文字数に応じた細かい調整 |
| CSS clamp+vw | 低 | 不要 | 画面幅に応じたレスポンシブ |
| fitTextライブラリ | 低 | 必要 | コンテナ幅いっぱいに収めたい |
よくある質問(FAQ)
Q. 純CSSだけで文字数に応じてフォントサイズを変えることはできますか?
A. 現時点(2024年)では難しいです。CSSには文字数を計測するプロパティがありません。
clamp()やvwを組み合わせることでコンテナ幅に応じた調整は可能ですが、テキストの文字数そのものへの対応にはJavaScriptが必要です。Q. 日本語(全角文字)と英字(半角文字)が混在する場合の対処法は?
A. 全角文字は半角の約2倍の幅を取ります。文字数を計算する際に
文字.charCodeAt(0) > 127で全角を判定し、全角1文字を2カウントするなどの重み付けをすると精度が上がります。Q. Reactなどのフレームワークでこの実装をするにはどうすればよいですか?
A. useEffectでマウント後にfontSize計算を実行し、stateまたはstyleプロパティに設定します。テキスト内容が変わった場合の再計算はuseEffect依存配列にテキストの状態を追加することで対応できます。
まとめ
- 文字数に応じた調整にはdata属性+CSS切り替えが管理しやすい
- 連続的な調整にはJavaScriptで動的計算してstyle.fontSizeに設定
- 画面幅対応にはCSS clamp()+vwが純CSS・設定不要で便利
- コンテナいっぱいに収めたいならfitText.jsが手軽

