支持从左到右 (RTL) 布局

为阿拉伯语和希伯来语等语言调整您的布局

问题

一个应用程序的布局是通过 CSS 属性(如 margin-leftpadding-right)构建的,这些属性假定文本方向为从左到右 (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=阿拉伯语, he=希伯来语
export const defaultLocale = 'en';
export const localeCookieName = 'NEXT_LOCALE';

export const rtlLocales = ['ar', 'he'];

2. 在根布局中设置 dir 属性

修改您的 app/[lang]/layout.tsx,以有条件地将 dir(方向)属性添加到 <html> 标签。

// 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 };
}) {
  // 确定当前语言是否为 RTL
  const isRtl = rtlLocales.includes(params.lang);

  return (
    <html lang={params.lang} dir={isRtl ? 'rtl' : 'ltr'}>
      <body>
        {/* ...您的 providers 和内容... */}
        {children}
      </body>
    </html>
  );
}

通过在 <html> 标签中添加 dir="rtl",您告诉浏览器整个文档流对于该页面应该从右到左。

3. 更新 CSS 以使用逻辑属性

检查您的全局 CSS 和组件样式。将所有方向性属性替换为其逻辑等价属性。

  • margin-left 替换为 margin-inline-start
  • margin-right 替换为 margin-inline-end
  • padding-left 替换为 padding-inline-start
  • padding-right 替换为 padding-inline-end
  • 定位中的 left 替换为 inset-inline-start
  • 定位中的 right 替换为 inset-inline-end
  • text-align: left 替换为 text-align: start
  • text-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 应用于右侧,从而正确翻转组件布局。