⛷️

[CSS組版]並行して進む二段組の実現例

2024/12/11に公開

CSS組版アドベントカレンダー2024の11日目の記事です。ラップトップの液晶壊れちゃった。

https://adventar.org/calendars/10448

昨日は メイユールさんの『Vivliostyleで脚注のスタイルを変更する』でした。

今日のネタは、以前Vivliostyleのワークショップに参加したときに懇親会で相談された表現です。

通常の段組

通常の段組では、段の端に到達すると同ページの次段へ内容が進みます。段ページ内に段がなければそこで次ページの一段目に進みます。1ページ目に段A1と段B1、2ページ目に段A2と段B2があるとして、段A1→段B1→段A2→段B2と進んでいくことになります。

並行して進む段組

並行して進む段組では、それぞれの段の内容は独立して次のページへ進みます。段A1→段A2、段B1→段B2でAとBは干渉せずに進んでいきます。

どんなときに嬉しいのかというと、平行世界系小説を同時進行で組みたいとき……はともかくとして、対訳を組むときですね。

テーブルレイアウトでの実装

「並行して進む段組」、実は皆さん昔結構見た筈です、歴史の授業なんかで。……そう、「年表」って並行して何段かの流れが書いてあったりしましたよね、日本の歴史とその頃の世界の歴史、とか。年表の表は表の表なんですよ。タイムテーブルは1段にフォーカスするものが多いですし、後はラジオの進行表なんかは近いかもしれません。

そう、CSSはCSSでもCSS組版の世界でテーブルレイアウトは生きている! まあCSS組版ではちょっとテーブル組版機能が弱いのでより限定的ですが。その限定的な機能が生きるのが並行して進む段組なんですね。

話として難しいことはないのでいきなりCSS。

        table {
            width: 100%;
            table-layout: fixed;
        }

        table col.a {
            width: 50%;
            background-color: burlywood;
        }

        table col.b {
            width: 50%;
            background-color: lightpink;
        }
        <table>
            <colgroup>
                <col class="a" />
                <col class="b" />
            </colgroup>
            <thead>
                <tr>
                    <th >A</th>
                    <th >B</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>  
                        <p>...</p>
                        <p>親類のも...</p>
                        <p>庭を東へ...</p>
                        <p>この外...</p>
                    </td>
                    <td>
                        <p>...</p>
                        <p>親類のも...</p>
                        <p>庭を東へ...</p>
                        <p>この外...</p>
                    </td>
                </tr>
            </tbody>
        </table>

HTMLはtd内をA段とB段で同じ内容にしています。ただの横着です。

ポイントといえばポイントなのはtable-layout: fixedです。カラムのサイズ計算を処理系任せにする利点が今回は無い(段Aも段Bも同じサイズで進めたい)ので、計算する分処理が重くなる自動カラムレイアウトをしない。

キリの良いところでtrを切り換えることによって、A段とB段の長さに差異がある場合でもある程度リセットが利きます。

なぜflexやgridを使わないのか

flexはページ分割を挟むとちょっと怖い処理系が多い、というのはおいておいて、書くならこんな感じになる、のかな。

.A {
display: flex;
flex-direction: column;
...
}
...

tableの場合はrowを単位としてAとBの進行に同期が取れるんですが(年表で「1900-1999」みたいに時代を区切ったり)、flexのAとflexのBで位置の同期を取ることは困難なので、後々カスタムしようと思ったときに大変かもしれないのが大きいです。

Gridは単純に、Fragmentation仕様を実装した処理系が今のところないので、ページ分割がある内容には使えません。単ページごとに区切れる内容ならやれなくはないでしょうが、それは段組ではないので。

Discussion