📰

Chrome で text-spacing-trim プロパティがサポートされたぞ!!

2024/03/24に公開

今月の 19 日に Chrome 123 が正式にリリースされ、CSS 上で CJK の約物アキ(スペーシング)を調整する text-spacing-trim プロパティがサポートされました!!🎉🎉
折角の機会ですので、実際のブラウザの挙動や W3C の草案を基に、このプロパティの仕様を紐解きます。

text-spacing-trim プロパティとは?

日本語に使用されるひらがなや漢字等の文字は正方形のボディ(枠)の中に表されます。同様に、句読点や括弧等の約物も全角の送り幅を持ちます。しかしながら実際のところ、多くの約物の幅は半角であるため、約物が行頭・行末に位置したり、約物と約物が連続したりすると、不格好なスペース(アキ)が生じてしまいます。こうしたアキは適切に詰める(削る)ことが望ましいです。

約物のアキを調整した例。上段には調整前の文字組みが、下段には調整後の文字組みが掲載されている。

字間を詰める操作は InDesign 等の DTP ソフトウェアでは一般的ですが、従来 Web 上で実現するには別途ライブラリを導入する必要がありました。今回サポートされた text-spacing-trim プロパティを利用すると、ブラウザ標準で約物のアキを適切に制御することができます。

プロパティ値

text-spacing-trim プロパティには本来 7 つの値が定義されており、Chrome 123 ではこのうち space-all, normal, trim-start, space-first の 4 つがサポートされています [1]。

プロパティ値とアキの関係を簡単に表した表を以下に示します。Chrome 123 以降の規定値[1]normal であり、特に意図しない場合はこの値で問題ありません(綺麗に調整されます)。従来の挙動を維持したい場合は space-all を指定します。

プロパティ値 行頭のアキ 行末のアキ 連続する約物間のアキ
space-all 詰めない(半角下げ) 詰めない 詰めない
normal 詰めない(半角下げ) 行の調整に必要な場合のみ詰める 適切に詰める
trim-start 詰める(天付き) 行の調整に必要な場合のみ詰める 適切に詰める
space-first 最初の行は半角下げ
その他は天付き
行の調整に必要な場合のみ詰める(地付き) 適切に詰める

Chrome の挙動を見てみる

百聞は一見に如かずと言いますので、実際の挙動を見てみます。以下の図では、text-align: justify を指定したテキストボックスに対し、上段には space-first を、下段には従来の挙動である space-all を設定しています。上段は下段に比べて、自然な組版が実現されていることが見て取れます。

text-spacing-trim プロパティを適用したスクリーンショット
文章は 京葉線 - Wikipedia を改変して使用。CC BY-SA

画像からは、以下の挙動が確認できます。

  • 行頭の括弧(橙色)
    1 行目のみアキが残り、2 行目以降は行頭のアキが詰まる(space-first であるため)
  • 連続する約物(ピンク色、青色、緑色)
    読点→句点、閉じ括弧→閉じ括弧ではアキなし、中黒→括弧、閉じ括弧→開き括弧では二分(1/2)–全角程度のアキに調整される
  • 行末の閉じ括弧(青色)
    必要に応じて行末のアキが詰まる
  • 行末の句点(緑色)
    行末のアキが詰まることはなく、行長をはみ出した場合は次の行に送られる(追い出し)

注意点

注意すべき点としては、以下の事柄が挙げられます。

  • font-feature-settings に palt, halt 等を設定した場合、(これらの機能に対応したフォントの使用時に限って)text-spacing-trim の有無にかかわらず、句読点は半角で表示される
  • メイリオや MS ゴシック、HG創英角ゴシックUB 等の Windows や Office に同梱されるフォントに対しては text-spacing-trim が適用されず、句読点は常に全角で表示される。一方、ヒラギノ、モリサワ、フォントワークス等の書体では正常に動作する

上記の 2 点目については、Chrome Platform Status のドキュメント [2] における「Excessive Kerning」の項目にて言及されています。初期実装では text-spacing-trim プロパティの適用対象を、OpenType 機能の chws, halt タグを有するフォントに限定[2]することで、フォントデザイナの意図に反して過剰に文字が詰められることを防止しているようです。MS のフォントはこれらの機能に対応していないため、今回の実装では対象外となっています。

2024/3/25 追記
Yu Gothic UI を使用した場合に、鍵括弧等が正常に表示されない現象が発生しています。

https://zenn.dev/inaniwaudon/scraps/f224417d4c51ee

W3C Working Draft を読む

text-spacing-trim プロパティは、W3C Working Draft の CSS Text Module Level 4 [3] に定義されているため、これを読んでみます。

仕様書ではプロパティ値を以下の通りに定義しています。説明中で波括弧で囲った用語は後ほど説明します。

プロパティ値 説明
space-all すべての全角約物:位置に関係なく全角で組む
normal 各行頭の{全角開き約物}:全角で組む
各行末の{全角閉じ約物}:両端揃えを行う上で調整する必要があれば半角で、そうでなければ全角で組む
連続する約物:後述する「連続する約物間のアキの処理」に従って組む
trim-auto 各行頭の{全角開き約物}:半角で組む
各行末の{全角閉じ約物}:半角で組む
連続する約物:後述する「連続する約物間のアキの処理」に従って組む
trim-start 各行頭の{全角開き約物}:半角で組む
その他:normal と同等
space-first ブロックコンテナの最初の行および強制改行後の行頭の{全角開き約物}:全角で組む
その他:normal と同様
trim-all {全角開き約物、全角閉じ約物、全角中黒}:位置に関係なく半角で組む
auto 組版的に高品質なスペーシングを自動選択する。プラットフォームによって異なる設定が選択される可能性がある

上記の値のなかで、space-first は互換性のために設けられた選択肢であると補足されています。hanging-punctuation プロパティの信頼できる実装が欠如していたため、歴史的に text-indent プロパティの代わりに全角スペース(U+3000)を用いて字下げを表現し、行頭の句読点をインデント内にぶら下げたい場合のみ、このスペースを省略する指定がなされる場合がありました。こうしたコンテンツを壊さないために space-first が用意されましたが、そもそも本来は字下げの表現にスペースを利用するべきではありません。

処理

text-spacing-property プロパティは以下の通りに処理されます。

1. 文字クラスの分類

ブラウザは、文字を次のテキストスペーシング文字クラス(Text Spacing Character Classes)に分類します。これらはUnicode のカテゴリやコードポイントを基に分類されます(詳細は仕様書を参照)。

  • 表意文字(ideographs)
  • 非表意文字(non-ideographic letter)
  • 非表意数字(non-ideographic numeral)
  • 全角開き約物(fullwidth opening punctuation):開き括弧類(「(等)
  • 全角閉じ約物(fullwidth closing punctuation):閉じ括弧類(」)等)
  • 全角中黒(fullwidth middle dot punctuation)
  • 全角コロン(fullwidth colon punctuation):コロン、セミコロン
  • 全角ドット(fullwidth dot punctuation):全角読点、句点、カンマ、ピリオド

なお、全角コロン・全角ドットは、全角閉じ約物・全角中黒のいずれかとしてみなす必要があります。これは、言語によって約物がグリフの枠中のどこに位置するかが変わる[3]ためです。

言語 全角コロン 全角ドット
中国語(簡体字) 全角閉じ約物 全角閉じ約物
中国語(繁体字) 全角中黒 全角中黒
日本語、韓国語 全角中黒 全角閉じ約物

2. 連続する約物間のアキの処理

約物が連続する場合は、その間のアキを以下に従って調整します。

  • text-spacing-trim が trim-all である場合
    文脈にかかわらず、すべての全角グリフのスペースを詰める
  • その他の場合
    次の通りに処理する。該当しない場合は全角に設定する
    1. 前置の文字が以下に該当する場合、全角開き約物を半角に設定する
      全角開き約物、全角中黒、全角スペース(U+3000)、同等以上のフォントサイズの全角閉じ約物、Unicode general category Ps(Punctuation open)に属する文字
    2. 後置の文字が以下に該当する場合、全角閉じ約物を半角に設定する
      全角閉じ約物、全角中黒、全角スペース(U+3000)、同等以上のフォントサイズの全角開き約物、Unicode general category Pe(Punctuation close)に属する文字

3. グリフの変換

最後に、以下の条件に応じてグリフを変換します。

  • 全角幅のグリフを半角幅として組む場合
    グリフの空白の半分を詰める。この際、OpenType 機能の halt, vhal タグ[4]を使用してもよい。ただし、グリフの形状が変わることを防ぐために、hwid 機能を用いたり、半角文字で代用したりしてはならない
  • 半角幅のグリフを全角幅として組む場合
    グリフにスペースを追加する
  • プロポーショナルグリフの場合
    フォントによっては、約物がプロポーショナル幅のグリフとして定義される場合(Osaka フォント等)がある。全角、半角のグリフ形状を区別するための情報がフォントに定義されない場合、ブラウザはプロポーショナルグリフに対してスペースを追加および削除することはない

漢字の送り幅は、以下のいずれかを基に決定されます。

  1. OpenType における ideo, idtp 等のメトリクス情報
  2. 水(U+6C34)等の漢字の送り幅。「水」(U+6C34)「卜」(U+535C)「一」(U+4E00)が同一の送り幅を持たない場合、そのフォントの送り幅はプロポーショナルであり、グリフを測定しても全角の送り幅を確定できない。

むすびにかえて

近年はブラウザでも日本語組版への対応が進んでおり、word-break: auto-phrase による文節での改行や、フラグ付きではありますが、text-autospace プロパティを用いた和欧間スペースの自動挿入なども既に実装されています。今回の text-spacing-trim プロパティもデフォルトで適用されるため、Web における日本語組版の品質向上が期待できます。

参考文献

脚注
  1. 従来の挙動は space-all であったため、破壊的変更となる ↩︎

  2. 技術的にはグリフを解析してアキ量を調整することも可能だが、今回はその実装は行わないと明記されている ↩︎

  3. 例えば繁体字の場合、句点は天地左右中央に位置する ↩︎

  4. 全角幅の約物を半角幅に調整するために、フォントに埋め込まれた機能 ↩︎

Discussion