CSSで、日本語と英数字のあいだに自動ですきまを入れる方法

​​CSS​Playwright,日本語組版

日本語の文の中に HTML や 3 のような半角の英数字があると、前後の文字と詰まって見えます。CSS の text-autospace プロパティに normal を指定すると、漢字やかなと半角の英数字のあいだに、ブラウザーが自動ですきまを入れます。HTML に半角スペースを足す必要はありません。

css
body {
  text-autospace: normal;
}
補足

検証環境は Ubuntu 24.04、Node.js 22.23.4、Playwright 1.63.0、Chromium 153 です。フォントは Noto Sans CJK JP と Noto Sans Mono CJK JP を入れ、横書きのページを Playwright で開いて、1文字ずつの幅を測りました。縦書き、Chrome 以外のブラウザー、Windows や macOS に入っているフォントでの表示は試していません。各ブラウザーの対応バージョンは、互換性データ(@mdn/browser-compat-data 8.1.8)の値です。

書かないと、すきまは入らない

CSS Text 4 の仕様では、text-autospace の初期値は normal です。ところが互換性データの注記では、Chrome、Edge、Firefox、Safari はどれも、初期値が normal ではなく no-autospace(すきまを入れない)になっています。

検証環境の Chromium 153 でも、何も指定しない段落の計算値は no-autospace で、すきまは入りませんでした。すきまを入れたいときは、normal を自分で書きます。

text-autospace は子要素に継承されます。検証環境でも、body に normal を書くと、中の段落にすきまが入りました。サイト全体に効かせるなら、body に1回書けば足ります。

すきまの幅は1/8文字分

仕様では、入るすきまの幅は CJK の文字1つ分の幅の1/8(0.125ic)と決められています。検証環境の Noto Sans CJK JP では、全角の文字1つの幅が文字サイズと同じだったので、すきまの幅は文字サイズの1/8になります。

検証環境で「HTMLの第3章」という段落を、no-autospace と normal で表示して比べました。

文字サイズ すきまが入った場所 1か所の幅 段落の幅(指定なし → normal)
40px L と の、第 と 3、3 と 章 5px 249.48px → 264.48px
16px 同じ3か所 2px 99.80px → 105.80px

16px の本文なら、1か所あたり2px です。

2つの段落を縦に並べた画面。上は「指定なし(初期値の no-autospace)」、下は「text-autospace: normal」で、どちらも「HTMLとCSSで作る、第3章のWebページ」という文。下の段落では、英数字と日本語がとなり合う7か所(「HTML」と「と」のあいだなど)が少し広がり、その位置の下にピンクの短い線がある
上が初期値、下が normal。ピンクの線が、自動で入ったすきまの位置

すきまは見た目だけのもので、文字は増えません。検証環境でも、normal の段落全体を選択して getSelection().toString() で取り出した文字列は、元の「HTMLの第3章」のままでした。仕様にも、コピーして貼り付けた文字列に影響してはいけないと書かれています。

すきまが入る場所と入らない場所

仕様では、すきまが入るのは「漢字やかな」と「半角の英字や数字」が直接となり合うところです。くわしい文字の範囲は、仕様の文字の種類どうしのすきま(Inter-script Spacing)の節に書かれています。

検証環境で、いろいろな文字の並びを normal で表示して、すきまが入った場所を調べました。

段落の文字列 すきまが入った場所
カタカナAとひらがなB ナ と A、A と と、な と B
HTMLの第3章(全角の英数字) なし
(CSS)とCSS、 と と C だけ
第1回@東京#2 第 と 1、1 と 回 だけ
日本 HTML 入門(半角スペースあり) なし
日本 HTML入門(片側だけ半角スペース) L と 入 だけ

ひらがなとカタカナは、漢字と同じ扱いでした。全角の英数字のあいだには入りません。かっこや句読点、@ や # のような記号と英数字のあいだにも入りませんでした。

もともと半角スペースがあるところには、すきまは足されません。手で半角スペースを入れてある文章でも、すきまが二重になることはありません。

code や strong の境目にも入る

文の中で、英数字だけが <code> や <strong> に入っていることはよくあります。検証環境では、<code>CSS</code>の書き方 の S と の のあいだにも、<strong>HTML</strong>の の L と の のあいだにも、5px(文字サイズ40px)のすきまが入りました。このとき <code> のフォントは、等幅の Noto Sans Mono CJK JP にしています。

仕様では、あいだに padding などがあるときは、すきまを入れないとされています。ところが検証環境の Chromium 153 では、<code> に左右4pxの padding を付けても、S と の のあいだに5pxのすきまが入りました。そのため Chromium では、インラインの code に padding を付けていても、code と後ろの文字のあいだは padding にすきまの5pxを足した幅になります。

letter-spacing と重ねたときは、letter-spacing の空きに、すきまがそのまま足されます。仕様にそう書かれており、検証環境でも letter-spacing: 0.1em の段落でも、letter-spacing なしのときと同じく、1か所あたり5px(3か所で15px)広がりました。

pre の中では列がずれる

body に normal を書くと、<pre> にも継承されます。等幅フォントで文字の位置をそろえたコードやアスキーアートでは、漢字やかなと英数字がとなり合う行だけが広がり、列がずれます。

検証環境で、等幅フォント(Noto Sans Mono CJK JP、40px)の <pre> に + - | の記号で枠を描くと、|猫ABC| の行だけが5px広くなり、右端の | がずれました。

2つの pre を縦に並べた画面。上は「body { text-autospace: normal; } だけ」で、+-----+ の枠の中の「|猫ABC|」の行の右端の縦線が、ほかの行より少し右に出ている。下は「pre だけ no-autospace に戻す」で、すべての行の右端がそろっている
上は body の normal が pre にも継承された場合、下は pre だけ no-autospace に戻した場合

コードを表示する pre だけは、no-autospace に戻しておきます。

css
body {
  text-autospace: normal;
}

pre {
  text-autospace: no-autospace;
}

Chrome で使える値は normal と no-autospace だけ

仕様と MDN には、ほかにも値があります。ideograph-alpha は漢字やかなと英字のあいだだけ、ideograph-numeric は漢字やかなと数字のあいだだけに、すきまを入れます。insert と replace は、すでにある半角スペースをどう扱うかを決める値で、replace は半角スペースを取り除いて、すきまに置き換えます。auto は、すきまの幅をブラウザーに任せる値です。punctuation は句読点のまわりにすきまを入れる値ですが、仕様では、今のところ効くのはフランス語の文章だけとされています。

検証環境の Chromium 153 で CSS.supports() を使って調べると、受け付けたのは normal と no-autospace だけでした。auto、ideograph-alpha、ideograph-numeric、punctuation、insert、replace は、どれも false でした。

互換性データでの対応状況は次のとおりです。

ブラウザー normal・no-autospace ideograph-alpha・ideograph-numeric・auto
Chrome・Edge(Android の Chrome を含む) 140 から 対応していない
Firefox(Android を含む) 145 から 145 から
Safari(iOS を含む) 18.4 から 18.4 から

Chrome・Firefox・Safari のどれでも使えるのは、normal と no-autospace の2つです。英字と数字のどちらか一方だけにすきまを入れたいときは、Chrome では効かないことを前提にしてください。

かっこや句読点の詰め方は、text-spacing-trim という別のプロパティで変えます。

​Posted by 86