🐷

[CSS組版]腑分けして理解したいCSS組版 余白のコラプシング・破棄

2024/12/19に公開

CSS組版アドベントカレンダー2024の19日目の記事です。

https://adventar.org/calendars/10448

組版環境揃った計算機を修理に出しているし図示は後日追記とします。

スペース・マージン・パディングの雑整理

実運用では入り乱れてよく分からないことになっているし、仕様の話というよりは考え方の整理と捉えてください。

余白には2種類あります。空いた空間の調整としての余白と、必要な空間の確保としての余白です。ざっくりとは、CSSに於けるパディングは前者、マージンは後者です。
必要な空間にも色々ありますが、視認性のために損なわれてはいけないというのが指標として分かり易いでしょう。一方で、必要以上に空間があるとき、視認性は悪くなることもあります。この距離の問題は、ゲシュタルト則を適用して考えるのがおすすめです。

『レタースペーシング タイポグラフィにおける文字間調整の考え方』(今市達也, 2021,株式会社ビー・エヌ・エヌ)では、ゲシュタルト則を提示した上で、版面を構成する文字の各スペーシングの基本バランスを説明してくれています。要約すれば文字間<単語間<行間<カラム間<ページマージンとして各関係間のスペースを設定していくことを説明しています。本は文字間のスペースを中心としているので本文組版ではいじらない箇所の話も多いのですが、「詰めすぎないようにするにはどんな感覚が必要か」ということも考えさせられます[1]

両端揃えと和欧混合文

さておき、自動組版では組版の優先順位に従って文字は流し込まれていきます。この優先順位によっては必ずしも美観・視認性は優先されません。素晴しい余白デザインだが1000ページの本と、文字を詰めすぎだが100ページの本では、印刷や置き場所といったコストで100ページの本にしなければならない場面が出ます。スペーシングについても同様に、「この一行の組版はぶっこわれるが、全体ではここを許容した方がよいかもしれない」というケースがあります。

Jpanスクリプト内にLatnスクリプトが存在する、所謂和欧混合文では、字間<行間を守るのが難しいケースが生じ易い傾向にあります。
和文は基本「どの文字間でも改行してよい(禁則はある)」で、「両端揃えのときどの文字間でスペースをとってもよい」ですが、欧文は「ハイフネーション可能箇所か単語間なら改行してよい(禁則もあるよ)」「両端揃えのときはワードスペース間を広げてもよい」というルールで動きます。
すると 、和文に混じったとても長くハイフネーションできない欧文と見做される単語箇所の前後で大変な字間のスペースが発生してしまうことがあります。URLはできるだけ別行で書くか改行可能な形にしておこうね!!

両端揃えは、「空いた空間の調整としての余白」に分類されるでしょう。版面の端を揃えることを優先するのであれば多少の不恰好を許容することはありますが、不恰好が全体に渡るならレイアウト設計を見直しましょう。

letter-spacing の補足

話題がずれますがついでに。

例えば「序論」という2文字項目を目次に配置するとき、「他の項目は30文字くらいのばっかりだから両端揃えにしちゃお」と安易に決定すると、大変な空白を生み出すことがあります。

1. 序                                                                            論
2. な ん か と り あ え ず 長 い タ イ ト ル を こ こ に 入 れ て お く か も し れ な い

両端揃えでなく、文字間に均一なスペースを指定するにはletter-spacingプロパティがあります。しかしこのプロパティはコンテンツをかなり選びます。文字同士が離れるため、大概の実装でフォントのリガチャやカーニングは効かなくなります。また、20文字のコンテンツと40文字のコンテンツの両端を揃えたりする用途ではJavaScriptで文字数カウントをして調整、のように泥臭い話になるでしょう。

Antenna House Formatterでは文字数に応じたletter-spacingなんて拡張を用意していますが、標準的な方法というのはありません。

https://www.antenna.co.jp/AHF/help/ja/ahf-ext.html#text-decoration#axf.auto-letter-spacing

余白のコラプス

必要な空間の確保としての余白は、隣のコンテンツ間で空いていればいいサイズです。確保するスペースの幅は最低限が理想となります。

  • 1.5emの余白が必要なグループA
  • 3emの余白が必要なグループB
  • 4.5emの余白が必要なグループC

ABが隣接したとき、1.5em+3em=4.5emを空ける、これは大概は不正解となります。3emの余白があったら、Aに必要な余白もBに必要な余白も確保できるからです。余白は隣接コンテンツ間のアキの大きい方を確保するのが基本です。約物間、段落やセクション間の余白などはこのように余白のデカさバトルをしています。

(行進行方向)マージンのコラプス

pmargin-topを1em、margin-bottomを1.5emとして。

p {
  margin-top: 1em;
  margin-bottom: 1.5em;
}

p間の余白は1.5emになります。p内の行間はline-heightなので[2]、小説など同じバランスで続けたい場合は特に気を付けないといけないポイントです。

逆にコラプスさせないためにはどうすればいいかというと、隣接しなければいいので、更にdivで囲うなどするとそれぞれのマージンが取られます。

約物間のコラプス text-spacing-trim

trimなのでコラプスというより除去なんですが、大体の指定で約物が隣接するときは結果的に約物のアキのデカい勝ちバトルをやってくれるので。次の記事が分かり易いでしょう。

Chrome で text-spacing-trim プロパティがサポートされたぞ!! Zenn いなにわうどん

https://www.w3.org/TR/css-text-4/

margin-breakによる余白のdiscard(破棄)

隣接するマージン間はデカいもの勝ち。では隣接不可能なページマージンとの調整はどうすればいいか。
margin-breakプロパティがあります。まあ処理系に実装されているなら既定であろうautoでページ上に来たときの余白を破棄してくれるので「これがいい感じにしれくれている」ということだけ頭にあれば良いでしょう。

強制破棄のdiscardは、CSSセレクタなどで特定の組み合わせ時に適用されるようにすることが多いでしょう。

強制改ページを行ったときの例についてはLibroWorksのブログ記事が参考になります。

[[CSS組版]見出しやコラムがページ上に来たときの上マージン調整~margin-breakの補足 LibroWorks] (https://libroworks.co.jp/?p=7403)

ハーフレーディングは今のところ消しきれない

line-heightは文字モノ、段落を有する組版では欠かせません。しかし一番最初の行の上、一番最後の行の下に発生するハーフレーディングは日本語組版ではちょっと厄介です。

単行を想定して除去を試みるブログ記事もあります。

line-heightのハーフ・レディングを打ち消すcalc((1em - 1lh) / 2)をCSS変数に定義しておくとよい TAKLOG

しかし見出しですら2行になってしまいかねない状況であると、text-box-trim,text-box-edgeプロパティがあるに越したことはないよなあ。

ちなみにこの問題はページレイアウトを文字サイズ基準でバッチリ決めたと思ったような版面設計でも顔を出します。下側はどうせページマージンなので見えないが、上はね。

脚注
  1. 考えた結果、諸々あって詰めすぎた本を出したりすることもある ↩︎

  2. 行内で文字サイズ変えたりするとまた基準が変わるので気を付けましょう ↩︎

組版・ドキュメンテーション勉強会

Discussion