アイキャッチ画像

CSSで行間を広げない見栄えの良いルビと圏点を作る(そしてHugoでショートコードにまとめる)

活版印刷、植字大好きー! rubyタグ大好きー!

ルビ。それは活字の8Qサイズを語源とする振り仮名のこと。漢字の読み方を教え、海外小説のニュアンスをできるだけ崩さずに表現し、時に厨二病な演出を可能にする、日本語には欠かせない文章表現の一つです。

悲しいかなHTML及びCSSにおけるrubyタグの扱いはとってもぞんざい。ルビの位置が上か下かを設定するruby-positionと、単語と読みの長さが異なる場合のレイアウトを決定するruby-alignが存在しますが、そもそも実験的な機能という位置づけらしく、2020年2月現在、Firefoxぐらいでしかサポートされていません。モノルビ設定もなければ、1-2-1ルールも均等アキも当然なく、それどころかルビのサイズや位置すら気軽に設定できないのが現状です。

Can I use ruby-position?

そもそも、ルビって日本語以外にあるんでしょうか?

英語ではHTMLCSS、最近ではあまり聞くことのなくなったWYSIWYGなどのように、頭文字を使った略語(イニシャリズム、アクロニム)が広く使われていますが、それらに日本語のようなルビをふる文化はなく、正式名称を示したい場合は後ろに書くのが普通です。HTMLタグとしてもacronymabbrがありますが、一般にはバルーンチップとして表示されるだけです。さらに前者はHTML5で廃止されました。

ではアジア言語圏はと言うと、中国語は漢字だけですが、読み方を示すために発音記号“ピンイン”を漢字の上に置くことがあるようです。でもピンインはあくまで発音記号、日本語のように単独でも使用できる文字であるひらがなを使ったルビとは少しおもむきが異なる気がします(日本語が表音文字と表意文字を併用する特殊な言語というのもあります)。

台湾語も同様に発音記号をふることがあるみたいなんですが、“ボポモフォ”と言うらしいです。字面が可愛いですね。
韓国語なんかはどうなんでしょう? 漢字を使うので読めない場合はルビを振ると思いますが、そもそも漢字の使用頻度が日本語ほど高くないと聞きます。

日本語の文章表現には欠かせないルビ

一方で日本語はやたらルビを使います。一つの漢字に音読みと訓読みがあるのが基本ですし、当て字という文化もあって知らない限り読めない単語も多いです。人の名前も当て字が殆ど。個人情報の入力フォームに必ず「ふりがな」が存在する国って日本以外にあるのでしょうか?

活字の分野では表現手法として使われるルビが発達しています。ファンタジーやSFではこの世界では……」というように関係代名詞に固有名詞を当てる表現は一般的ですし、アルファベットなどの文字そのものが重要な言葉は表記そのままに翻訳をルビで乗せたり、“凝り性”アーティストのように一般名詞や固有名詞に異なるニュアンスを与えるといった役割もこなします。もともとは海外小説の翻訳からの流れなのでしょうか。本格推理に出てくる[〇〇荘]なんかは大抵漢字にカタカナが振られていましたし、SF小説の『ニューロマンサー (1984)なんかルビだらけだった印象です。

いわゆる厨二病なジャンルの小説にもルビは欠かせないですよね。奈須きのことか……(ルビだらけでそれらに意味もなくひたすら読みづらいという印象しかないですが)あとは代表的なところで不運ハードラックダンスっちまったんだよ……」とかw

閑話休題

rubyタグ

素直にHTMLのrubyタグでルビを振ってしまうと、位置の調整ができず、行間も広がってしまいます。下記の例では、ルビのある行間のみ広がっていて、さらにルビの長さに合わせて字間も取られているのがわかります。

Chromeによるレンダリング

<ruby>タグによるルビ

HTML

そうして私たちはお互に恋し合い、数週間後に結婚したんです。――ところで私自身はホップの<ruby>卸商<rt>おろししょう</rt></ruby>です。私は年に七八百<ruby>磅<rt>ポンド</rt></ruby>の収入がありますから、私たちは別に不自由はしておりません。

CSS

body
{
	line-height: 100%;
	text-align: justify;
}

(参考)お使いのブラウザでの表示

そうして私たちはお互に恋し合い、数週間後に結婚したんです。――ところで私自身はホップの卸商おろししょうです。私は年に七八百ポンドの収入がありますから、私たちは別に不自由はしておりません。

  • 上記はrubyタグとrtタグそれぞれにall: revartスタイルを指定しています。
そうして私たちはお互に恋し合い、数週間後に結婚したんです。――ところで私自身はホップの卸商おろししょうです。私は年に七八百ポンドの収入がありますから、私たちは別に不自由はしておりません。
コナンドイル Conan Doyle 三上於莵吉訳 黄色な顔 THE YELLOW FACE

CSSの疑似要素を使って改善

今度は、上記サイトを参考にさせていただき、CSSの疑似要素を使って見た目を改善したものです。わかりやすいようルビの範囲に背景色を付けていますが、行間はルビが入る前提で全体的に広く取った上で、そこに綺麗にルビが収まっている事がわかると思います。ポイントはHTML5のカスタムデータ属性を使うことで、rubyタグの構造はしっかり維持出来ているという事です。

Chromeによるレンダリング

CSSを使ったルビ

HTML

そうして私たちはお互に恋し合い、数週間後に結婚したんです。――ところで私自身はホップの<ruby data-ruby="おろししょう">卸商<rt>おろししょう</rt></ruby>です。私は年に七八百<ruby data-ruby="ポンド">磅<rt>ポンド</rt></ruby>の収入がありますから、私たちは別に不自由はしておりません。

CSS

body
{
	line-height: 160%;
	text-align: justify;
}

ruby[data-ruby]
{
	position: relative;
}

ruby[data-ruby]::before
{
	content: attr(data-ruby);
	position: absolute;
	line-height: 100%;
	text-align: center;
	left: -3em;
	right: -3em;
	transform-origin: bottom center;

	/* ルビの文字サイズを親文字に対する比率で指定 */
	transform: scale(0.5);

	/* 100%を越える部分が親文字とルビとのスペースになる。単位は親文字に対する比率 */
	bottom: 105%;

	/* デバッグ用 */
	background-color: rgba(255, 0, 0, 0.2);
}

ruby[data-ruby] rt
{
	display: none;
}

(参考)お使いのブラウザでの表示

そうして私たちはお互に恋し合い、数週間後に結婚したんです。――ところで私自身はホップの卸商おろししょうです。私は年に七八百ポンドの収入がありますから、私たちは別に不自由はしておりません。

なお、ルビのサイズ指定をわかりやすくするために、参考サイトから少しだけプロパティを変えました。具体的には……

  • 親要素に指定した行間160%が継承されてしまうので、ルビの方ではline-height: 100%を指定して打ち消し。
  • ルビの文字サイズをfont-sizeで指定すると、疑似要素全体としての大きさは親要素の文字の大きさを継承したまま、文字だけが小さくなってしまい、位置の指定がわかりづらくなるので、transformプロパティを使って要素全体を縮小。
  • さらにtransform-originbottomとし、親文字と下端を一旦いったん揃えてからbottomで上に移動することで、親文字のサイズを基準とした値でルビのオフセットを指定できるように。
    100%で親文字上端ぴったり、100%を超える部分がルビ下端から親文字上端のスペースになります。
  • 上記の変更を加えた結果、ルビの字数が親文字の字数を越えると折り返されてしまうようになったので、leftrightにマイナス値を指定して長いルビも表示できるように。(親文字の字数+両方のemの絶対値の合計)がほぼそのまま表示できるルビの字数になります。

Hugoのショートコードにまとめる

これで見た目はなんとかなったものの、ただでさえ書くのが面倒なタグであるrubyがさらに冗長になってしまったので、ショートコードにまとめました。規則的な書き方のHTMLはなんでもショートコードにまとめてしまえるのがHugoの良いところ。

layouts/shortcodes/ruby.html

<ruby data-ruby="{{.Get 0}}">{{.Inner}}<rt>{{.Get 0}}</rt></ruby>

使う時は{{<ruby "おろししょう">}}卸商{{</ruby>}}みたいに書けば先程のHTMLのように書き出してくれます。

圏点けんてん傍点ぼうてん

もう一つ、ルビほど多用はされませんが、重要な活字表現として圏点(または傍点ないし脇点わきてん、いずれも同じもの)があります。単純に文章を強調する以外にも、ひらがなが連続して分かりづらい場合に文節の区切りを示して読みやすくするのにも使われます。ミステリファンとしては、盲点だった重要な事実に傍点が振られていたりするともう大興奮です。

これもルビと同じレイアウトで実現できるので、読み仮名の代わりに●や﹅を小さめのフォントサイズで使い、一文字ずつ前述のルビタグで囲めば綺麗に実現できます。

CSSを使った圏点

(参考)お使いのブラウザでの表示

「あなたがね、山田さん」

ただ、何しろ一文字ずつタグで囲まなきゃいけないというのが作業として大変辛いですね。そこでまたHugoの出番。ショートコードを使うことで、一文字ずつタグで囲む手間のかかる作業もおまかせできちゃいます! ショートコード便利!

layouts/shortcodes/kenten.html

{{range findRE ".{1}" .Inner}}<span class="kenten" data-symbol="●">{{.}}</span>{{end}}

上記では、ショートコードの内部にあるテキストをHugoのfindRE関数で一文字ずつに分解したあと、rangeを使ってそれぞれHTMLタグで囲んでいます。

書く時

「あなたが{{<kenten>}}犯人ではありません{{</kenten>}}ね、山田さん」

出力してくれる時

「あなたが<span class="kenten" data-symbol="●">犯</span><span class="kenten" data-symbol="●">人</span><span class="kenten" data-symbol="●">で</span><span class="kenten" data-symbol="●">は</span><span class="kenten" data-symbol="●">あ</span><span class="kenten" data-symbol="●">り</span><span class="kenten" data-symbol="●">ま</span><span class="kenten" data-symbol="●">せ</span><span class="kenten" data-symbol="●">ん</span>ね、山田さん」

このHTMLを手で書くとなると相当に手間ですが、上のショートコードぐらいなら普通に使えますね!

ほんとはCSSが標準でInDesign並みにルビの見た目をいいんですけど、まあ未だにChromeですらサポートされてないruby関連プロパティが今後使えるようになるとは思えないし、そもそもその2つのプロパティがサポートされたところで美しい組版には程遠いしで、CSSで強引に再現するしか無いというお話と、Hugoのショートコードは便利だなぁというお話でした。
あ、「いじれるようになってれば」に打った圏点に意味はないです。でもまあひらがなが続く文章で読みやすくするためにも使われたりしますね、圏点。好きです。

Prev前の記事

アイキャッチ画像
[Hugo] How to write a comment which for hidden (or shown) in HTML

Next次の記事

アイキャッチ画像
【PS4】「The Last of Us Part II」レビュー。ポリコレと良いところとイマイチなところ