アラビア語RTL Web は何をしますか?
アラビア語ページが自然に読め、375pxで正しくレイアウトされ、数字やURL、英語の単語が乱れないようにするためのチェックリストです。タスクに関連する各セクションを適用し、最後に最終チェックリストを実行してください。
1. 方向と言語
- ルート要素:
<html lang="ar" dir="rtl">。JavaScriptではなくHTMLに記述し、最初の描画時点でRTLにします。 dirをCSSのdirection: rtlで置き換えないでください。属性は双方向テキスト、フォームコントロール、スクリーンリーダーも制御します。- アラビア語ページ内の英語ブロック:
<p lang="en" dir="ltr">。ユーザーが入力するテキスト(名前、コメント、チャット):dir="auto"。
2. 論理プロパティによるレイアウト
物理的なleft/rightは決して反転しません。論理プロパティを使用することで、1つのスタイルシートが両方向で機能します。
| 避ける | 使用する |
|---|---|
margin-left, padding-right | margin-inline-start, padding-inline-end |
left: 0, right: 0 | inset-inline-start: 0, inset-inline-end: 0 |
text-align: left | text-align: start |
border-left | border-inline-start |
border-top-left-radius | border-start-start-radius |
float: left | float: inline-start |
- Flexboxとgridはすでに
dirに従います: RTLではflex-direction: rowが右から始まります。RTLを「修正」するためにrow-reverseを追加しないでください。 transform: translateX()、background-position、box-shadowのオフセットは物理的です。必要に応じて:dir(rtl)または[dir="rtl"]で反転させてください。- Tailwind:
ms-*,me-*,ps-*,pe-*,start-*,end-*,text-start、およびrtl:/ltr:バリアント。
3. アラビア語ウェブフォント
- アラビア語用にデザインされたファミリーを選択してください(IBM Plex Sans Arabic, Noto Naskh Arabic, Noto Sans Arabic, Tajawal, Cairo, Almarai, Readex Pro)。Aref Ruqaaなどの装飾的な書体は見出しのみに使用してください。
- WOFF2ファイルをセルフホストしてください。サードパーティのリクエストなし、オフラインでも動作、フォントCDNに情報が漏れません。ライセンスを確認してください(OFLはセルフホスティングを許可しています)。
font-display: swapを使用し、unicode-rangeでアラビア語とラテン語のファイルを分割することで、各ページが必要なものだけをダウンロードします:
@font-face { font-family: 'Plex'; font-weight: 400; font-display: swap;
src: url(plex-400-ar.woff2) format('woff2');
unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200E, U+FB50-FDFF, U+FE70-FEFC; }
@font-face { font-family: 'Plex'; font-weight: 400; font-display: swap;
src: url(plex-400-lat.woff2) format('woff2');
unicode-range: U+0000-00FF, U+2000-206F; }
body { font: 400 17px/1.75 'Plex', 'Segoe UI', Tahoma, sans-serif; }
- アラビア語は、ダイアクリティカルマークとディセンダーのためにより高い行間(1.6〜1.8)と、ラテン語よりやや大きいサイズが必要です。
- アラビア語には
letter-spacingを使用しないでください(文字の結合が壊れます)。text-transform、偽のイタリックは使用しないでください。狭いカラムではtext-align: justifyを避けてください。 - タトウィール(U+0640)で単語を引き伸ばさないでください。検索とコピー&ペーストが壊れます。
4. 双方向テキスト: 数字、URL、アラビア語内の英語
Unicode双方向アルゴリズムは、数字やラテン語のテキストの隣にある中立文字を並べ替えます。RTL段落の典型的な2つのバグ:
- 電話番号
+966 55 123 4567が数字のグループを逆順に表示:4567 123 55 +966。 - 時間範囲
10:00 - 12:00が12:00 - 10:00と表示。
修正:
- 方向が不明な挿入値の周りに
<bdi>:مرحبًا <bdi>${userName}</bdi>، أهلًا بك。 - 常にLTRである値に
dir="ltr":<span dir="ltr">+966 55 123 4567</span>、URL、メール、ファイルパス、IBAN、<code dir="ltr">、<pre dir="ltr">。 - 繰り返しパターン用のCSS:
.num, .code { unicode-bidi: isolate; }。<bdi>はデフォルトで分離することに注意してください。 - メール、URL、電話の入力:
<input type="email" dir="ltr">。 - マークアップが不可能な場合(文書タイトル、通知、プレーン文字列)、Unicode分離文字でラップ: FSI U+2068 ... PDI U+2069、または既知のLTRテキストにはLRI U+2066 ... PDI。
5. 数字: ページ内で統一されたシステム
- ラテン数字
0-9またはアラビア・インド数字٠-٩(U+0660〜U+0669) のいずれかを選択し、テーブル、チャート、日付を含むページ全体でそれを使用します。 - 混在は読者を混乱させ(両方を含むテーブルはエラーのように見える)、検索(「15」は「١٥」に一致しない)、並べ替え、スプレッドシートへのコピー&ペーストを壊します。
- ペルシア数字
۰-۹(U+06F0〜U+06F9) は異なるコードポイントです。混在させないでください。 Intlのデフォルトはロケールとエンジンのバージョンによって異なります: Node 24では、ar-SAはアラビア・インド数字でフォーマットされ、プレーンなarはラテン数字になります。番号付けシステムを明示的に設定してください:new Intl.NumberFormat('ar-SA-u-nu-latn')または'ar-SA-u-nu-arab'。- アラビア・インド数字の場合、小数点記号は
٫(U+066B)、桁区切り記号は٬(U+066C) です。 - 実際の落とし穴: アラビア・インド数字の隣で区切り記号として使用される中点(U+00B7)は、アラビア・インドのゼロ(U+0660)のように見えます。これも小さなドットです。「12, 区切り記号, 3」は「1203」と読み取られます。代わりにアラビアコンマ「،」、スラッシュ、または追加のスペース(CSS
gap)で区切ってください。
6. アラビア語句読点
,(U+060C),;(U+061B),?(U+061F) を使用し、,,;,?は使用しないでください。ピリオドと!は共有されます。- 句読点の前にスペースを入れず、後ろに1つのスペースを入れます: «كيف حالك؟» であり «كيف حالك ؟» ではありません。
- 引用スタイル(«...» または "...")はページ内で統一してください。
7. アイコンと反転
方向や順序を示すアイコンを反転: 戻る/次へ矢印、リストとパンくずリストのシェブロン、ステッパーと進行方向、「送信」、テキストインデントとリストアイコン。
反転しない: ロゴとブランドマーク、メディアコントロール(再生、巻き戻し、早送り)、時計とタイマー、チェックマーク、写真、ラテン文字や数字を含むアイコン。
:dir(rtl) .icon-dir { transform: scaleX(-1); } /* オプトインクラス。グローバルにはしない */
8. アラビア語キーボードからの数値入力
<input type="number">よりも<input inputmode="decimal" autocomplete="off">を優先してください。number入力の値はASCII数字でのみ有効なため、アラビア・インド数字は空文字列として返される可能性があります。また、スピナーが追加されます。- ユーザーは
٠-٩、アラビア語の小数点記号٫、時にはペルシア数字を入力します。Number()の前に正規化:
function parseArabicNumber(raw) {
const s = String(raw ?? '').trim()
.replace(/[٠-٩]/g, (d) => d.charCodeAt(0) - 0x0660)
.replace(/[۰-۹]/g, (d) => d.charCodeAt(0) - 0x06F0)
.replace(/٫/g, '.')
.replace(/٬/g, '');
if (s === '') return null; // Number('')は0なので、最初に空をチェック
const n = Number(s);
return Number.isFinite(n) ? n : NaN;
}
parseArabicNumber('٩٥٫٥'); // 95.5
- 入力された
,の扱い(小数点か桁区切りか)を決定し、文書化してください。 - 検証メッセージをアラビア語で表示し、
aria-invalidを設定し、aria-describedbyでメッセージをリンクしてください。 - アラビア語の名前の並べ替えは
new Intl.Collator('ar').compareを使用します。検索の場合は、クエリとデータの両方でアレフ形式(أ إ آ を ا に)を正規化し、タシュキールとタトウィールを削除してください。
9. テスト
- 375px幅(可能であれば320px)でテストしてください。
document.documentElement.scrollWidth <= innerWidthを確認してください。 - 「والمستشفيات」や「باستخداماتها」のような、つながった文字を持つ長いアラビア語の単語を見出しやボタンでテストしてください。見出しやカードには
overflow-wrap: anywhere、フレックスとグリッドの子にはmin-width: 0を使用してください。 - lorem ipsumではなく、英語と数字が混在した実際のアラビア語コンテンツを使用してください。
- iOSのSafariとAndroidのChromeでチェックし、さらに200%ズームとキーボードフォーカス順序(Tabキーで右から左に移動)を確認してください。
10. [hidden]の落とし穴
hidden属性はユーザーエージェントのdisplay: noneにすぎません。.card { display: flex }などの作成者ルールはそれを上書きするため、el.hidden = trueが静かに機能しなくなります。ベーススタイルシートにこれを追加してください:
[hidden] { display: none !important; }
最終チェックリスト
- ソースに
<html lang="ar" dir="rtl"> - 新しいCSSに物理的なleft/rightプロパティが残っていない
- セルフホストのアラビア語フォント、
font-display: swap、unicode-range分割 - 電話番号、URL、コード、ユーザー名が分離されている
- 数字システムが統一されている。アラビア・インド数字の隣に中点がない
- アラビア語句読点、前にスペースなし
- 方向性のあるアイコンのみ反転
- 数値入力が
٠-٩と٫を受け付ける - 375pxで水平スクロールなし。長い単語が折り返される
-
[hidden] { display: none !important; }が存在する