幅を節約したリスト表示
「Theme Rep」の「登録テーマ一覧」のパネルは、変更先のテーマを指定するインターフェイスですが、このパネルの幅が広過ぎると「記事リスト」に被るので幅を節約する必要がありました。
問題は、狭くなった幅で隠れるテーマの表示の仕方でした。 最初は JavaScriptでリストの文字列の長さを取得して、上限幅を越えた分のマイナスの「text-indent」を指定するコードを試作。 しかし、これは上手く動作せず、CSSの「direction: rtl」に目を着けました。
英語は左から右に文字を並べますが、「direction: rtl」は右から左へ並べる事を指定するものです。 この指定を使うと、文字を「よこはま」➔「まはこよ」という表示にでき、右から書き始める言語に対応できるわけです。
この「逆方向に並べる」機能を使えば、「overflow: hidden」で右端が隠れた枠の表示を、「右詰め」で左端が隠れた表示に変える事が出来ると考えたわけです。 この様な「右端を隠す」➔「左端を隠す」というデザインは、外側の枠幅と内側の表示要素の幅が固定の場合は簡単ですが、表示要素の幅が不定の場合は案外と難しいのです。
サンプルと「unicode-bidi」について
実際の表示を見ると判り易いです。 下の6行のリストにポインターを乗せると、右に隠れた部分があれば、それが表示されます。
登録テーマ一覧
- テーマ1 ●▢▢▢▢▢(172)
- テーマ2 ●▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢(234)
- ●テーマ3 ▢▢▢▢▢(172)
- ●テーマ4 ▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢(234)
- ●テーマ5 ▢▢▢▢▢(172)
- ●テーマ6 ▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢(234)
◎「テーマ1」「テーマ2」は目的通りの結果です。「テーマ1」は溢れていないので変化せず、「テーマ2」は隠れていた部分が表示されます。行中に「●」がありますが、これは後で説明します。
「テーマ1」~「テーマ4」の HTML
「テーマ1」~「テーマ4」の CSS
CSSの上側の項は、「幅360px」以上の文字列の右端を隠す指定です。 下側の項は、ホバー時に行を「右から左の表記」に置換える指定です。
◎「テーマ3」「テーマ4」は、「1、2」との違いは「●」が行頭に書かれている点だけで、CSSは同条件です。 ところが「3、4」は、妙な事が生じます。「●」が行末に送られた上で、幅が溢れている「4」は右詰めになり左側が溢れます。
「1、2」の「●」は移動しないのに、「3、4」は移動します。 この移動は、どうも行頭に「記号文字」や「句読点」がある場合に、これを文字列とは別種のものと判断して、順序を入れ替える様です。 これが「direction: rtl」の仕様と受け取るしかありません。
不要な置換えを抑止する
「3、4」の様な「記号文字」がテーマに使われる事は、実際にあり得ます。 この妙な置換えを抑止しないと「direction: rtl」が使えません。
そこで、テーマの文字列を「span要素」等で囲み、その内部には「direction: rtl」が及ばない様にします。
「テーマ5」「テーマ6」の HTML
テストしてみると、「span要素」で囲んだだけでは「3、4」と状況は同じです。つまり「direction: rtl」は継承されるという事です。
そこで、「span要素」に「uni」の class名を付けて、以下の指定をしました。
「テーマ5」「テーマ6」のために追加した CSS
この厄除けが効いて、「テーマ5」「テーマ6」は「記号文字」の移動が無くなり、完全に目的を達しました。
「unicode-bidi」の指定可能な値には、継承を抑止できそうな「initial」「isolate」「unset」などの値がありますが、「plaintext」以外の値は全て無効でした。 こういう場合の抑止は「plaintext」しか無い様です。
まとめ
「direction: rtl」の指定は「embedid」「override」が必要と、多くの場所で書かれています。
インラインレベル要素で direction プロパティに効果を持たせたいときは、unicode-bidi プロパティの値が embed もしくは override である必要があります。
これは、最初に書いた様に「よこはま」➔「まはこよ」の置換えを目的とする場合です。 このページの目的は本筋とは異なる利用で、この指定をしていないわけです。
「direction」を指定した結果は想定出来ない事が多く、実験しながら実装することになります。 上の例で、溢れない行が「右詰め」になりません。 全ての行は、親要素や先祖要素から「text-align: left」を継承していて、それに対して「direction: rtl」は無関係という事です。
良く調べると、「direction」は、行頭や行末の「記号文字」のみの配置を変えるのでは無い様です。 以下の全ての行は「plaintext」の抑止をせずに「direction: rtl」の指定をしただけの状態です。
- 特殊な置き換えが生じます。
- 、特殊な置き換えが生じます,
- ▢■■■4bite(漢字)の記号文字,,, )(
- + 123456-
- + 123456-漢字
- + 123456-漢字+(
- + 123456-漢字+(789)
最後の4行は、記号文字・半角英数・漢字 などを追加して、倒置の規則を調べていますが、最後の行は以下の文字・文字列として区分けされて、全てが倒置されている事がわかります。
▪半角スペースも1区分になりうる
▪記号文字を含まない文字の連続は1区分として扱われる
このルールで 4、5、6 行の区分が説明できます。
「+」「 」「123456」「-」「漢字」「+」「(」
しかし、最後の 7行目の区分は以下の様に変化し、それだけで説明できません。
「+」「 」「123456」「-」「漢字+(789)」
この区分は複雑なルールに従っている様で、何処かに策定された仕様書があると思われます。「direction」を完全に使いこなすには、この区分の仕様を理解する必要がある様です。 なお、上の全ての行は、やはり「plaintext」で倒置を抑止できました。
以下に「direction」の機能を纏めたMDNの説明があります。 興味がある方は参照ください。