CSSでの句読点ぶら下げ: hanging-punctuationプロパティ

句読点のぶら下げを指定する hanging-punctuation プロパティと、超縦書ビューアでの表示例についてご紹介します。

句読点のぶら下げとは

行末に句読点が来た場合、通常の行長よりはみ出して配置する方法です。日本語の均等割り組版でよく使われます。

句読点のぶら下げ

小学校の時の作文では、この書き方をした記憶があります。

ぶら下げのメリット

もともとは、手動組版で微調整の手間を省くため、ある種の手抜きから生まれたという話もありますが、

  • 行末がより揃って見える
  • 文字間隔の調整に無理がなくなる

などのメリットもあります。紙の書籍では、それなりに多く利用されています。

hanging-punctuationプロパティ

CSS Text Module Level 3では、句読点ぶら下げを指定するための hanging-punctuation というプロパティが定義されています。

効果
none(デフォルト) ぶら下げしない
first 先頭行の開き括弧や閉じ引用符をぶら下げる(開始側にはみ出す)
last 最終行の閉じ括弧や閉じ引用符をぶら下げる
force-end 行末の句読点をぶら下げる
allow-end 他の文字間調整などで調整しきれない場合に限り、行末の句読点をぶら下げる

指定の仕方としては以下のような形になります。

p {
    text-align: justify;
    hanging-punctuation: allow-end;
}

超縦書での対応

超縦書では、2013年頃より hanging-punctuation プロパティのうち日本語組版で利用頻度の高い force-endallow-endの2つについて独自に対応しています(EPUBでは定義されていないため独自拡張扱いです)。

  • hanging-punctuation: none
hanging-punctuation: none

hanging-punctuation: none


  • hanging-punctuation: force-end
hanging-punctuation: force-end

hanging-punctuation: force-end


  • hanging-punctuation: allow-end
hanging-punctuation: allow-end

hanging-punctuation: allow-end

EPUB内のCSSにプロパティを指定することで動作します。特にベンダープレフィックス等はありません。

他の環境での対応

caniuseによると、Safariでは2016年にリリースされたバージョン10から対応しているようです。AH Formatterもかなり以前から対応していると聞いています。それ以外のブラウザでの実装は進んでいません。

なお、ブラウザCSS実装ではありませんが、Amazon Kindleも2014年頃から句読点ぶら下げが行われていたと記憶しています。

hanging-punctuationとoverflow

ぶら下げをするとブロックのサイズを超えて文字が配置されることになるため、overflowが生じます。これがInk overflowなのかScrollable overflowなのかというのは難しい問題です。

Ink overflowとは、はみ出た部分は描画されるもののサイズに反映されないもので、bow-shadowなどが該当します。対してScrollable overflowとは、サイズに反映されるもので、親の要素に収まり切らなければ overflow:auto の場合にスクロールバーが出るタイプのものです。

素直に考えれば、句読点はメインコンテンツである「文章」の一部なので、Scrollable overflowとなるように思えます(禁則ルールなどではみ出る文字はすべてScrollable overflowです)。しかし、以下のようなケースを見てみましょう。

緑色が本文を含むブロック(<p>など)の領域、グレーがぶら下げではみ出た領域です。

日本語ではいわゆる等幅フォントが広く利用されるため、句読点もグリフ分ではなく1文字分の幅を持つフォントが多いです。この場合、1文字分まるごとScrollable overflowにすると、たまたま親要素に0.5文字分のパディングがあった場合、「はみ出た句読点を含めて十分表示しきれる領域があるのに、無駄にスクロールバーが出る」という問題が発生します。このため、一度は「hanging-punctuationによるぶら下げはInk overflowとし、表示領域に適切なパディングを付与するのはページ作者の責任とする」という決定がされました。

しかし、contenteditable の場合を考えると、編集時に見えなくなってしまうのは大きな問題です。また、通常の禁則などとの相互運用を考えても、本文がInk overflowになり隠れうるのはやはり問題とされ、「Scrollable overflowだが、はみ出た部分はtrimされるべき」と言った結論に変更されたりしました。その後の議論があったのか追い切れていないのですが、実装があまり進んでいないうえ後述のとおり hanging-punctuation 自体がat-riskになったこともあり、明確になりきっていないと思います。

hanging-punctuationプロパティの今後

2017年7月現在、 hanging-punctuation プロパティはat-risk扱いとなっています。これは、CSS Text Module Level 3がドラフト段階であり、正式版までの間に削除される可能性があることを示しています。ブラウザ実装も積極的に推奨されるフェーズではないという扱いです。これには以下のような背景があります。

西洋組版での利用に関する問題提起

西洋組版における句読点ぶら下げについての問題提起が、2016年4月にサンフランシスコで開催されたF2Fで議論されました。詳しくは参考リンクとして挙げられている解説がわかりやすいですが、西洋組版では日本語よりも複雑なぶら下げルールが利用されます。例えば以下のようなものです。

  • 先頭行以外でも、開き括弧をぶら下げることがある
  • 行末でハイフンをぶら下げる際など、1文字ではなく半文字程度ぶら下げることがある
西洋組版でのぶら下げ例

西洋組版でのぶら下げ例

現行の hanging-punctuation プロパティは、元々CJKでのユースケースを元に制定された仕様なこともあり、これらの要望に対応できません。

この時点で、 hanging-punctuation プロパティへのプロパティ追加やいったん白紙に戻す案も出ましたが、すでに一部実装が存在することからLevel 4での機能追加という案が有力視されました。

より汎用的な制御への変更案

2016年9月にリスボンで開催されたTPACでのCSSWG F2Fにて、さらなる議論が実施されました。

hanging-punctuationプロパティは、1つで以下の3つを制御しているといえます。

  • どの文字をぶら下げるか
    • first では開き括弧類、 last では閉じ括弧類、 force-end, allow-end では句読点など決められています。
  • どのような条件でぶら下げるか
    • first では1行目の行頭、 last では最終行の行末、 force-end, allow-end では行末となります。
  • どれくらいぶら下げるか
    • 最大1文字固定で、半分ぶら下げるなどの制御は出来ません。

これらを1つで制御するのは筋が悪いのでは、という意見、文字種別ではなくOptical Kerningの方が適しているのではという意見などが出ました。Optical Kerningは、文字の形に合わせてカーニングを行う手法で、文字の組み合わせによってはみ出す量を変更する処理が可能になります。

Optical Kerning

これらを踏まえ、プロパティの再構築が改めて検討されましたが、既存実装もあるため現状ではドロップされず、at-risk扱いとなりました。

最終的な結論はまだ出ていませんので、他の言語や組版でのユースケース、実装面での意見などがあればまだ反映されやすいフェーズだと思います。

関連記事(CSS)

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

baba

ゆとりプログラマー。

高校時代から趣味でプログラミングを初め、そのままコードを書き続けて現在に至る。慶應義塾大学環境情報学部(SFC)卒業。BPS設立初期に在学中から参加している最古参メンバーの一人。Ruby on Rails、PHP、Androidアプリ、Windows/Macアプリ、超縦書の開発などを気まぐれにやる。軽度の資格マニアで、情報処理技術者試験(15区分 + 情報処理安全確保支援士試験)、技術士(情報工学部門)、CITP、Ruby Programmer Goldなどを保有。

babaの書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ