Comment prendre en charge les langues de droite à gauche (RTL) dans Next.js (Pages Router) v16
Inverser les mises en page pour l'arabe et l'hébreu
Problème
La plupart des mises en page web supposent un flux de texte de gauche à droite. Les menus de navigation s'ancrent à gauche, le contenu se lit de gauche à droite, et l'espacement est appliqué avec des propriétés comme margin-left ou padding-right. Lorsqu'une application est traduite en arabe ou en hébreu, ces langues se lisent de droite à gauche, et toute la mise en page visuelle doit s'inverser pour correspondre. Sans inversion, les utilisateurs font face à une interface désorientante où la hiérarchie visuelle contredit leur sens de lecture naturel, rendant la navigation confuse et l'application peu soignée.
Le défi va au-delà de l'alignement du texte. Les propriétés CSS physiques comme left, right, margin-left et padding-right sont liées à des positions d'écran fixes plutôt qu'au flux de contenu. Lorsque la direction du texte change, ces propriétés restent ancrées aux mêmes bords physiques, empêchant la mise en page de s'adapter naturellement.
Solution
Définir l'attribut de direction du texte du document pour correspondre à la locale actuelle, permettant aux navigateurs d'inverser automatiquement le flux de mise en page pour les langues RTL. Remplacer les propriétés CSS physiques par des propriétés logiques qui référencent le flux de contenu plutôt que la position à l'écran. Les propriétés logiques comme margin-inline-start et padding-inline-end se mappent automatiquement au bon bord physique en fonction de la direction du texte, permettant aux mises en page de s'inverser sans code supplémentaire ni style conditionnel complexe.
Cette approche crée des mises en page indépendantes de la direction qui fonctionnent correctement pour les langues LTR et RTL sans dupliquer les styles ni ajouter de logique complexe.
Étapes
1. Créer une fonction utilitaire pour déterminer la direction du texte à partir de la locale
Les propriétés logiques s'adaptent en fonction de la direction du texte, avec margin-inline-start équivalent à margin-left dans les contextes LTR et margin-right dans les contextes RTL. Créez une fonction utilitaire qui mappe les locales à leur direction de texte.
export function getDirection(locale: string): "ltr" | "rtl" {
const rtlLocales = ["ar", "he", "fa", "ur"];
return rtlLocales.includes(locale) ? "rtl" : "ltr";
}
Cette fonction identifie les langues RTL et renvoie la valeur de direction appropriée pour une utilisation dans HTML et CSS.
2. Définir l'attribut de direction du document
Les classes Document personnalisées peuvent remplacer la méthode render pour personnaliser l'élément HTML avec des attributs tels que lang et dir. Créez un Document personnalisé pour définir l'attribut dir sur l'élément HTML racine en fonction de la locale actuelle.
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
} from "next/document";
import { getDirection } from "../utils/direction";
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const initialProps = await Document.getInitialProps(ctx);
return initialProps;
}
render() {
const locale = this.props.__NEXT_DATA__.locale || "en";
const dir = getDirection(locale);
return (
<Html lang={locale} dir={dir}>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
Le routeur Next.js fournit la locale actuellement active via la propriété locale. Le document lit la locale à partir des données de routage Next.js et applique la direction correspondante à l'élément HTML, activant ainsi la prise en charge RTL au niveau du navigateur.
3. Remplacer les propriétés CSS physiques par des équivalents logiques
Les propriétés logiques telles que margin-inline-start, padding-inline-start et leurs formes abrégées margin-inline et padding-inline se mappent automatiquement aux propriétés physiques en fonction du mode d'écriture et de la direction. Mettez à jour les styles de vos composants pour utiliser des propriétés relatives au flux.
export default function Navigation() {
return (
<nav className="nav">
<ul className="nav-list">
<li className="nav-item">Home</li>
<li className="nav-item">About</li>
<li className="nav-item">Contact</li>
</ul>
</nav>
);
}
.nav {
padding-inline: 1rem;
border-inline-start: 4px solid blue;
}
.nav-list {
display: flex;
gap: 1rem;
margin-block: 0;
padding-inline-start: 0;
}
.nav-item {
margin-inline-end: 1.5rem;
}
Les propriétés logiques pour margin, padding et inset facilitent le positionnement des éléments et le rendent plus efficace dans tous les modes d'écriture. Ces propriétés s'inversent automatiquement dans les contextes RTL sans styles supplémentaires ni media queries.
4. Utiliser les propriétés logiques pour le positionnement
Pour les éléments positionnés de manière absolue ou relative, remplacez left et right par inset-inline-start et inset-inline-end.
export default function Sidebar() {
return (
<aside className="sidebar">
<button className="close-button">×</button>
<p>Sidebar content</p>
</aside>
);
}
.sidebar {
position: fixed;
inset-inline-start: 0;
inset-block-start: 0;
inline-size: 250px;
block-size: 100vh;
padding-inline: 1rem;
}
.close-button {
position: absolute;
inset-inline-end: 0.5rem;
inset-block-start: 0.5rem;
}
La propriété width est remplacée par inline-size et height par block-size dans la méthodologie des propriétés logiques. Ces propriétés garantissent que les éléments positionnés apparaissent du bon côté pour la direction de texte actuelle.
5. Appliquer l'alignement de texte logique
Remplacez text-align: left et text-align: right par text-align: start et text-align: end.
.content {
text-align: start;
}
.metadata {
text-align: end;
margin-inline-start: auto;
}
Les propriétés logiques font référence aux bords d'une boîte en relation avec le flux du contenu plutôt qu'aux dimensions physiques de la fenêtre d'affichage. Les valeurs d'alignement de texte start et end s'adaptent automatiquement à la direction du texte, alignant le contenu de manière appropriée pour les langues LTR et RTL.