ruby要素を擬似的に再現する

 Internet Explorerが先行実装したruby要素をMoziilaやOperaなどの他のモダンブラウザでも利用できるようにします。
 また、ruby要素はHTML4.01では未定義の要素ですので、使用した場合invalidとなりますが、この方法の場合汎用要素のspanを使用する為、未定儀の要素を使用するよりはより仕様に近い記述になります。

まずはやってみる

 span要素のclass属性にそれぞれruby、rb、rt、rpを指定します。

<span class="ruby">
  <span class="rb">Internet Explorer</span>
  <span class="rp">(</span>  <!-- ルビ非表示用カッコ -->
  <span class="rt">インターネットエクスプローラ</span>
  <span class="rp">)</span>  <!-- ルビ非表示用カッコ -->
</span>

 実際のcssでの記述は、

span.ruby {
  position: relative;
}

span.rt {
  position: absolute;
  left: 0px;
  top: -1.33em;
  font-size: 60%;
}

span.rp {
  display: none;
}

 のようになります。
 なお、topプロパティに指定する値は環境によって調整が必要だと思います。おそらく段落のline-heightやfont-sizeが関係しているのではないかと思いますが、未調査。

 実際の表示例は次のとおりです。

 Internet Explorerインターネットエクスプローラが先行実装したruby要素をMoziilaやOperaなどの他のモダンブラウザでも利用できるようにします。
 また、ruby要素はHTML4.01では未定義の要素ですので、使用した場合invalidとなりますが、この方法の場合汎用要素のspanを使用する為、未定儀の要素を使用するよりはより仕様に近い記述になります。

ルビ文字列を中央揃えにする

 このままだと、spanで擬似的に再現したrubyの擬似rtが、振り仮名を振る対象文字列に対し均等に割り付けることができません。均等に割り付けるためには、擬似rtの幅を擬似rubyと同じにし、text-align:justifyを指定する必要がありますが、text-align:justifyは多くのブラウザで未実装です。ここでは均等割付は諦め、中央寄せにすることにします。

 振り仮名を振る対象の文字列の幅と擬似rtの幅を揃えるのはCSSでは不可能です。そこで、振り仮名対象文字列の長さに応じてclassを指定し、そのclassごとに異なる幅を指定する方法を取ります。

<span class="ruby tetra">
  <span class="rb">先行実装</span>
  <span class="rp">(</span>  <!-- ルビ非表示用カッコ -->
  <span class="rt">せんこうじっそう</span>
  <span class="rp">)</span>  <!-- ルビ非表示用カッコ -->
</span>

 まず、HTMLはこのように擬似rubyにclass属性を追加してやり、CSS側で

span.ruby {
  position: relative;
}

span.rt {
  position: absolute;
  left: 0px;
  top: -1.33em;
  font-size: 60%;
  text-align: center;
}

span.mono span.rt {
  left: -2.25em;
  width: 6.1em;
}

span.di span.rt {
  left: -2.25em;
  width: 7.7em;
}

span.tri span.rt {
  left: -2.25em;
  width: 9.3em;
}

span.tetra span.rt {
  left: -2.25em;
  width: 10.9em;
}

span.penta span.rt {
  left: -2.25em;
  width: 12.5em;
}

span.rp {
  display: none;
}

とし、monoは1文字、diは二文字、triは三文字……のように、それぞれの文字数毎にclassを割り当てます。下記が表示例です(※わかりやすいように擬似ルビの前後にスペースを入れてあります)
 leftプロパティに指定する値もtopプロパティ同様に各環境で調整してください。

 Internet Explorerが 先行実装せんこうじっそう したruby要素をMoziilaやOperaなどの他のモダンブラウザでも利用できるようにします。
 また、ruby要素はHTML4.01では 未定義みていぎ の要素ですので、使用した場合invalidとなりますが、この方法の場合 汎用はんよう 要素ようそ のspanを使用する為、 定儀ていぎ の要素を使用するよりはより仕様に近い記述になります。

 この例では順に先行実装、未定儀、汎用、要素、未、定義に振り仮名を指定しました。実際には連続した熟語で文字ごとに振り仮名を振ると、振り仮名が重なる恐れがありますのでご注意ください。

ルビ文字列中での改行を禁止する

 このままだと禁則処理ができません。
 通常、ルビが振られた単語は分離禁則となり、単語中で改行を行なうことができません。
 そこで、

span.ruby {
  position: relative;
  white-space: nowrap;
}

を加えてやります。こうすることでルビが振られた単語中では改行されないようになります。

 なお、word-breakプロパティを用いても同様のことができますが、このプロパティは現段階ではInternet Explorerが先行実装しているだけでまだ実装段階ではありません。他のブラウザで正しく表示されるとは限りませんのでご注意ください。

ところで

 今回の方法でルビを振ると、サンプルを見てもらえば分かるとおり、行の高さのズレが生じません。XHTML1.1のruby要素を普通に使うと、デフォルトのスタイルシートではルビを振った文字を含む行の高さが他より大きくなってしまいます(ちなみに、かつてXHTML1.1を使っていた頃、スタイルシート側で調整を試みましたが、複数のブラウザ間で表示ズレが発生し、上手く行きませんでした)。
 実際にruby要素を多用した文書を読めば分かるかと思いますが、行の高さが一致しない文書は読んでいて非常に疲れます。カッコ書きが勧められるのはルビが読みにくいからというのもあるかもしれません。

 もしあなたが文書の再利用性を高めたいと思うなら、迷わずXHTML1.1へ移行しruby要素を用いるべきです。ある仕様で定義された要素は、その仕様をサポートするアプリケーション側でのデータの抽出や加工が容易です。また、動作保証もされます。
 例えばテキストビューアのazurなどの、青空文庫形式のXHTMLでも読めるように、ということであれば、XHTML1.1を用い、その他青空文庫で定義されたクラス名を使用して文書を作成するのがいいと思います。
 自分でデータを利用するプログラムやスクリプトを記述する上では、仕様に定義された要素かどうかということはあまり関係ありません。

 このページで示した方法というのは、ある種のバッドノウハウです。そうであると知りつつ、可読性の向上という目的のためや、Webサーバの環境がXHTMLに適合しないという原因のために、あえてHTML4.01を用いるという選択肢は、私はありだと思っています。

おまけ

 JavaScriptの勉強も兼ねて、ページ読み込み時にclass="ruby"なspan要素から、ruby要素を擬似的に再現するコードを動的に生成するスクリプトを書いてみました。

 要するに、

<span class="ruby">漢字(ふりがな)</span>

をJavaScriptで

<span class="ruby di"><span class="rb">漢字</span>
<span class="rp">(</span>
<span class="rt">ふりがな</span>
<span class="rp">)</span></span>

に変換する、というだけのことです。

 百聞は一見にしかずというので、サンプル - spanから擬似的にrubyを動的生成をどうぞ。