右から左へ(RTL)のレイアウトのサポート

アラビア語やヘブライ語などの言語向けにレイアウトを適応させる

問題

アプリケーションのレイアウトは、左から右(LTR)のテキスト方向を前提としたmargin-leftpadding-rightなどのCSSプロパティで構築されています。アプリケーションがアラビア語やヘブライ語などの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を変更して、<html>タグに条件付きでdir(方向)属性を追加します。

// 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>
        {/* ...プロバイダーとコンテンツ... */}
        {children}
      </body>
    </html>
  );
}

<html>タグにdir="rtl"を追加することで、このページのドキュメントフロー全体が右から左に流れるようにブラウザに指示しています。

3. 論理的プロパティを使用するようにCSSを更新する

グローバルCSSとコンポーネントスタイルを確認します。すべての方向性プロパティを論理的な同等物に置き換えます。

  • margin-leftmargin-inline-start になります
  • margin-rightmargin-inline-end になります
  • padding-leftpadding-inline-start になります
  • padding-rightpadding-inline-end になります
  • left(位置指定において)は inset-inline-start になります
  • right(位置指定において)は inset-inline-end になります
  • text-align: lefttext-align: start になります
  • text-align: righttext-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;
}

ユーザーが /endir="ltr")にアクセスすると、padding-inline-start は左側に適用されます。ユーザーが /ardir="rtl")にアクセスすると、ブラウザは自動的に padding-inline-start を右側に適用し、コンポーネントのレイアウトを正しく反転させます。