Wie man Rechts-nach-Links (RTL) Sprachen in Next.js (Pages Router) v16 unterstützt
Spiegelung von Layouts für Arabisch und Hebräisch
Problem
Die meisten Web-Layouts gehen von einem Textfluss von links nach rechts 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 entsprechend gespiegelt werden. Ohne Spiegelung erleben Benutzer eine desorientierte Benutzeroberfläche, bei der die visuelle Hierarchie ihrer natürlichen Leserichtung widerspricht, was die Navigation verwirrend macht und die Anwendung unfertig 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 der aktuellen Sprache 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 beziehen und nicht auf die Bildschirmposition. Logische Eigenschaften wie margin-inline-start und padding-inline-end werden automatisch auf die richtige physische Kante abgebildet, basierend auf der Textrichtung, wodurch Layouts sich selbst spiegeln können, ohne zusätzlichen Code oder bedingte Stilisierung.
Dieser Ansatz schafft 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 einen Helfer, um die Textrichtung aus der Sprache zu bestimmen
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 Sprachen 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. Setzen des document-direction-Attributs
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 im root-HTML-Element basierend auf der aktuellen Locale zu setzen.
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 die RTL-Unterstützung auf Browser-Ebene aktiviert wird.
3. Ersetzen physischer CSS-Eigenschaften durch logische Äquivalente
Logische Eigenschaften wie margin-inline-start, padding-inline-start und ihre Kurzformen margin-inline und padding-inline werden automatisch auf physische Eigenschaften abgebildet, basierend auf Schreibmodus und Richtung. Aktualisieren Sie Ihre Komponenten-Styles, um flow-relative 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 und machen sie effizienter über verschiedene Schreibmodi hinweg. Diese Eigenschaften werden in RTL-Kontexten automatisch umgekehrt, ohne zusätzliche Styles oder Media Queries.
4. Verwenden Sie logische Eigenschaften für die Positionierung
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 logischen Eigenschaftsmethodik durch inline-size und height durch block-size ersetzt. Diese Eigenschaften stellen sicher, dass positionierte Elemente auf der richtigen Seite für die aktuelle Textrichtung 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. Die Textausrichtungswerte 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.