今回の対戦相手は <ruby> です。 強敵です。 強敵だからこそ早めに叩くべきですし、 叩けないと分かれば早目に (この企画がムリっていう) 諦めが付きます。
ルビを振るとグリッドからズレてしまう
はい。 酷いですね。 醜くって見難いですね。 がんばります。
ズレる原因は?
ズバリ、 ルビのせいです。 いや、 当たり前ですのでもう少し詳しく。
そもそも、 ルビの仕組みはこんな感じです。
<p> ルビを <ruby> 振 <rt> ふ </rt></ruby> ると </p>
ルビを振りたい文字 (親文字) を <ruby> タグで囲み、 その中に読み仮名を <rt> タグで囲んでいます。 んで、 この <rt> タグがズレる原因です。
この様に、 高さ 14px の 「display: block;」 として鎮座しています。
試しに、 「display: flex;」 なんてしてみると、
あ、 なんかイケそう。 と思ったのですが、 ここからが動かない。 動きません。
どうにか動かせないかと、 いろいろとググってみたのですが目ぼしい情報は見当たりません。
そんな中、 こんな記事に辿り着きました。
data-ruby 方式
早速と試してみると、
イイ!すごくイイ!めったに使わない感嘆符を使ってしまうくらいイイ!
だが惜しい。 ルビがセンター揃えになっている。 ここは是非とも justify っぽくしたい。 と思うと同時に無理だと察しが付く。 単行・最終行には justify が効かないってのが世の常 (?) ですしね。
一応調べてみると、 あった。
text-align-last: justify;
スゲー!一日に二度も感嘆符を使うとは。
でも Safari は未対応、、、 感嘆符返せよ、、、 項垂れた先に辿り着いたのはココでした。
ルビ文字を <span> で分割
ふぅ、、、 もう感嘆符はでない。 達成感と安堵感に包まれます。
それではカスタマイズ方法です。
カスタマイズ
基本方針は、 data-ruby 方式と同じく、 <rt> タグを非表示にし、 別の手段でルビ文字を表示します。
data-ruby 方式では疑似要素を利用しているので、 実装はお手軽なのですが、 反面コントロール性に欠けてしまいます。
今回はルビ文字を <span> で分割する方法でカスタマイズします。
jQuery
/* ルビ */
jQuery(window).on('load', function (){
var fz = parseInt(jQuery('body').css('font-size'));
jQuery('ruby').each(function() {
var ow = jQuery(this).outerWidth();
var ruby_html;
var yomigana;
var yomigana_span = '<div class="thx_yomi">';
ruby_html = jQuery(this).html();
yomigana = jQuery(this).children("rt").text();
yomigana_length = yomigana.length * fz / 2;
if (yomigana.length == 1) {
yomigana_span = '<div class="thx_yomi thx_yomi_mono">';
}
if (yomigana_length + fz / 2 > ow) {
yomigana_span = '<div class="thx_yomi thx_yomi_long">';
}
if(yomigana_length > ow){
jQuery(this).css('width', yomigana_length);
}
for(var i=0; i< yomigana.length; i++) {
yomigana_span += '<span>'+yomigana.substr(i, 1)+'</span>';
}
yomigana_span += '</div>';
jQuery(this).html(ruby_html+yomigana_span);
});
});
それでは順に見ていきます。
ruby_html = jQuery(this).html();
yomigana = jQuery(this).children("rt").text();
yomigana_length = yomigana.length * fz / 2;
ruby_html に <ruby> タグ内の html を確保し、 yomigana に <rt> タグ内のテキスト (読み仮名) を入れます。
yomigana_length で読み仮名の px 数を計算します。
var yomigana_span = '<div class="thx_yomi">';
if (yomigana.length == 1) {
yomigana_span = '<div class="thx_yomi thx_yomi_mono">';
}
if (yomigana_length + fz / 2 > ow) {
yomigana_span = '<div class="thx_yomi thx_yomi_long">';
}
yomigana_span に <span> 分割された読み仮名を追加していきます。
<span> 分割された読み仮名は <div> で囲む必要があるので、 事前に <div class="thx_yomi"> を追加しておきます。
また、 読み仮名が一文字の場合はクラスに thx_yomi_mono を追加し、 逆に読み仮名の文字数が多い場合は thx_yomi_long を追加しています。
if(yomigana_length > ow){
jQuery(this).css('width', yomigana_length);
}
読み仮名の px 数が <ruby> の文字 (親文字) よりも大きい場合、 <ruby> の width を読み仮名の px 数に合わせます。
for(var i=0; i < yomigana.length; i++) {
yomigana_span += '<span>'+yomigana.substr(i, 1)+'</span>';
}
yomigana_span += '</div>';
読み仮名を一文字ずつ <span> で分割し、 yomigana_span に追加していきます。
jQuery(this).html(ruby_html+yomigana_span);
確保していた <ruby> タグの html に yomigana_span を追加して、 <ruby> タグの html を書き換えます。
scss
.thx_yomi {
font-size: $font_size / 2;
position: absolute;
top: - ($line_space - $font_size / 2) * 0.4;
display: inline-flex;
justify-content: space-between;
left: $font_size / 4;
right: $font_size / 4;
line-height: $font_size / 2;
}
.thx_yomi_long {
left: 0px;
right: 0px;
}
.thx_yomi_mono {
display: inline-block;
}
読み仮名を親文字の上に配置するため、 position: absolute; とします。
display: inline-flex; と
justify-content: space-between; の二行で <span> 分割した読み仮名を均等配置します。
justify-content: space-between; の効果を以ってしても、 一文字の場合は左によってしまいますので、 display: inline-block; とする事によってセンター配置にしています。
ruby {
position: relative;
display: inline-block;
text-align: center;
rt {
display: none;
.editor-rich-text & {
display: block;
}
}
}
読み仮名が position: absolute; なため、 ベースとなる <ruby> を position: relative; とします。
不要となった <rt> タグを非表示、 エディタ画面では表示する様にします。
まとめ
満足しました ♪
個人的にルビは結構好きなので、 これをグリッド揃え出来た事が素直に嬉しいです。
現状の問題点
和欧間スペース
<ruby> タグを inline-block としているため、 欧文にルビを振った場合に以前設定した和欧間スペースが効かなくなってしまいます。
和欧間スペースそのものを inline-block にし、 margin で余白を取る方法もあるのですが、 行頭でも余白を取ってしまい好ましくありません。
しかしながら、 そもそも和欧間スペースは文中に現れる欧文を際立たせる目的でしたので、 ルビが振られるのであれば十分に際立っているのでスペースは不要かとも思います。
親文字の justify
ルビ文字が多い場合、 現状では親文字はセンター揃えです。 これを justify にするためには、 読み仮名と同様に <span> 分割の必要が出てきます。
ただ、 同じ事をするだけなので処理は可能なのですが、 実際に親文字が justify されたら可読性が落ちるのでは?とも思いますので暫くは様子見したいと思います。
コメント