Поддержка макетов с направлением справа налево (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=Arabic, he=Hebrew
export const defaultLocale = 'en';
export const localeCookieName = 'NEXT_LOCALE';
export const rtlLocales = ['ar', 'he'];
2. Установите атрибут dir в корневом макете
Измените ваш app/[lang]/layout.tsx, чтобы условно добавлять атрибут dir (direction) к тегу <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 };
}) {
// 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>
);
}
Добавляя dir="rtl" к тегу <html>, вы сообщаете браузеру, что весь поток документа для этой страницы должен быть справа налево.
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 справа, корректно переворачивая ваш компонент.