So unterstützen Sie Rechts-nach-links-Sprachen (RTL) in Next.js (Pages Router) v16
Layouts für Arabisch und Hebräisch spiegeln
Problem
Die meisten Web-Layouts gehen von einem Links-nach-rechts-Textfluss aus. Navigationsmenüs sind links verankert, Inhalte werden von links nach rechts gelesen und Abstände werden mit Eigenschaften wie margin-left oder padding-right angewendet. Wenn eine Anwendung ins Arabische oder Hebräische übersetzt wird, werden diese Sprachen von rechts nach links gelesen, und das gesamte visuelle Layout sollte gespiegelt werden, um dies zu berücksichtigen. Ohne Spiegelung erleben Benutzer eine desorientierte Oberfläche, bei der die visuelle Hierarchie ihrer natürlichen Leserichtung widerspricht, was die Navigation verwirrend macht und die Anwendung unausgereift wirken lässt.
Die Herausforderung geht über die Textausrichtung hinaus. Physische CSS-Eigenschaften wie left, right, margin-left und padding-right sind an feste Bildschirmpositionen gebunden und nicht an den Inhaltsfluss. Wenn sich die Textrichtung ändert, bleiben diese Eigenschaften an denselben physischen Kanten verankert, was verhindert, dass sich das Layout natürlich anpasst.
Lösung
Setzen Sie das Textrichtungsattribut des Dokuments so, dass es dem aktuellen Gebietsschema entspricht, damit Browser den Layout-Fluss für RTL-Sprachen automatisch umkehren können. Ersetzen Sie physische CSS-Eigenschaften durch logische Eigenschaften, die sich auf den Inhaltsfluss statt auf die Bildschirmposition beziehen. Logische Eigenschaften wie margin-inline-start und padding-inline-end werden basierend auf der Textrichtung automatisch der richtigen physischen Kante zugeordnet, sodass sich Layouts ohne zusätzlichen Code oder bedingtes Styling selbst spiegeln können.
Dieser Ansatz erstellt richtungsunabhängige Layouts, die sowohl für LTR- als auch für RTL-Sprachen korrekt funktionieren, ohne Stile zu duplizieren oder komplexe Logik hinzuzufügen.
Schritte
1. Erstellen Sie eine Hilfsfunktion zur Bestimmung der Textrichtung aus dem Gebietsschema
Logische Eigenschaften passen sich basierend auf der Textrichtung an, wobei margin-inline-start in LTR-Kontexten margin-left und in RTL-Kontexten margin-right entspricht. Erstellen Sie eine Hilfsfunktion, die Locales ihrer Textrichtung zuordnet.
export function getDirection(locale: string): "ltr" | "rtl" {
const rtlLocales = ["ar", "he", "fa", "ur"];
return rtlLocales.includes(locale) ? "rtl" : "ltr";
}
Diese Funktion identifiziert RTL-Sprachen und gibt den entsprechenden Richtungswert zur Verwendung in HTML und CSS zurück.
2. Dokumentrichtungsattribut festlegen
Benutzerdefinierte Document-Klassen können die Render-Methode überschreiben, um das HTML-Element mit Attributen wie lang und dir anzupassen. Erstellen Sie ein benutzerdefiniertes Document, um das dir-Attribut auf dem Root-HTML-Element basierend auf der aktuellen Locale festzulegen.
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;
Der Next.js-Router stellt die aktuell aktive Locale über die locale-Eigenschaft bereit. Das Document liest die Locale aus den Next.js-Routing-Daten und wendet die entsprechende Richtung auf das HTML-Element an, wodurch RTL-Unterstützung auf Browser-Ebene ermöglicht wird.
3. Physische CSS-Eigenschaften durch logische Äquivalente ersetzen
Logische Eigenschaften wie margin-inline-start, padding-inline-start und ihre Kurzformen margin-inline und padding-inline werden automatisch basierend auf Schreibmodus und Richtung auf physische Eigenschaften abgebildet. Aktualisieren Sie Ihre Komponenten-Styles, um flussrelative Eigenschaften zu verwenden.
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;
}
Logische Eigenschaften für margin, padding und inset erleichtern die Positionierung von Elementen über verschiedene Schreibmodi hinweg und machen sie effizienter. Diese Eigenschaften kehren sich in RTL-Kontexten automatisch um, ohne zusätzliche Styles oder Media Queries.
4. Logische Eigenschaften für Positionierung verwenden
Ersetzen Sie bei absolut oder relativ positionierten Elementen left und right durch inset-inline-start und 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;
}
Die width-Eigenschaft wird in der Methodik logischer Eigenschaften durch inline-size und height durch block-size ersetzt. Diese Eigenschaften stellen sicher, dass positionierte Elemente für die aktuelle Textrichtung auf der korrekten Seite erscheinen.
5. Logische Textausrichtung anwenden
Ersetzen Sie text-align: left und text-align: right durch text-align: start und text-align: end.
.content {
text-align: start;
}
.metadata {
text-align: end;
margin-inline-start: auto;
}
Logische Eigenschaften beziehen sich auf die Kanten einer Box in Bezug auf den Inhaltsfluss und nicht auf physische Viewport-Dimensionen. Textausrichtungswerte von start und end passen sich automatisch an die Textrichtung an und richten den Inhalt sowohl für LTR- als auch für RTL-Sprachen entsprechend aus.