RTL言語の対応方針
2022年4月ごろに作成した資料です
RTL言語とは
RTL言語(Right to Left)は 右から左方向、かつ上から下方向の文字体系です。
普及しているRTL文字体系としては、アラビア語、ヘブライ語、パシュトゥー語、ペルシア語、ウルドゥー語、シンド語などがあります。
日本語や英語、フランス語などは左から右のLTR(Left to Right)言語です。
RTL言語でのUI
RTL言語ではインターフェースも右から左に反転する必要があります。
日本語でのWikipedia
https://gyazo.com/18703ae9489a8ee1dbb3391d49873461
アラビア語でのWikipedia
https://gyazo.com/fe558c6e3b1fb26a657be9f8f6eb7b14
UIの反転では起こることとしては以下のようになります。
サイドバーも右側
横並びで表示されている箇所は逆の順序になります。
テキストフィールドのアイコンはフィールドの反対側に表示されます。
方向を示すアイコン (矢印やページングなど) は反転します。
テキスト (RTL 言語に翻訳された場合) は右揃えになります。
反転しない項目は以下のようになります。
方向を示さないアイコンや画像 (カメラなど)
数字 (時計の数字や電話番号など)
グラフ (X 軸と Y 軸は常に同じ方向になります)
ビデオコントロールとタイムラインインジケータ
時計
音符と楽譜
注意点
太字と斜体の使用
ほとんどのRTL言語では太字のテキストは判読性を下げる原因になり、斜体はそもそも使われないようです。
太字は使われるらしいです
RTL言語での強調方法としては、上線を使用します。(あんまり使わない)
text-decoration: overline
ナビゲーションメニュー
ロゴやメニューなどは右上隅に配置する必要があります。
ビデオプレイヤーのタイムライン、再生ボタンなどは反転する必要はありません。
https://gyazo.com/ca28f839a46053119ba6fb38b11f1d1c
数字は左から右に向かって表示する場合と変わらないため、数字の順序は変更する必要はありません
西アラビア数字と東アラビア数字があり、同じ国でも扱いが違うらしいです
システムが提供する数字の表現に頼るのが良いとされています
インド数字でもアラビア数字でも問題ないらしいです
アイコンなどを使っている場合はアイコンの位置を変更する必要があります
LTRでは電話番号の左側にアイコンを表示していたら、RTLでは右側にアイコンを表示する必要があります
プログレスバー / スクロールバー / スライダー / スライド
RTLに変更する、もしくは縦や円で表示する必要があります
星などで表す評価値
どちらが最大か最小化を表す必要があります
カレンダーの年の表示
カレンダーの年の表示がLRTとRTLで地域で異なるため、考慮する必要があるかもしれないです
イスラムのカレンダーは太陰暦で12×29.53 = 354.36日のため
曜日は右から進みます
タイトル「英語」本文「アラビア語」の場合、タイトルは左寄せ、本文は右寄せになります(左寄せでも違和感はないらしい)
曜日名の省略
英語ではSやSun、MやMonなど、日本語では日や月という風に曜日名を省略しますが、アラビア語では全ての曜日が同一の文字で始まるため省略できません。
段落(3行以上のテキスト)でRTL言語の中にLTR言語が混じっている場合
読みやすさを維持するために、1行または2行のテキストブロックを現在のコンテキストの読み取り方向に合わせて整列させ続けます
現在のコンテキストがRTLであっても、LTRテキストを含むパラグラフを左揃えにします
リスト
リスト内のすべてのアイテムの配置を逆にします
実際の方向を参照したり、画面上の領域を指し示すコントロールの方向を保持します
「右」という意味のコントロールを使用する場合はそのまま右を指すように
「戻る」ボタンであれば、「←」を「→」に変更する必要がある
必要に応じて大きさを調整する必要があります
大文字のラテン語のテキストの隣にあるとアラビア語などが小さく感じる場合があります
RTLのフォントを2pt上げるのが効果的です
一般的な写真は反転しないようにする
文章の方向性に依存する画像だとしたら、画像の反転ではなく新しい画像を用意することを検討します
画像の順序に意味がある場合は、画像の位置を反転させます
テキストを表示するアイコンのローカライズ版の作成を検討する必要があります
UIの記載があるサイト
CSSの変更
code:html
<html lang = "en" dir = "ltr" >
<html lang = "ar" dir = "rtl" >
dir属性によって、要素のテキストの方向を変更することができます。
MDNでは
テキストの書字方向はその表示ではなく、内容に対して意味論的な関係がありますので、ウェブ開発者には、可能であれば関連する CSS プロパティの代わりにこの属性を使用することを推奨します。これにより、 CSS に対応しないブラウザーや CSS を無効化したブラウザーでもテキストが正しく表示されます。
とされています。
CSSの変更箇所
主に変更する必要があるのは、下記項目になります。
marginやpadding
transform
right, leftの指定
表示の順序
強調表示、下線
文字揃え
表
marginやpadding
code:css
.menu-item {
margin-right: 1rem;
}
margin-right: 0;
margin-left: 1rem;
}
基本的には、LTRの時のCSSとは反対の値を付与する必要があります。
他の方法としては、margin-block-start 、margin-block-end、 margin-inline-start、margin-inline-end というプロパティもあります。これらは要素の書字方向やテキストの方向に応じて物理的なマージンとなります。
それぞれ、writing-mode, direction, text-orientation の値によって、margin-top, right, bottom, leftのいずれかに対応します。
table: css
inline / block RTL LTR
margin-block-start margin-top margin-top
margin-block-end margin-bottom margin-bottom
margin-inline-start margin-left margin-right
margin-inline-end margin-right margin-left
transform
transformのtranslateで横方向の位置を変更していた場合、値に-1をかけた値にする必要があります。
code:css
.menu-item {
transform: translateX(100px);
}
transform: translateX(-100px);
}
right, leftの指定
absoluteやfixedなどで right や left の指定をしていた場合、その値を変更する必要があります。
正常な表示になるかは一個ずつ検証する必要があるかもしれません。
float や text-align などでleftやrightを指定していた場合も変更が必要です。
code:css
.logo {
position: absolute;
left: 10px;
top: 0;
}
right: 10px;
left: auto;
}
表示の順序
flex
inline-block
左がLTR、真ん中がdisplay:inline-blockのRTL、右がdisplay:inlineのRTL。
inline-blockは順番通りに左から並んでいるため問題なさそうでした(おそらく)
https://gyazo.com/63aeb5095408098f6cc1b4c617af5853 https://gyazo.com/8ea59ef5aebd89a5878a5742e2563f2chttps://gyazo.com/cb105a6f4f1233f2d56a0df2d4382a0e
code:html
<div class="hoge" dir="rtl">
<p class="inline">THIS</p>
<p class="inline">IS </p>
<p class="inline">A PEN.</p>
</div>
code:css
.hoge {
width: 500px;
height: 200px;
padding: 20px;
}
.inline {
display: inline-block;
}
強調表示、下線
太字と斜体の使用 で前述したように、斜体、下線で強調している箇所を上線に変更する必要があります。
*上線については古い情報かもしれないです。
文字揃え
text-align の start と end を使うことで、言語によって変更する必要はありません。 left や right を指定していたら変更する必要があります。
start
書字方向が左書きであれば left、右書きであれば right と同じです。
end
書字方向が左書きであれば right、右書きであれば left と同じです。
inputなどの入力箇所
text-align などで入力方向を変更する必要があります。
表
tableタグ
https://gyazo.com/f414a876fb29bc80f69fef8bf105c103https://gyazo.com/d3cfb09cad219fb798bb43cc34bac696
https://gyazo.com/10b4bcf00c3eca6a4ca6fe4405d30c9dhttps://gyazo.com/8fbf99c62caeefde10cad85c5634b2b3
code:html
<table dir="rtl">
<tbody>
<tr>
<th>タイトル</th>
<td>テスト</td>
</tr>
<tr>
<td colspan="2">
<hr>
</td>
</tr>
</tbody>
</table>
code:css
th {
border-right: solid 1px #000; }
border-left: solid 1px #000; border-right: solid 0px #000; }
https://gyazo.com/e4c14ff86e9940d2e9cc89609a48a267https://gyazo.com/3c0d7cc32d606527c8ac0941d54c6e39
tableであれば基本的には対応はpaddingやborderのみ
dl dd dtの説明リスト
code:html
<div dir="ltr" class="hoge">
<dl>
<dt>タイトル1</dt>
<dd>項目1</dd>
<dt>タイトル2</dt>
<dd>項目2</dd>
</dl>
</div>
code:css
dt {
float: left;
padding-right: 10px;
border-right: solid 1px #000; }
float: right;
padding-left: 10px;
border-left: solid 1px #000; border-right: 0px;
}
dd {
margin-left: 100px;
}
margin-right: 110px;
margin-left: 0px;
}
https://gyazo.com/64ee1b45a5a9dbe14a73dad0303897a7https://gyazo.com/fc492b464982ca7fbb73a0cfb116c298
before, after
code:css
left: 1px
}
right: 1px
}
beforeやafterでabsoluteなどでアイコンなどを設定すると、leftとrightを変えるだけでは想定通りにならないことがあります
その時は display:flex justify-content:left などで設定すると上手くいくかもしれません(体感)
他の対応箇所
float 、clear、direction、text-shadow、transition、border系、box-shadow、backgroud系、など
基本的にはrightとleftを変更するだけですが、場合によって数値も変更する必要があります
一部だけRTLにしたくない、RTLにすると表示がバグるという場合は、その要素のHTMLに dir="ltr" とつけることで、その要素はltrの向きで表示されます。
htmlがltrの向きで表示されるだけでCSSは dir =rtlのものが適用されるため、ltrで表示したい場合はCSSを変更しないようにしてください
code:html
<div dir="ltr">hoge</div>
PCでは値を設定していて、SPではその値を打ち消すという場合は注意が必要です。
その場合はmedia screenの中でltr,rtlそれぞれで値を打ち消す必要があります。
code:css
float: right;
}
float: left;
}
@media screen and (max-width: $spWidth) {
float: none;
}
}
htmlタグに dir属性をつけないとCSSが動きません
実装方法
実装方法としては以下のようなものがあるかと思います。
[dir="rtl] 属性セレクターをそれぞれのプロパティにつける(もしくは lang(ar))
基本的にはHTMLのdir属性を参照する。
dir属性がない要素は文字方向が親から継承されていても無視する。
文書自身に設定されているもののみを使用する。
継承されていたり、ユーザーエージェントの計算だったりの値で選択する。
CSSに記述されている左右に関係するプロパティの値を反転してくれるフレームワークです。
コメントを挿入しておくことで、出力の仕方を調整できる機能があります。
プロパティ値を変換せずにそのまま出力したり、削除したり、指定した値に変更したりすることができます。
bootstrapはRTLCSSが入っています
PostCSSのRTLCSS
共通の要素は書き出して、RTLとLTRの場合それぞれで異なるプロパティを書き出す
より多くのCSSコードが生成されるものの、上書きする必要がない
テキストの方向によって影響を受けるプロパティのみを生成する
コードは少ない
複数のクラスが同時に使用されている場合に問題が起きる可能性がある
通常の実装方法
方法1 共通要素、rtl要素、ltr要素に分ける
code:css
.my-element {
background: yellow;
padding: 10px 20px 30px 40px;
float: right;
}
padding: 10px 40px 30px 20px;
float: left;
}
}
方法2 rtl要素でltrの要素を打ち消す
code:css
.my-element {
padding: 10px 20px 30px 40px;
background: yellow;
float: right;
padding: 10px 40px 30px 20px;
float: left;
}
}
SASSでの方法
方法1 mixinを使う
長所
方法2と比較して、出力ファイルが小さい
rtlとltrのミックスインを使っているので、セマンティックなsassになる。
短所
1つの出力ファイルでrtlとltrをサポートできない
code:direction.css
$layout-direction: ltr !default;
@mixin ltr {
@if $layout-direction == ltr {
@content;
}
}
@mixin rtl {
@if $layout-direction == rtl {
@content;
}
}
code:css
@import "direction.scss";
.my-element {
padding: 50px;
background: yellow;
@include rtl {
float: right;
}
@include rtl {
float: left;
}
}
方法2 dirタグでの判別
共通要素、RTLのみ、LTRのみに分ける
長所
rtlとltrを1つのファイルで対応できる
短所
出力ファイルが重くなる可能性がある
code:css
.my-element {
padding: 50px;
background: yellow;
float: right;
}
float: left;
}
}
方法3 sass varsを使う
2つのファイルを用意し、言語によって使用するプロパティ自体を変更する
長所
自動的にRTL、LTRの対応ができる
短所
対応できない箇所が出てくる
code:css
$default-float: right;
$opposite-float: left;
$default-direction: rtl;
$opposite-direction: ltr;
$transform-direction :1;
@import 'style';
code:css
$default-float: left;
$opposite-float: right;
$default-direction: ltr;
$opposite-direction: rtl;
$transform-direction : -1;
@import 'style';
code:css
body {
direction: $default-direction;
}
.media {
float: $default-float;
padding-#{$opposite-float}: 10px;
}
.button {
background-image: url("images/arror-#{default-float}.png");
transform: translateX(200px * $transform-direction);
}
2つの変数ファイルと1つのメインCSSファイルからLTR、RTLのファイルを作成する
code:css
@import "config-directions / _direction-ltr.scss ";
@import " _main.scss ";
sass用 mixinを追加する?
探した限りだとSASSでdirタグを追加するようなものはなかったので、SASSだと(変換使いつつ)対応が手作業かも....
_____________________________________________
RTL、LTRに変更するブックマークレット
code:js
javascript:(function(b){b.dir='ltr';})(document.documentElement); // LTRにする
javascript:(function(b){b.dir='rtl';})(document.documentElement); // RTLにする
_____________________________________________
所感
こういった複合的な書き方(共通要素、RTL、LTR)が一番わかりやすく保守がしやすそうだと思いました。
ただしLTR時(日本語や英語の時など)にもhtmlのdir属性をつけていないと、思うように動かないため注意が必要です。
RTLの時のみdir属性をつけるという対応がしたい場合は、[dir=rtl] でltrのCSSを打ち消すような書き方がいいかなと思います。
code:css
.my-element {
padding: 50px;
background: yellow;
float: right;
}
float: left;
}
}
参考