支持从右到左(RTL)布局
为阿拉伯语和希伯来语等语言适配布局
问题
应用程序的布局通常使用 margin-left 和 padding-right 等 CSS 属性构建,这些属性默认假设文本方向为从左到右(LTR)。当应用被翻译为阿拉伯语或希伯来语等 RTL 语言时,整个布局会变得颠倒,内容错位且难以阅读。
解决方案
将方向性 CSS 属性(left / right)替换为现代、与方向无关的逻辑属性(start / end)。在 <html> 元素上根据当前语言设置 dir 属性,浏览器会自动正确翻转布局。
步骤
1. 定义哪些语言为 RTL
首先,你需要一种方式来识别你支持的语言中哪些是 RTL。
新建一个 app/i18n-config.ts 文件(或更新现有文件)来存储这些信息。
// i18n-config.ts
export const locales = ['en', 'es', 'ar', 'he']; // ar=Arabic, he=Hebrew
export const defaultLocale = 'en';
export const localeCookieName = 'NEXT_LOCALE';
export const rtlLocales = ['ar', 'he'];
2. 在根布局中设置 dir 属性
修改你的 app/[lang]/layout.tsx,有条件地为 <html> 标签添加 dir(direction)属性。
// app/[lang]/layout.tsx
import { rtlLocales } from '@/i18n-config';
export async function generateStaticParams() {
return [{ lang: 'en' }, { lang: 'es' }, { lang: 'ar' }, { lang: 'he' }];
}
export default async function RootLayout({
children,
params,
}: {
children: React.ReactNode;
params: { lang: string };
}) {
// Determine if the current language is RTL
const isRtl = rtlLocales.includes(params.lang);
return (
<html lang={params.lang} dir={isRtl ? 'rtl' : 'ltr'}>
<body>
{/* ...your providers and content... */}
{children}
</body>
</html>
);
}
通过在 <html> 标签上添加 dir="rtl",你告知浏览器该页面的整个文档流应为从右到左。
3. 更新 CSS,使用逻辑属性
检查你的全局 CSS 和组件样式,将所有方向性属性替换为逻辑属性。
margin-left替换为margin-inline-startmargin-right替换为margin-inline-endpadding-left替换为padding-inline-startpadding-right替换为padding-inline-endleft(定位时)替换为inset-inline-startright(定位时)替换为inset-inline-endtext-align: left替换为text-align: starttext-align: right替换为text-align: end
示例:
之前(方向性):
.card {
padding-left: 16px;
border-left: 4px solid blue;
}
.title {
text-align: left;
}
之后(逻辑性):
.card {
padding-inline-start: 16px;
border-inline-start: 4px solid blue;
}
.title {
text-align: start;
}
当用户访问 /en(dir="ltr")时,padding-inline-start 会应用在左侧。当用户访问 /ar(dir="rtl")时,浏览器会自动将 padding-inline-start 应用到右侧,从而正确翻转你的组件布局。