堀北真希うさぎ
主な作品
堀北真希ちゃんのボシュロム社ソフトコンタクト洗浄液TVCMへの出演に因んで描いた、ソフトコンタクトをつけている堀北真希うさぎの仮想CM動画

ページ案内

強調する文字に傍点を与えるには。

DOMをスタイルに用いる例の一つとして、強調したい文字に傍点を与える処理を書いてみましょう。

強調する文字に傍点を与えるには・目次。

CSSで傍点を与える事の限界。

CSSを用いて無理矢理擬似傍点を実現する事は可能ですが、この方法には幾つかの欠点があります。

フォントの幅が変わると傍点がずれる
閲覧者が見易いフォント幅が適用されている場合に綺麗に傍点が並ぶかどうか分かりません。

だからと言って、CSSでフォントの幅をピクセル単位で強制するのはアクセシビリティの見地から問題があります。

また、フォントが等幅フォントで無い場合には高確率でずれが生じるでしょう。

半角文字が入るとやはりずれる
全角文字を仮定して擬似傍点画像の幅を設定する事になるでしょうから、半角文字が奇数個入ると半分ずつずれる事となります。

この問題点を克服するには一文字ずつに背景画像を指定する事ですが、まさかそのためだけにいちいちタグを書くなんて幾ら何でも馬鹿げております。

しかし、JAVAスクリプトとDOMを用いてプログラム任せにしておけばそれ程面倒では無いでしょう。

ここでは、傍点を綺麗に打てる様にするためのスクリプトを紹介しましょう。

強調する文字に傍点を与える処理の仕様。(平成22年 3月13日 更新)

スクリプトは自由に改変していただいて構いませんが、そのためにも本記事で紹介しているスクリプトの前提条件を仕様として挙げておきます。

対象となる環境は現行のグラフィカルなウェブブラウザとします
具体的には、

となります。

対象はHTML文書内にある全ての二重になっていない<em>要素とします (平成22年 3月13日)
二重になっている<em>要素はHTML 5では更なる強調(従来のHTMLでの<strong>要素に相当)となるため、傍点は適さないと判断しました。

その他の特定の<em>要素は除外したいと言う場合については、後ほどヒントを挙げておきますが、この二重<em>を除外する処理がヒントとなる事でしょう。

傍点に用いる画像は 3ピクセルズ四方の真っ黒なGIF画像とします。
半角の英数字は二文字続けばそのペアに一個の傍点を与えます
半角の記号類には傍点を与えません。その方が見易いと判断したからです。

尚、半角の英数字が一個だけ孤立している状態では、その文字に対して傍点を打つ事とします。

文字参照は記号類と見なし傍点を打ちません
実際にはJIS第一・第二水準から外れる文字を数値文字参照で記述すると言うケースもあり得ますが、ここではこれは想定しない、すなわちそのような文字には傍点は打たないものとします。

尚、文字参照は必ず;で終わっている事とします。

万が一;が漏れている場合は普通の半角文字列と見なして処理されます。

<em>要素内に含まれるタグは勿論傍点処理の対象外です
このような仕様にしておかないと、<em>要素に別の要素がマークアップされている場合におかしな結果になってしまい、その結果<em>要素には生テキストしか入れられないと言う事になってしまいます。

強調する文字に傍点を与えるスクリプトの利用方法。

スクリプトは、HTML文書とは別のファイルで保存し、傍点を打ちたいHTML文書では当該スクリプトを文書中の任意の箇所に<script>要素で埋め込むように記述します。

スクリプトはHTML文書の読込が完了すると自動的に傍点処理スクリプトを起動して傍点が綺麗に描かれるようになります。

強調する文字に傍点を与えるスクリプトのコード。(平成22年 3月13日 更新)

実際の傍点を打つコードは以下の通りです。

onload4setStyle=window.onload;
window.onload=setStyle;

function setStyle() {
    if (onload4setStyle) onload4setStyle();
    // 対応出来ない環境を弾く。
    if (!document.getElementById ||
         navigator.userAgent.indexOf('Opera/6')>-1 ||
         navigator.userAgent.indexOf('Opera 6')>-1) {
        return;
        }

    //    **** 全ブラウザ対象の処理 ****
    // <em>要素に傍点を打つ処理(全ブラウザ対象)。
    var i,j,k,l,m,n;
    var eles=new Array();
    var eles2=new Array();

    // 本処理。
    eles=document.getElementsByTagName('em');
    j=-1;
    while (++j<eles.length) {
        // <em>要素の下位要素となっている<em>要素は弾く。(平成22年 3月13日)
        l=' '+(eles[j].getAttribute('class') || eles[j].getAttribute('className') || '')+' ';
        if (l.indexOf(' __doubleEM__ ')>-1) continue;

        // 二重の<em>要素は弾く。(平成22年 3月13日)
        eles2=eles[j].getElementsByTagName('em');
        if ((k=eles2.length)>0) {
            while (--k>=0) {
                l=(eles2[k].getAttribute('class') || eles2[k].getAttribute('className') || '')+' __doubleEM__';
                eles2[k].setAttribute('class', l);
                eles2[k].setAttribute('className', l);
                }
            continue;
            }

        i=eles[j].innerHTML; l='';
        while(i!='') {
            // タグ。
            m=i.substring(0,1); i=i.substring(1,i.length);
            if (m=='<' && (n=i.indexOf('>')+1)>0) {
                l+=m+i.substring(0,n);
                i=i.substring(n,i.length);
                continue;
                }

            // 文字参照。
            if (m=='&' && (n=i.indexOf(';')+1)>0) {
                l+=m+i.substring(0,n);
                i=i.substring(n,i.length);
                continue;
                }

            // 半角記号。
            if (' (){}[]+-=*/\\!?,."#$%\'~;:@'.indexOf(m)>-1) {
                l+=m; continue;
                }

            // 半角英数字。
            if ('abcdefghijklmnopqrstuvwxyz0123456789'.indexOf(m.toLowerCase())>-1) {
                if (i!='' && 'abcdefghijklmnopqrstuvwxyz0123456789'.indexOf(i.substring(0,1).toLowerCase())>-1) {
                    m+=i.substring(0,1);
                    i=i.substring(1,i.length);
                    }
                }
            l+='<span style="background: transparent url(\'傍点画像への絶対URL\') no-repeat 50% 0; margin: 0; padding: 6px 0 0; ">'+m+'</span>';
            }
        eles[j].innerHTML=l;
        eles[j].style.background='transparent';
        eles[j].style.margin='0';
        eles[j].style.padding='0';
        eles[j].style.fontWeight='normal';
        eles[j].style.fontStyle='normal';
        }
    // <em>要素に傍点を打つ処理はここまで。

    //    **** IE 7.0までのみ対象の処理 ****
}

強調する文字に傍点を与えるスクリプトの動作原理。(平成22年 3月13日 更新)

このスクリプトの処理の流れは以下の通りになります。

  1. 先ず、他のスクリプトなどでonloadプロパティを設定している事も考えられますので、変数onload4setStyleにその内容を退避させ、代わりにsetStyle()を実行させるようにします。
  2. 実際の函数setStyle()では、
    1. 先ず、予め退避していた文書読込後に行なうべき処理があればそれを実行します。
    2. HTML文書内にある全ての<em>要素ノードを集めます。
    3. これらのノードを一つずつ処理して行きます。
      1. 先ず、他の<em>要素の下位にある<em>要素には、上位となる<em>要素の処理時にクラス名に特別な文字列が加えられているので、それがあれば二重<em>要素と見なして以後の処理は行わないものとします。
      2. 続いて、下位に<em>要素があれば、先ほどの特別なクラス名をそれらに与え、その上で元の<em>要素の以下の処理を行わないものとします。
      3. 以上の二重<em>要素チェックを終えたら、対象となる<em>要素のの内容を取り、頭から一文字ずつ切り出して、以下の処理を行ないます。
        1. 切り出した一文字が<であれば、それはタグの始まりと見なし、その後の>までを纏めて切り出してそのまま出力文字列に加えます。
        2. &であれば、それは文字参照の始まりと見なし、その後の;までを纏めて切り出してそのまま出力文字列に加えます。
        3. 半角の英数字であれば、その直後にも半角の英数字がある場合にはその二文字を纏めて一文字と見なします。そうでない場合には切り出した一文字をそのまま傍点の対象とします。
        4. 処理対象となる全角文字または半角文字(この場合は直前の処理で二文字または一文字となる)について、style属性で上端中央に傍点画像を一個だけ背景として表示するようなスタイルを与えた<span>要素として出力文字列に加えます。
          • このため、上にはstyle属性でパディングが与えられます。
          • HTML文書はどのディレクトリ階層に置かれているかは仮定出来ませんので、style属性で指定される傍点画像は絶対URLで記述しておく必要があります。
      4. 全ての文字の処理が終わったら、それを<em>要素の新たな内容とし、また<em>要素のスタイルをDOMで変更しておきます。
        • ここでは、
          • 背景色を透明
          • 文字の太さは普通
          • 文字のスタイルは直立

          と言うスタイルを設定しております。

改造のヒント。(平成22年 3月13日 更新)

今回紹介したコードはご自由に改変してお使いいただけます。

そのためにも、幾つかのヒントを挙げておきます。

特定要素内の<em>要素には処理したくない場合。(平成22年 3月13日 更新)

例えば、<code>要素内にある<em>要素には傍点を付けられると却って見難くなるので傍点を付けたくないと言うような場合です。

実際のコードでは、二重の<em>要素について弾いておりますが、他の要素の場合は、getElementsByTagName() メソッドなどで特定の要素を抽出し、それらの下位にある<em>要素に対して上記で用いた特別なクラス名を付け加える事で弾く事が可能になります。

画像表示を停めている環境に対しての配慮。

画像については何らかの都合で非表示にしている事もあり、その場合強調されている事が伝わらない事も考えられます。

その問題を考慮するのであれば、以下のようにすれば良いでしょう。

  1. 傍点画像とは別に、HTML文書に適用されるスタイルでの通常の背景色と同じ色の 1ピクセル四方の背景画像を用意し、これを<em>要素に新たに与える背景画像とします。
  2. 更に、<em>要素に新たに与える背景には、画像と併せて通常の背景色とは異なる色(例えば背景が白の場合には薄めの色が良いでしょう)を指定するようにします。

コードとしては、<em>要素に新たな背景を与える処理では以下のように変更すれば良いでしょう。

        eles[j].style.background='通常の背景色とは異なる色 url("背景色の画像への絶対URL")';

こうする事で、

と言う訳です。

おまけ・画像ではなくテキストで傍点を打てないか?

では、画像を用いず、例えば などを各文字の上に表示させる事で傍点を表現する事は出来ないのでしょうか。

CSSの仕様を見れば、不可能ではありません。

しかも、この方法なら、

と言う利点もあります。

しかし、その一方で、実装が正しくないと巧く表示されないと言う点があります。

制作者が試して見たところ、

と言う問題がありました。

また、CSSの仕様上の問題もあります。

と言うのは、CSSの仕様上仕方がありません。

更に、

と言う問題も残ります

結局、この方法は望ましいものではあるものの、ちょっと無理のようです。

しらぎくのウェブサイト作成入門サイトマップ



marguerite.site@gmail.com