hebrew-rtl-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHebrew RTL Best Practices
希伯来语RTL最佳实践
Instructions
操作步骤
Step 1: Set Up Document Direction
步骤1:设置文档方向
Always start with the HTML attribute (not just CSS):
html
<html lang="he" dir="rtl">This tells browsers, screen readers, and CSS to use RTL as the base direction.
始终从HTML属性开始(而不仅仅是CSS):
html
<html lang="he" 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 Hebrew 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 Hebrew text: Wrap in
<span dir="ltr">
当混合希伯来语与英文/数字时:
css
/* Isolate embedded LTR content */
.ltr-content {
unicode-bidi: isolate;
direction: ltr;
}
/* For inline elements with mixed content */
.bidi-override {
unicode-bidi: bidi-override;
}常见的双向文本问题:
- 电话号码显示颠倒:包裹在中
<bdo dir="ltr"> - 标点符号出现在句子错误的一端:使用
unicode-bidi: isolate - 希伯来语文本中的URL/邮件地址:包裹在中
<span dir="ltr">
Step 4: Hebrew Typography
步骤4:希伯来语排版
Recommended font stack:
css
font-family: 'Heebo', 'Assistant', 'Rubik', 'Noto Sans Hebrew', sans-serif;Typography settings:
css
body[dir="rtl"] {
font-size: 16px; /* Hebrew needs slightly larger than Latin */
line-height: 1.7;
letter-spacing: normal; /* NEVER add letter-spacing for Hebrew */
word-spacing: 0.05em; /* Slight word spacing improves readability */
}推荐字体栈:
css
font-family: 'Heebo', 'Assistant', 'Rubik', 'Noto Sans Hebrew', sans-serif;排版设置:
css
body[dir="rtl"] {
font-size: 16px; /* Hebrew needs slightly larger than Latin */
line-height: 1.7;
letter-spacing: normal; /* NEVER add letter-spacing for Hebrew */
word-spacing: 0.05em; /* Slight word spacing improves readability */
}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 { Heebo } from 'next/font/google';
const heebo = Heebo({
subsets: ['hebrew', '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={heebo.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
<!-- 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>仅在逻辑属性无法处理的情况下(如方向图标、变换)保留 / 变体。
rtl:ltr:Tailwind v4说明: v4使用CSS优先配置(在CSS中)而非。逻辑工具类在v3和v4中的工作方式完全相同。
@import "tailwindcss"tailwind.config.jsNext.js App Router:
tsx
// app/layout.tsx
import { Heebo } from 'next/font/google';
const heebo = Heebo({
subsets: ['hebrew', '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={heebo.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' });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 Hebrew readers
- 具有方向含义的图标(箭头、返回按钮)——需镜像翻转
- 进度条——应从右向左填充
- 滑块/轮播——滑动方向应反转
- 表单标签——应右对齐
- 面包屑——分隔符方向应反转
- 表格——表头对齐和单元格对齐
- 图表——希伯来语读者可能需要反转X轴
Examples
示例
Example 1: Convert LTR Component to RTL
示例1:将LTR组件转换为RTL
User says: "Make this card component work in Hebrew"
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 Hebrew 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
<!-- 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>对于纯CSS解决方案,在包含元素上使用。
unicode-bidi: isolateExample 3: Tailwind RTL Navigation
示例3:Tailwind RTL导航
User says: "My sidebar is on the wrong side in Hebrew"
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
<!-- 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>Bundled Resources
配套资源
References
参考资料
- — Complete physical-to-logical CSS property mapping table (margin, padding, border, positioning, text alignment, sizing) plus Hebrew font stack recommendations for sans-serif, serif, and monospace. Consult when converting any LTR stylesheet to RTL-compatible logical properties or choosing Hebrew web fonts.
references/css-logical-properties.md
- — 完整的物理属性到逻辑属性的CSS映射表(外边距、内边距、边框、定位、文本对齐、尺寸),以及针对无衬线、衬线和等宽字体的希伯来语字体栈推荐。在将任何LTR样式表转换为兼容RTL的逻辑属性或选择希伯来语网页字体时参考此文档。
references/css-logical-properties.md
Gotchas
注意事项
- CSS is wrong for Hebrew. 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 Hebrew | https://fonts.google.com/?subset=hebrew | Available Hebrew 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=hebrew | 可用的希伯来语字体家族 |
| 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: lefttext-align: starttext-alignleftrightstartendError: "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