Поддержка макетов с направлением справа налево (RTL)

Адаптация вашего макета для языков, таких как арабский и иврит

Проблема

Макет приложения создается с использованием CSS-свойств, таких как margin-left и padding-right, которые предполагают направление текста слева направо (LTR). Когда приложение переводится на язык с направлением текста справа налево (RTL), например, арабский или иврит, весь макет отображается в обратном порядке, с несоответствующим выравниванием контента и нечитаемым видом.

Решение

Перейдите от направленных CSS-свойств (left/right) к их современным, независимым от направления логическим эквивалентам (start/end). Установите атрибут dir в элементе <html> в зависимости от текущего языка, и браузер автоматически скорректирует макет.

Шаги

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>
        {/* ...ваши провайдеры и контент... */}
        {children}
      </body>
    </html>
  );
}

Добавляя dir="rtl" в тег <html>, вы указываете браузеру, что весь поток документа для этой страницы должен быть справа налево.

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 к правой стороне, корректно переворачивая макет вашего компонента.