HTMLのrubyがイマイチと感じた時にCSSでフリガナを付ける方法
htmlにrubyってのがありますよね。漢字にフリガナを振ったりするアレです。
でも、こいつがなかなかイマイチなやつで。。最近は未対応ブラウザも(たぶん)無くなって、かなり良い感じに振り仮名を付けられるようになりましたが、いろいろ試すとやっぱり使えない(イマイチ)。
という事で、今回はCSSで漢字にルビ(振り仮名)を付ける機会がありましたので、方法を記事にしておきたいと思います。
~ 目次 ~
ルビの配置に関する問題
2023年1月時点で、ルビのレイアウトについて私が気になる点は以下の2点です。
将来的には変わっているかもしれませんので、ご了承ください。
ruby-align が効かない
私の感覚では「ruby-align : center」としてルビは中央配置にしたいのですが、ruby-alignはFirefoxでは対応しているようですが、未対応のブラウザでは均等割付のような感じになってしまいます。
「昨日、近所で小啄木鳥を発見した。」
上の例のように、文字間隔がバラバラになってしまいます。これは好みの問題もありますが、個人的には中央寄せになってほしいかなと。
ruby-overhang が使えない
こっちの方が問題かもしれません。前後のテキストに対するルビのかかり方を指定するらしい ruby-overhang というプロパティを発見したのですが、こいつが上手く効いてくれませんでした。
私の解釈違いなら申し訳ありませんが、ググった情報を見る限り「autoで前後のテキストにかかってOK」という事で、フリガナが長い場合、左右にはみ出してくれるのかと思いました。が…
「たしかに承りました。」
お使いのブラウザで、どう見えているかは確証がありませんが、上の例のようなルビが長くなってしまう場合に、ルビがはみ出してくれるのではなく、元テキストの字間が広げられてしまいます。
ちょっとこれは我慢できません。。
もっと追及して調査するのも手ですが、こういった不安定な挙動の場合、たいがい時間の無駄です。という事で、今のところ私はルビはCSSで振る事にします。
CSSでフリガナを振ってみたサンプル
「昨日、近所で小啄木鳥を発見した。」
「たしかに承りました。」
どうでしょうか。私の感覚では、おおよそイメージ通りに綺麗にフリガナが振れました。
一般的な文章すべてに対応させたい場合に注意する点
一般的な漢字の中で一番読みの長い漢字は、例でも挙げた「承」の訓読み(うけたまわ)などの5文字だそうです。
私の主観ですが、5文字まで綺麗に見えるようにするにはルビの文字サイズは元テキストの45%程度までにしないと、前後のテキストに被りすぎて見栄えが悪くなります。ルビを45%程度にする事を考えると、あまり元テキストのサイズが小さいとルビが読みづらくなってしまいますね。
また、レアケースかもしれませんが、下のように読みが5文字の漢字のそばに読みが4文字の漢字が出現する場合を想定すると、元テキストの letter-spacing が、最低0.14em程度は必要なようです。
「私が承りました。」
とまあ、ゴチャゴチャ書きましたが、細かい部分は使用環境に合わせて調整してください。
サンプルコード
rubyタグは使用しますが、それ自体は非表示にしてCSSで用意したルビを表示します。
HTML
ちょっと見づらくなってしまうので改行を入れてあります。
1 2 3 4 5 6 |
<p> <ruby data-ruby="わたくし">私<rt>わたくし</rt></ruby> が <ruby data-ruby="うけたまわ">承<rt>うけたまわ</rt></ruby> りました。 </p> |
rubyタグの data属性にrtタグと同じ内容を入れておきます。
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
p{ font-size: 18px; } ruby[data-ruby] rt { display: none; } ruby[data-ruby] { position: relative; display: inline-block; } ruby[data-ruby]::after { content: attr(data-ruby); position: absolute; transform: translate(-50%, -1.7em); display: block; left: 50%; top: 0; white-space: nowrap; font-size: 44%; letter-spacing: 0; } |
HTMLの方でdata-rubyに記述しておいたルビテキストを、CSS関数で取得して疑似要素のcontentにします。
後はpositionをabsoluteにして、テキストの上に中央寄せで配置するだけです。
ハマった点。。
実はカンタンに実装できたのですが、独自挙動でおなじみの iPhone(ios safari)で問題が出てハマってしまいました。iPhoneは好きで使っていますが、コーディングする立場で見ると「IEの次はお前かいっ!」って感じがしなくもありません。
ちょっと話がそれましたが、改行位置の関係でフリガナを振った要素が行の先頭にきてしまった時だけ、フリガナが上の行の末尾に残ってしまう状況でした。
しばらく格闘した結果、解決した方法は疑似要素をbeforeからafterに替えただけ。なぜか、beforeを使用すると前述のような問題が出ます。どうせpositionはabsoluteだし「どっちでも一緒やろ!」と思っていましたが、とにかくbeforeだとダメでした。
サンプルコードのようにafterで実装すると、iosでも問題は見つかりませんでした。
最後に
どうでしょうか。ここまで読んで下さった方は、もしかしたらCSSでフリガナ、付けてみちゃいました?
綺麗にできましたか?
まっ、私のように細かい事を気にしている人も少ないんでしょうけど、どなたかのお役に立てば幸いです。