arabic-rtl-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseArabic RTL Best Practices
阿拉伯语RTL布局最佳实践
Instructions
操作指南
Step 1: Set Up Document Direction
步骤1:设置文档方向
Always start with the HTML attribute (not just CSS):
html
<html lang="ar" dir="rtl">This tells browsers, screen readers, and CSS to use RTL as the base direction.
始终从HTML属性开始设置(不要仅依赖CSS):
html
<html lang="ar" dir="rtl">这会告知浏览器、屏幕阅读器和CSS以RTL作为基础方向。
Step 2: Use CSS Logical Properties
步骤2:使用CSS逻辑属性
NEVER use physical directional properties for layout:
| Physical (avoid) | Logical (use) |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
This ensures the layout automatically mirrors in RTL mode.
绝对不要使用物理方向属性进行布局:
| 物理属性(避免使用) | 逻辑属性(推荐使用) |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
这确保布局在RTL模式下自动镜像。
Step 3: Handle Bidirectional Text
步骤3:处理双向文本
When mixing Arabic and English/numbers:
css
/* Isolate embedded LTR content */
.ltr-content {
unicode-bidi: isolate;
direction: ltr;
}
/* For inline elements with mixed content */
.bidi-override {
unicode-bidi: bidi-override;
}Common bidi issues:
- Phone numbers appearing reversed: Wrap in
<bdo dir="ltr"> - Punctuation at wrong end of sentence: Use
unicode-bidi: isolate - URLs/emails in Arabic text: Wrap in
<span dir="ltr">
混合阿拉伯语与英语/数字内容时:
css
/* 隔离嵌入的LTR内容 */
.ltr-content {
unicode-bidi: isolate;
direction: ltr;
}
/* 用于包含混合内容的行内元素 */
.bidi-override {
unicode-bidi: bidi-override;
}常见双向文本问题:
- 电话号码显示颠倒:用包裹
<bdo dir="ltr"> - 标点符号出现在句子错误的一端:使用
unicode-bidi: isolate - 阿拉伯语文本中的URL/邮箱:用包裹
<span dir="ltr">
Step 4: Arabic Typography
步骤4:阿拉伯语排版
Recommended font stack:
css
font-family: 'Tajawal', 'Assistant', 'Rubik', 'Noto Sans Arabic', sans-serif;Typography settings:
css
body[dir="rtl"] {
font-size: 16px; /* Arabic needs slightly larger than Latin */
line-height: 1.7;
letter-spacing: normal; /* NEVER add letter-spacing for Arabic */
word-spacing: 0.05em; /* Slight word spacing improves readability */
}推荐字体栈:
css
font-family: 'Tajawal', 'Assistant', 'Rubik', 'Noto Sans Arabic', sans-serif;排版设置:
css
body[dir="rtl"] {
font-size: 16px; /* 阿拉伯语字体需要比拉丁语系字体稍大 */
line-height: 1.7;
letter-spacing: normal; /* 绝对不要为阿拉伯语添加字母间距 */
word-spacing: 0.05em; /* 轻微的单词间距可提升可读性 */
}Step 5: Framework-Specific Setup
步骤5:框架专属配置
Tailwind CSS RTL (v3.3+ / v4):
Prefer logical property utilities over / variants:
rtl:ltr:| Physical class | Logical class | CSS property |
|---|---|---|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
html
<!-- Bad: requires two classes, breaks without dir attribute -->
<div class="ltr:ml-4 rtl:mr-4">...</div>
<!-- Good: single class, auto-mirrors based on dir -->
<div class="ms-4">...</div>Reserve / variants only for cases logical properties cannot handle (e.g., directional icons, transforms).
rtl:ltr:Tailwind v4 note: v4 uses CSS-first configuration ( in CSS) instead of . Logical utilities work identically in both v3 and v4.
@import "tailwindcss"tailwind.config.jsNext.js App Router:
tsx
// app/layout.tsx
import { Tajawal } from 'next/font/google';
const tajawal = Tajawal({
subsets: ['arabic', 'latin'],
weight: ['400', '500', '700'],
});
export default async function RootLayout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const isRTL = locale === 'he';
return (
<html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>
<body className={tajawal.className}>{children}</body>
</html>
);
}next/fontReact with MUI:
jsx
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import rtlPlugin from 'stylis-plugin-rtl';
import { prefixer } from 'stylis';
const cacheRtl = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});
const theme = createTheme({ direction: 'rtl' });Tailwind CSS RTL(v3.3+ / v4):
优先使用逻辑属性工具类,而非/变体:
rtl:ltr:| 物理类名 | 逻辑类名 | CSS属性 |
|---|---|---|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
html
<!-- 不推荐:需要两个类名,无dir属性时会失效 -->
<div class="ltr:ml-4 rtl:mr-4">...</div>
<!-- 推荐:单个类名,根据dir属性自动镜像 -->
<div class="ms-4">...</div>仅在逻辑属性无法处理的场景(如方向图标、变换)中保留 / 变体。
rtl:ltr:Tailwind v4注意事项: v4采用CSS优先配置(在CSS中),而非。逻辑工具类在v3和v4中的工作方式完全相同。
@import "tailwindcss"tailwind.config.jsNext.js App Router:
tsx
// app/layout.tsx
import { Tajawal } from 'next/font/google';
const tajawal = Tajawal({
subsets: ['arabic', 'latin'],
weight: ['400', '500', '700'],
});
export default async function RootLayout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const isRTL = locale === 'he';
return (
<html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>
<body className={tajawal.className}>{children}</body>
</html>
);
}next/fontReact搭配MUI:
jsx
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import rtlPlugin from 'stylis-plugin-rtl';
import { prefixer } from 'stylis';
const cacheRtl = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});
const theme = createTheme({ direction: 'rtl' });Step 6: Common Pitfalls to Check
步骤6:需检查的常见陷阱
- Icons with directional meaning (arrows, back buttons) -- mirror them
- Progress bars -- should fill from right to left
- Sliders/carousels -- swipe direction should reverse
- Form labels -- should be right-aligned
- Breadcrumbs -- separator direction should reverse
- Tables -- header alignment and cell alignment
- Charts -- x-axis may need to reverse for Arabic readers
- 具有方向含义的图标(箭头、返回按钮)——需镜像处理
- 进度条——应从右向左填充
- 滑块/轮播组件——滑动方向需反转
- 表单标签——应右对齐
- 面包屑导航——分隔符方向需反转
- 表格——表头和单元格对齐方式
- 图表——阿拉伯语用户可能需要反转X轴
Examples
示例
Example 1: Convert LTR Component to RTL
示例1:将LTR组件转换为RTL兼容
User says: "Make this card component work in Arabic"
Before (LTR-only):
css
.card {
margin-left: 16px;
padding-right: 12px;
text-align: left;
border-left: 3px solid blue;
}After (RTL-compatible):
css
.card {
margin-inline-start: 16px;
padding-inline-end: 12px;
text-align: start;
border-inline-start: 3px solid blue;
}With Tailwind, replace with .
ml-4 pr-3 text-left border-l-4ms-4 pe-3 text-start border-s-4用户需求:“让这个卡片组件适配阿拉伯语”
转换前(仅支持LTR):
css
.card {
margin-left: 16px;
padding-right: 12px;
text-align: left;
border-left: 3px solid blue;
}转换后(支持RTL):
css
.card {
margin-inline-start: 16px;
padding-inline-end: 12px;
text-align: start;
border-inline-start: 3px solid blue;
}使用Tailwind时,将替换为。
ml-4 pr-3 text-left border-l-4ms-4 pe-3 text-start border-s-4Example 2: Bidi Text Issue
示例2:双向文本问题
User says: "Numbers are showing backwards in my Arabic text"
html
<!-- Wrong: phone number renders as 0544-123-050 -->
<p>התקשרו אלינו: 050-321-4450</p>
<!-- Correct: isolate the LTR content -->
<p>התקשרו אלינו: <span dir="ltr">050-321-4450</span></p>Use on the containing span for CSS-only solutions.
unicode-bidi: isolate用户需求:“阿拉伯语文本中的数字显示颠倒了”
html
<!-- 错误:电话号码显示为0544-123-050 -->
<p>התקשרו אלינו: 050-321-4450</p>
<!-- 正确:隔离LTR内容 -->
<p>התקשרו אלינו: <span dir="ltr">050-321-4450</span></p>对于纯CSS解决方案,在包含元素上使用。
unicode-bidi: isolateExample 3: Tailwind RTL Navigation
示例3:Tailwind RTL导航
User says: "My sidebar is on the wrong side in Arabic"
html
<!-- Bad: sidebar stuck on left -->
<aside class="fixed left-0 w-64">...</aside>
<!-- Good: sidebar auto-mirrors -->
<aside class="fixed start-0 w-64">...</aside>
<!-- Back arrow icon still needs rtl: variant -->
<button class="rtl:rotate-180">
<ArrowLeftIcon />
</button>用户需求:“我的侧边栏在阿拉伯语模式下位置错误”
html
<!-- 错误:侧边栏固定在左侧 -->
<aside class="fixed left-0 w-64">...</aside>
<!-- 正确:侧边栏自动镜像 -->
<aside class="fixed start-0 w-64">...</aside>
<!-- 返回箭头图标仍需使用rtl:变体 -->
<button class="rtl:rotate-180">
<ArrowLeftIcon />
</button>Bundled Resources
配套资源
References
参考资料
- — Complete physical-to-logical CSS property mapping table (margin, padding, border, positioning, text alignment, sizing) plus Arabic font stack recommendations for sans-serif, serif, and monospace. Consult when converting any LTR stylesheet to RTL-compatible logical properties or choosing Arabic web fonts.
references/css-logical-properties.md
- — 完整的物理属性到逻辑属性的CSS映射表(边距、内边距、边框、定位、文本对齐、尺寸),以及适用于无衬线、衬线和等宽字体的阿拉伯语字体栈推荐。转换任何LTR样式表为RTL兼容的逻辑属性,或选择阿拉伯语网页字体时可参考此文档。
references/css-logical-properties.md
Gotchas
注意事项
- CSS is wrong for Arabic. Use
text-align: leftwhich respects the document direction. Agents frequently hardcodetext-align: startalignment in CSS.left - and
margin-leftdo not flip in RTL mode. Use CSS logical properties:padding-rightandmargin-inline-startinstead. Agents trained on LTR CSS will generate physical properties.padding-inline-end - Flexbox direction auto-reverses in RTL, but
rowalso reverses, causing a double-flip back to LTR order. Agents may addrow-reversethinking it creates RTL, but it actually creates LTR within an RTL context.row-reverse - Phone numbers, credit card numbers, and code snippets must remain LTR even inside RTL containers. Wrap them in or use
<bdo dir="ltr">on the containing element. Agents often let these inherit RTL.direction: ltr
- CSS 不适用于阿拉伯语。应使用
text-align: left,它会遵循文档方向。AI助手常在CSS中硬编码text-align: start对齐方式。left - 和
margin-left在RTL模式下不会自动翻转。请使用CSS逻辑属性:padding-right和margin-inline-start。基于LTR CSS训练的AI助手会生成物理属性。padding-inline-end - Flexbox的方向在RTL中会自动反转,但
row也会反转,导致双重翻转回到LTR顺序。AI助手可能会添加row-reverse以为这能实现RTL,但实际上它会在RTL环境中创建LTR顺序。row-reverse - 电话号码、信用卡号和代码片段即使在RTL容器中也必须保持LTR方向。用包裹它们,或在包含元素上设置
<bdo dir="ltr">。AI助手常让这些内容继承RTL方向。direction: ltr
Reference Links
参考链接
| Source | URL | What to Check |
|---|---|---|
| MDN CSS Logical Properties | https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_values | Full property list, browser support tables |
| Tailwind CSS RTL Support | https://tailwindcss.com/docs/hover-focus-and-other-states#rtl-support | |
| Tailwind Logical Properties | https://tailwindcss.com/docs/margin#logical-properties | |
| Google Fonts Arabic | https://fonts.google.com/?subset=arabic | Available Arabic font families |
| W3C Internationalization | https://www.w3.org/International/articles/inline-bidi-markup/ | Unicode bidi algorithm, markup best practices |
| 来源 | URL | 查看内容 |
|---|---|---|
| MDN CSS逻辑属性 | https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_values | 完整属性列表、浏览器支持表 |
| Tailwind CSS RTL支持 | https://tailwindcss.com/docs/hover-focus-and-other-states#rtl-support | |
| Tailwind逻辑属性 | https://tailwindcss.com/docs/margin#logical-properties | |
| Google Fonts阿拉伯语 | https://fonts.google.com/?subset=arabic | 可用的阿拉伯语字体家族 |
| W3C国际化 | https://www.w3.org/International/articles/inline-bidi-markup/ | Unicode双向算法、标记最佳实践 |
Troubleshooting
故障排查
Error: "Text alignment looks wrong"
错误:“文本对齐显示异常”
Cause: Using instead of
Solution: Replace all / in text-align with /.
text-align: lefttext-align: startleftrightstartend原因:使用而非
解决方案:将所有text-align中的/替换为/。
text-align: lefttext-align: startleftrightstartendError: "Layout not mirroring"
错误:“布局未镜像”
Cause: Using physical margin/padding instead of logical properties
Solution: Replace all / with /.
margin-leftmargin-rightmargin-inline-startmargin-inline-end原因:使用物理边距/内边距而非逻辑属性
解决方案:将所有/替换为/。
margin-leftmargin-rightmargin-inline-startmargin-inline-end