
見出しに何か問題があるようです? これは、アラビア語などの言語のサポートを追加するときにWeb開発者が直面する問題の1つです。 この記事では、遭遇した問題と、SpotifyデスクトップクライアントおよびWebプレーヤーでアラビア語をサポートするために思いついた解決策について説明します。
Spotifyのローカライズは重要です。 私たちの使命は、「人間の創造性の可能性を解き放ち、数百万人のミュージシャンに彼らの芸術から生計を立てる機会を提供し、数十億人のファンがそれを楽しんで刺激を受けることです」。 この使命を達成するには、さまざまな国のユーザーがそれぞれの言語で効果的にコミュニケーションできることが重要です。 最近、北アフリカと西アジアの地域でSpotifyを開始しました。 これらの地域の言語の1つはアラビア語です。 英語とは異なり、アラビア語は右から左に読みます。 これは、アラビア語をサポートしたいウェブサイトに影響します。
目次
この記事では、次の略語を使用します。
LTR (左から右):英語やスペイン語など、左から右に読むテキスト。
RTL (右から左):アラビア語など、右から左に読み取られるテキスト。
鏡像レイアウト
アラビア語では、テキストが右から左に広がるだけでなく、ページレイアウト全体にも広がります。 たとえば、方向を示す画像を反転します。 いくつかの例外が発生しました。これについては、以下のアイコンセクションで説明します。
dir属性の仕組み
要素内のテキストのブラウザへの方向は、
dir
属性によって報告されます。 ページのグローバルな方向を設定するには、ページ全体に
dir
属性を設定する必要があります。
属性値:
- ltr-左から右への書き込みに使用(たとえば、英語、スウェーデン語)。 これがデフォルト値です。
- rtl-右から左への書き込みに使用(アラビア語、ヘブライ語、ペルシャ語など)。
- auto-動的コンテンツに使用されます。 ブラウザ自体が方向を選択します。 要素を処理して方向を決定するために、 Unicode双方向アルゴリズムが使用されます。 詳細については、 「RTL形式の英語」を参照してください。
CSS
CSS FlexboxとCSS Gridは両方とも
dir
属性を見て、要素の方向を決定します。 たとえば、
dir
属性が
"rtl"
設定されている場合、
flex-start
自動的にRTLに切り替わります。
ただし、flexboxまたはgridを使用した
dir
属性では、RTLのユーザーインターフェイス全体を反映するには不十分な場合があります。 LTRとRTLの両方をサポートするWebサイトを開発する際に注意すべき非対称CSSプロパティが多すぎます。 たとえば、RTLの
margin-left: 20px
および
text-align: right
は変更され、
margin-right: 20px
および
text-align: left
ます。
この作業を自動化する多くのツールがあります。 PostCSS-RTLを選択しました 。これは、ビルドフェーズ中に「反転」プロパティを持つRTLルールを生成します。
.foo { margin-left: 15px; text-align: right; color: rebeccapurple; }
CSS入力
[dir] .foo { color: rebeccapurple; } [dir="ltr"] .foo { margin-left: 15px; text-align: right; } [dir="rtl"] .foo { margin-right: 15px; text-align: left; }
CSS出力
アイコン
方向性がある、または進行状況に関連付けられているアイコンと要素は、RTLに変換する必要があります。 たとえば、戻ると進むのナビゲーションボタンを交換する必要があります。

LTRの戻るボタン

RTLの戻るボタン(アラビア語の代わりに英語のテキストが使用されます)
すべての方向アニメーションも反転する必要があります。 たとえば、カルーセルは反対方向にスライドする必要があります。

例外
最初は、すべてがミラーリングされると想定していました。 しかし、すぐにいくつかの例外が見つかりました。 たとえば、メディア再生ボタンとプログレスバーは、再生中のテープの方向に関連するため、ミラーリングを必要としません。 アラビア語を話すユーザーは、再生コントロールと進行状況バーがLTRと同じように見えることを期待しています。

LTRの再生インジケーター
RTL形式の英語
多くの場合、LTRとRTLのテキストは同じページで混在しています。 Spotifyには、世界中のミュージシャンによる4000万曲以上の歌と30億を超えるプレイリストがあります。 コンテンツは、世界中のユーザー向けに多くの言語で表示されます。 そのため、Spotifyクライアントは多くの場合、LTRコンテンツとRTLコンテンツを混在させます。
(Hello(World:句読点と括弧の問題
最初に遭遇した問題の1つは次のようなものでした。

括弧の問題
これは、ブラウザが要素の
dir
属性の値に基づいてテキストの基本的な方向を設定するために発生します。
( ) . !
などの句読点
( ) . !
( ) . !
残りはUnicodeの方向によって記述されません。 テキストの基本的な方向を継承します。
双方向Unicode双方向アルゴリズムは、文字列内の各文字を右から左に見ていきます。 例として、ページの
"Hello (World)"
という行を取り上げます。
- アルゴリズムは、右側の行の解析を開始します。 彼は無向のキャラクターを見る
)
、それで彼はテキストの基本的な方向を見て、テキストが右から左に行くのを見る。 アルゴリズムは、行の先頭に移動することを決定します。
「Hello(World)」->「(Hello(World))
- アルゴリズムは、LTRの方向で
d
を見ます。 移動する必要はありません。 同じことは、最大(
。
- アルゴリズムは
(
方向なし。左から右へ、(前のW
によって与えられた)一般的な基本方向を記憶します。アルゴリズムは移動しないことを決定します。
Unicode双方向アルゴリズムの仕組みの詳細については、 こちらをご覧ください 。
その結果、
"(Hello (World"
という行が表示されます。この問題は、すべての動的コンテンツ(アーティスト名、アルバム名、曲名など)の
dir
属性に
auto
値を指定することで解決しました。厳密に型指定された方向文字この場合、非方向文字は常にページではなく周囲の文字から方向を継承するため、文字列
"Hello (World)"
を取得します。 それ以外の場合は、
text-align
プロパティを要素に追加する必要があります。
... ello World:切り捨ての問題
要素に合わない切り捨てを追加する場合、混合コンテンツも問題になります。

LTR UI:アラビア語のテキストが間違った側から切り捨てられました

RTL UI:間違った側から切り捨てられた英語のテキスト
ブラウザは
dir
属性からテキストの方向を設定するため、切り捨ては間違った側で発生します。 この問題は、切り捨てられたテキストを持つ要素に
"auto"
属性を設定することで解決されます。

LTR UI:アラビア語のテキストが右側で切り捨てられる

RTL UI:右側で切り捨てられた英語のテキスト
アラビア文字
多言語UIを開発する場合、すべてのアルファベットに対してインターフェイスが正しく機能することを確認することが重要です。 ここでは、簡単に言えば、アラビア語を追加するときに確認する必要があるものです。
記号間
アラビア文字は合字です。 すべてではないにしても、単語内のほとんどの文字は互いに関連しています。 このため、アラビア語では記号間スペースを使用しないでください。 彼はシンボルを壊し、自然な合字を壊します。
フォントサイズ
通常、アラビア文字には英語文字よりも複雑なグリフがあります。 同じスペースに収まるはずのラインとニュアンスがさらにあります。 このため、同じフォントサイズのアラビア文字は英語より読みにくくなります。 文字が小さすぎます。 アラビア語の最小フォントサイズを11から12ピクセルに増やすことにしました。 また、フォントがアラビア語のグリフを複雑にしないようにしました。 適切な選択肢は、ブラウザでアラビア語のデフォルトのバックアップフォントであるArialよりも読みやすいGoogle Notoです。
縦切り
一部のアラビア文字は英語よりも高いです。 これにより、文字が垂直方向に切り捨てられる可能性があります。 アラビア語の場合、行間隔を増やす必要がある場合があります。

縦切り
大文字
アラビア語には大文字がないので、ページ上の大文字で何かを強調しても意味がありません。
アラブのコンマ
多くの言語は、コンマとして使用します。 アラビア語では、別の区切り文字:
،
。
コードでは、コード
array.join(', ')
頻繁に検出されました。 ユーザーの言語設定に応じて異なる区切り文字をサポートするために、
getSeparator()
メソッドを追加しました。
アラビア数字
アラビア語では、2つの数値システム
- 西アラビア数字:0 1 2 3 4 5 6 7 8 9
- 東アラビア数字:٩ ٣ ٤ ٥ ٦ ٧ ٨ ١ ٢ ٠ ٠
1つのシステムを選択し、アプリケーション全体で一貫して使用します。 西アラビア数字を選びました。
透明なテキスト色
アラビア語のグリフは重複する場合があります。 テキストの透明色は機能しません。これは、重なり合う部分が期待される透明度を獲得しないためです。 解決策は、テキスト要素の完全に不透明な色と不透明度です。

透明性の問題
品質基準
以下は、アラビア語を最新の状態にするために行ったことの一部です。
- チームテストセッション
- アラビア語を話すスタッフによるベータテスト
- 外部機関によるUIと翻訳のテスト。
アラビア語UIの品質を確保するには、いくつかのツールが必要でした。
GitHubボットを作成することにしました。 彼は、潜在的な問題に一致するプール要求にコメントを投稿します。 このコメントは何も強制しません。テスト手順を参照して、変更がアラビア語にどのように影響するかを確認するだけのリマインダーです。 ボットは、パディング、文字間隔、変換などに対応する変更された行にコメントします。CSSコードはPostCSS-RTLによって変換されるため、通常はアラビア語で変更を確認し、見た目をよくすれば十分です。 CSSプロパティはJSを介して設定でき、PostCSS-RTLはJSを変換しません。 ボットは、対応するプロパティがそこに見つかった場合、JSファイルとそれらのコメントもチェックします。

tob-botによるコメント