12周年記念パーティ開催! 2024/5/10(金) 19:00

ウェブページでのルビと圏点 第1回 ルビのHTML

現在ではメジャーなブラウザで基本的なルビは問題なく扱えるようになっており、マークアップも以前よりシンプルになっています。基本的なルビの記述方法に加え、分割したルビや複数のルビを見てみましょう。

発行

著者 國仲 義則 フロントエンド・エンジニア
ウェブページでのルビと圏点 シリーズの記事一覧

HTMLのルビ

ウェブページ上でルビ(振り仮名、英語ではruby annotation)を扱えるようになったのは1999年、Internet Explorer 5の独自実装からでした。

その後に標準仕様として採用され、現在ではメジャーなブラウザで基本的なルビは問題なく扱えるようになっています。

Firefoxはルビの実装がもっとも遅れていたブラウザで、かつてはCSSのdisplay: inline-tableを使って見た目だけを再現しようとするテクニックも存在しました。

しかし、Firefox 38においてルビが使えるようになったとき、他のブラウザよりも進んだ実装が実現されました。これは2021年8月現在でも変わっておらず、ルビにおいてはFirefoxが一歩抜け出している状況です。

このシリーズでは、このウェブページでのルビについて見ていきます。また、ルビと同じように文字の脇に付ける点である、圏点(けんてん)についても、知っておきましょう。

ルビのマークアップ

現在、ルビのマークアップに使えるHTML要素は以下の3つです。

  • ruby
  • rp: ruby parentheses
  • rt: ruby text

ルビであることを示すruby要素を使い、その内部でrprt要素を使います。

基本構造としては次のようになります。

<ruby>
  ルビ基底文字列
  <rp>フォールバック用の開き括弧</rp>
  <rt>ルビ文字列</rt>
  <rp>フォールバック用の閉じ括弧</rp>
</ruby>

たとえば、「春」という漢字に「はる」というルビを振るとするなら、「春」がルビ基底文字列で、「はる」がルビ文字列です。

rp要素はルビのフォールバックとして括弧類を、rt要素はルビ文字列(振り仮名部分)を記述します。

かつて存在したrtc要素(ruby text container)、rb要素(ruby base)とrbc要素(ruby base container)は削除されました。HTML5では採用されていましたので、HTMLに記述しても描画に問題が起きることはありません。しかし現在は非標準となっています。

HTMLのルビはマークアップが面倒に感じるかもしれませんが、かつてに比べればシンプルになりました。

<!-- かつてのマークアップ -->
<p>
  <ruby><rb>春</rb><rp>(</rp><rt>はる</rt><rp>)</rp></ruby>
</p>
<!-- 閉じタグ省略。IEはrbの閉じタグを省略するとおかしくなる -->
<p>
  <ruby><rb>春</rb><rp>(<rt>はる<rp>)</ruby>
</p>

<!-- 現在 -->
<p>
  <ruby>春<rp>(</rp><rt>はる</rt><rp>)</rp></ruby>
</p>
<!-- 閉じタグ省略 -->
<p>
  <ruby>春<rp>(<rt>はる<rp>)</ruby>
</p>

ルビの多言語対応

ルビ文字列がページの言語と異なっている場合は、ルビ以外の要素と同じくlang属性を使うことで対応可能です。

<p>
  <ruby>春<rp>(</rp><rt lang="en">Spring</rt><rp>)</rp></ruby>
</p>

気をつけるのは、lang属性をつける対象はルビ文字列であるrt要素であるということです。ruby要素につけてしまうと、基底文字列までlang属性で指定した言語として扱われてしまいます。

rp要素を使う必要はあるのか?

rp要素は、ルビ非対応の環境向けのフォールバック要素です。現在、ルビの表示自体に非対応のブラウザはまずないでしょう。

Can I Useのrubyを見ると非対応になっているOpera Miniですが、Android Opera Mini 58で対応を確認しました。

手元の現行環境では、Windows向けのブラウザであるNetReader Neo クラシックモード 2002(ビルド11)における「テキスト画面」だけがサポートしていませんでした(この画面はテキストブラウザのようなもの)。「グラフィカル画面」およびNeoモードではサポートされています。

1行目はrp要素を記述した場合、2行目はrp要素を省略した場合

ルビをサポートしないブラウザが少なくなっている現状、rp要素は必要でしょうか。

もし作成するページでルビ非対応の環境を切り捨てるのなら、rp要素を使わないという選択もありかもしれません。しかし、HTMLを解釈して表示するのはウェブブラウザだけではありません。ルビをサポートしない環境でも違和感なく表示されることを考えると、可能なかぎりrp要素を使っておくべきでしょう。有名どころでは、Gmailはルビを表示できません。

rp要素を含むルビのマークアップは大変です。ですが、頻繁に使うのなら手作業ではなく機械的に処理できるようにしておけば、rp要素を含むルビであっても苦にはならないでしょう。

HTMLの前段階のルビ構文

HTMLへの変換が前提の文書において、サポートされているルビ構文を紹介します。

Markdown拡張

多くのMarkdown構文はルビをサポートしていませんが、PHP Markdown Extraの拡張である電子書籍用Markdown構文「でんでんマークダウン」(電書ちゃんのでんでんマークダウン - でんでんマークダウン)はルビをサポートしています。

でんでんマークダウンでの記述方法

{基底文字列|ルビ文字列}

{春夏秋冬|しゅんかしゅうとう}

さらにモノルビまでサポートしています(モノルビについては後述します)。

でんでんマークダウンでのモノルビの記述方法

{春夏秋冬|しゅん|か|しゅう|とう}

JavaScriptのMarkdownライブラリの1つ、markdown-itのプラグインも非公式ながら存在しています。Markdownでルビを使いたい場合は、このようなライブラリを用いるか、自身で各Markdownライブラリを拡張する必要があるでしょう。

ウェブ小説

小説投稿サイトは数多くあり、ルビをサポートしているサービスも多いのですが、その構文は多様です。そんな状況ですが、多くのサイトがサポートしているのが青空文庫記法(青空文庫作業マニュアル【入力編】 - 4-1. ルビ)をベースとしたルビ構文です。

青空文庫記法でのルビの記述方法

|基底文字列《ルビ文字列》

|春夏秋冬《しゅんかしゅうとう》

サイトごとに細かい仕様は異なっていますが、基本的にはこのような構文となります。

ルビのマークアップ例

ここからは、実際のマークアップ例を見ていきます。

なお、ルビのHTMLは長くなりがちなので、記事内では必要に応じて改行を入れています。要素ごとに改行すると環境によっては改行が半角スペースとして表示されてしまいますので、実際のマークアップでは>の前で改行するか、改行を入れないことをおすすめします。

基本的なルビ

<p>
  1年のうちに
  <ruby>
    春夏秋冬<rp>(</rp><rt>しゅんかしゅうとう</rt><rp>)</rp>
  </ruby>
  があります。
</p>

もっとも標準的な使い方です。先に説明した基本構造と同じHTMLです。

モノルビ

ruby要素内のルビ基底文字とルビ文字列のセットは1つでなくても構いません。

<p>
  1年のうちに
  <ruby>
    春<rp>(</rp><rt>しゅん</rt><rp>)</rp>
    夏<rp>(</rp><rt>か</rt><rp>)</rp>
    秋<rp>(</rp><rt>しゅう</rt><rp>)</rp>
    冬<rp>(</rp><rt>とう</rt><rp>)</rp>
  </ruby>
  があります。
</p>

組版では「モノルビ」と呼ばれるもので、1文字ずつルビを振る方法です。

分割しない場合と何が違うのかというと、描画結果が異なります。基本的なルビの例と並べて比較してみましょう。

基本的な使い方の場合、「春夏秋冬」というかたまりに対して「しゅんかしゅうとう」というルビがついています。

しかし、モノルビでは「春夏秋冬」それぞれの文字に、それぞれのルビがついているのがわかります。

分割したルビ

ルビ分割のモノルビ以外の例としては、人名が挙げられます。

<ruby>
  伊能<rp>(</rp><rt>いのう</rt><rp>)</rp>
  忠敬<rp>(</rp><rt>ただたか</rt><rp>)</rp>
</ruby>

このように、姓と名で分割する例もあります。

複数のルビ文字列

1つのルビ基底文字列に対し、複数のルビ文字列を付与したい場合があります。

この要件は、かつてrtc要素が存在していたころは次のように記述可能でした。

<ruby>
  基底文字列
  <rp>(</rp>
  <rt>ルビ文字列A</rt>
  <rp>)</rp>
  <rtc>
    <rp>(</rp>
    <rt>ルビ文字列B</rt>
    <rp>)</rp>
  </rtc>
</ruby>

このマークアップは、現在でもFirefoxで使用可能です。しかし非標準となっています。

現在のHTML標準ではruby要素をネストさせ、ルビが振られた要素に対してルビを振るという手順で複数のルビを実現します。

<ruby>
  <ruby>
    基底文字列
    <rp>(</rp>
    <rt>ルビ文字列A</rt>
    <rp>)</rp>
  </ruby>
  <rp>(</rp>
  <rt>ルビ文字列B</rt>
  <rp>)</rp>
</ruby>

実践

次の画像のようなルビを振りたい要件があったとします。

これを新旧2つのマークアップで比べてみます。

<!-- 以前のマークアップ -->
<p>
  鬼門は
  <ruby>
    北東<rp>(</rp><rt>ほくとう</rt><rp>)</rp>
    <rtc>
      <rp>(</rp><rt>うしとら</rt><rp>)</rp>
    </rtc>
  </ruby>
  の方角です。
</p>

<!-- 現行のマークアップ -->
<p>
  鬼門は
  <ruby>
    <ruby>
      北東<rp>(</rp><rt>ほくとう</rt><rp>)</rp>
    </ruby>
    <rp>(</rp><rt>うしとら</rt><rp>)</rp>
  </ruby>
  の方角です。
</p>

この表示結果を見てみましょう。

前述したように、Firefox以外はrtc要素による複数ルビをサポートしていませんので、意図通りに表示されません。

Firefoxで見比べてみましょう。

rtc要素を使ったHTMLでは、ルビが上、下の順で表示されます。

一方、rubyをネストした新しいマークアップでは、どちらも上についており、より上位階層のルビが上に来ます。

次回以降の回で解説しますが、ルビの配置についてはCSSで対応可能です。しかしより上位にあるものを下に置きたいという場合はrubyを子に持つruby要素を対象にしなくてはならず、現在実装されているセレクタ状況では厳しいでしょう。

下に置きたいルビについては、なんらかのクラス名を付与して対応するほうがよいでしょう。

新しいマークアップの利点は、ChromeなどのBlink系ブラウザとSafariでも複数のルビを付与可能なことです。CSSを工夫すれば上下にルビ文字列を配置可能です。

Internet Explorerはどちらの場合でも対応できません。今後対応されることもありませんので、複数のルビを検討している場合はサポートするかどうか考えなくてはならないでしょう。

ルビ文字列のコピーと貼り付けについて

ここまでで、ウェブページ上ではルビは基底文字列の上(下)に表示されることはわかりましたが、このテキストを選択してコピーし、それを貼り付けるとどうなるでしょうか。

先ほどの「春夏秋冬」のデモで試してみましょう。

このデモページを全選択して、任意のテキストエディタに貼り付けます。すると、Firefoxの場合は次のような結果を得られるでしょう。

1年のうちに春夏秋冬があります。
1年のうちに春夏秋冬があります。

Firefoxでコピーした場合はルビ文字列が貼り付けられません。ルビ文字列を貼り付けたい場合、ルビ文字列のみを選択してコピーする必要があります。

他のブラウザの場合は、rp要素を除いた部分が貼り付けられます。

1年のうちに春夏秋冬しゅんかしゅうとうがあります。
1年のうちに春しゅん夏か秋しゅう冬とうがあります。

Chromeの場合はCSSでrt {use-select: none}でFirefoxと同等の結果を得られますが、Safariではうまくいきません。

JavaScriptを駆使すればどうにかなるかもしれませんが、基本的には何もしないほうが閲覧者にとって違和感のない動作になるのではないでしょうか。

アプリケーションによってはFirefoxでルビ文字列が貼り付けられることもある

Firefoxはルビ文字列をコピーしていないわけではないようです。

たとえば、Gmailのメール作成でリッチエディタに貼り付けると、次のようになります。Googleドキュメントやスプレッドシートでも同様です。

1年のうちに春夏秋冬(しゅんかしゅうとう)があります。
1年のうちに春(しゅん)夏(か)秋(しゅう)冬(とう)があります。

同様の現象は、Typora(Markdownエディタ)の通常モードでも確認できます。

このとき、rp要素も入力されていることは注目したいところです。しっかりとフォールバックとしての機能を果たしています。

まとめ

ルビのHTMLは変化しており、気がつくと廃止になっている要素もありました。特にrb要素はHTML5の知識のままでは非標準になっていることを知ることができません。

互換性を保つために古い要素もしばらくはサポートされることでしょうが、今後は新しいマークアップを意識しておきたいものです。

次回からはルビ関係のCSSについての説明です。