Verwenden Sie eine gemeinsame CSS-Datei für LTR- und RTL-Seiten, indem Sie die HTML-Richtung explizit festlegen, logische Eigenschaften für richtungsabhängige Abstände verwenden und zwischen Layoutelementen gap einsetzen. Diese Anleitung erstellt ein lokales Beispiel mit zwei Seiten, die Sie in einem Mac-Browser vergleichen können.
Die Aufgabe besteht darin, dafür zu sorgen, dass dieselbe kleine Komponente ihren vorgesehenen Abstand beibehält, wenn sich ihre Inline-Richtung ändert. Sie benötigen einen einfachen Texteditor und einen aktuellen Desktop-Browser. Das Beispiel verwendet künstliche Beschriftungen und einen dekorativen Kreis, ohne Framework, externe Ressourcen oder JavaScript.
Was soll das gemeinsame Stylesheet steuern?
Überlassen Sie dem HTML die Richtung und dem Stylesheet die Abstände. Beide Seiten laden dieselbe CSS-Ressource und verwenden dieselben Komponentenklassen; das Seitenstamm-Element gibt entweder dir="ltr" oder dir="rtl" vor. HTML definiert rel="stylesheet" als einen Link zu einer externen Ressource, der zur Dokumentgestaltung beiträgt. HTML-Standard: Stylesheet-Links.
Verwenden Sie HTML dir, wenn die Richtung bekannt ist. Nachgeordnete Elemente übernehmen die Richtung im Allgemeinen, und lang legt sie nicht fest. Ziehen Sie für diesen kontrollierten Vergleich eine explizite Richtung gegenüber dir="auto" vor: Die automatische Richtung hängt vom Inhalt ab und würde bei den lateinischen Beispielbeschriftungen LTR wählen. MDN: das Attribut dir.
Entscheidend ist der Unterschied zwischen einer physischen Kante und einer Position im Textfluss. In der Schreibrichtung horizontal-tb dieses Beispiels bedeutet Inline-Anfang bei LTR links und bei RTL rechts. Block-Anfang bleibt oben. Logische Eigenschaften drücken diese Beziehungen direkt aus. MDN: logische Ränder, Rahmen und Innenabstände.
| Gewünschter Abstand | Gemeinsame CSS-Auswahl | Ergebnis bei Richtungsänderung |
|---|---|---|
| Abstand innerhalb der führenden Kante der Komponente | padding-inline-start |
Wandert auf die andere physische Seite |
| Abstand innerhalb beider Inline-Kanten | padding-inline |
Wendet Anfangs- und Endwerte in der neuen Richtung an |
| Abstand zwischen Flexbox-Elementen | gap |
Behält den festgelegten Abstand zwischen Elementen bei |
| Abstand oberhalb und unterhalb in diesem horizontalen Layout | padding-block |
Bleibt oberhalb und unterhalb |
| Ein Rand vor einem Element im Inline-Fluss | margin-inline-start |
Wird der neuen Inline-Anfangsseite zugeordnet |
Die Zuordnung von Rand und Innenabstand folgt Schreibrichtung und Richtung des Elements. gap erzeugt stattdessen Abstände in unterstützten Layout-Containern. Das sind getrennte Aufgaben: Verwenden Sie Innenabstand rund um den Inhalt und einen Abstand zwischen benachbarten Elementen. MDN: logische Abstände, MDN: gap.
Zwei lokale Seiten erstellen, die eine CSS-Datei verwenden
Erstellen Sie auf Ihrem Mac einen Ordner namens spacing-demo. Speichern Sie die folgenden Dateien als Klartext mit den exakten Dateiendungen. Vermeiden Sie einen Editor, der .txt an .html oder .css anhängt.
spacing-demo/
ltr.html
rtl.html
components.css
Speichern Sie dieses vollständige HTML-Dokument als ltr.html. Speichern Sie dann eine zweite Kopie als rtl.html und ändern Sie nur das Stammattribut von dir="ltr" zu dir="rtl". Behalten Sie den Stylesheet-Verweis und das Komponenten-Markup unverändert bei. Die Beschriftungen bleiben auf Englisch, da es sich um einen künstlichen Layoutvergleich handelt.
<!doctype html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Component spacing sample</title>
<link rel="stylesheet" href="components.css">
</head>
<body>
<main class="demo">
<h1>Spacing sample</h1>
<article class="sample-card">
<span class="sample-card__shape" aria-hidden="true"></span>
<div class="sample-card__copy">
<h2 class="sample-card__title">Module A</h2>
<p class="sample-card__description">A compact sample tile</p>
</div>
<span class="sample-card__tag">Set B</span>
</article>
</main>
</body>
</html>
Speichern Sie nun das folgende vollständige Stylesheet als components.css. Der absichtlich ungleiche Inline-Innenabstand macht Richtungsänderungen leicht erkennbar: Der größere Einzug sollte dem Inline-Anfang folgen.
:root {
--space-small: 8px;
--space-medium: 16px;
--space-large: 24px;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 24px;
font-family: system-ui, sans-serif;
line-height: 1.5;
color: #243447;
background: #f2f5f8;
}
.demo {
writing-mode: horizontal-tb;
max-width: 640px;
margin-inline: auto;
}
.sample-card {
display: flex;
flex-direction: row;
align-items: center;
gap: var(--space-medium);
padding-block: var(--space-medium);
padding-inline: var(--space-large) var(--space-small);
border: 1px solid #8594a5;
border-radius: 12px;
background: #ffffff;
}
.sample-card__shape {
flex: 0 0 32px;
width: 32px;
height: 32px;
border-radius: 50%;
background: #5477a3;
}
.sample-card__copy {
flex: 1 1 0;
min-width: 0;
overflow-wrap: anywhere;
}
.sample-card__title,
.sample-card__description {
margin: 0;
}
.sample-card__title {
font-size: 18px;
}
.sample-card__description {
margin-block-start: var(--space-small);
}
.sample-card__tag {
flex: 0 0 auto;
padding-block: 4px;
padding-inline: var(--space-small);
border: 1px solid #8594a5;
border-radius: 6px;
}
Hier bedeutet padding-inline: 24px 8px den Innenabstand am Anfang, gefolgt vom Innenabstand am Ende. Es bedeutet nicht links, gefolgt von rechts. Ein einzelner Wert würde auf beide Inline-Kanten angewendet. MDN: padding-inline.
Behalten Sie flex-direction: row auf beiden Seiten bei. Eine Flexbox-Zeile folgt bereits der Richtung ihres Containers: Bei LTR verläuft sie von links nach rechts und bei RTL von rechts nach links. Wenn Sie row-reverse zur RTL-Version hinzufügen, kehren Sie diese Richtung erneut um. MDN: flex-direction.
Der neutrale Kreis hat keine Richtungsbedeutung, daher bleibt seine Darstellung unverändert, während seine Position der Zeile folgt. Auch die lateinischen Beschriftungen behalten ihre Buchstabenreihenfolge bei; dieses Beispiel prüft das Komponentenlayout und nicht übersetzten Text.
Wie prüfen Sie, ob die Abstände tatsächlich gemeinsam verwendet werden?
Öffnen Sie beide HTML-Dateien in Ihrem Mac-Browser und vergleichen Sie sie bei gleicher Fensterbreite. Die folgenden Werte ergeben sich aus den Deklarationen; es handelt sich nicht um gemeldete Browsermessungen. Der Rahmen der Karte ist getrennt von ihrem Innenabstand.
| Prüfung | LTR-Seite | RTL-Seite |
|---|---|---|
| Position des Kreises | Erstes Element links | Erstes Element rechts |
| Innenabstand links an der Karte | 24px |
8px |
| Innenabstand rechts an der Karte | 8px |
24px |
| Abstand zwischen benachbarten Flex-Elementen | 16px |
16px |
| Innenabstand oben und unten an der Karte | 16px |
16px |
| Abstand vor der Beschreibung | 8px darüber |
8px darüber |
Prüfen Sie die gemeinsame Ressource unabhängig von der Richtung. Ändern Sie --space-medium in components.css von 16px auf 20px, speichern Sie die Datei und laden Sie beide Seiten neu. Bei beiden sollte der Abstand zwischen den Elementen und der Block-Innenabstand größer werden, da die Deklarationen dieselbe Variable verwenden. Setzen Sie den Wert nach dem Vergleich auf 16px zurück.
Verkleinern Sie dann das Browserfenster und ersetzen Sie die Beschreibung durch eine längere künstliche Beschriftung, zum Beispiel Module A extended sample description. Prüfen Sie, ob der Text umbricht, ohne den Kreis oder das Tag zu überdecken. Das ist ein zweiter nützlicher Test: Eine Komponente kann sich bei einer Breite korrekt spiegeln und bei einer anderen zu eng werden.
Beurteilen Sie nicht jeden sichtbaren Abstand allein anhand von gap. Elementränder, interne Innenabstände und verteilte Ausrichtung können den sichtbaren Abstand vergrößern. Das Beispiel setzt die Textränder zurück und vermeidet verteilte Ausrichtung, damit der Vergleich gut lesbar bleibt. MDN: Beschreibung von gap.
Wie migrieren Sie eine bestehende Komponente ohne Abstandskonflikte?
Beginnen Sie mit der Bedeutung jeder vorhandenen Deklaration. Ein führender Texteinzug gehört normalerweise zum Inline-Anfang; für eine bewusst festgelegte physische Kante kann weiterhin eine physische Eigenschaft erforderlich sein. Richten Sie die Umstellung an der Designabsicht aus, statt jedes Vorkommen von left mechanisch zu ersetzen.
Gehen Sie bei einer Komponente wie dieser Beispielkomponente folgendermaßen vor:
- Bestimmen Sie das übergeordnete Element, das die Richtung vorgibt.
- Ersetzen Sie richtungsabhängige Innenabstände durch logische Innenabstände.
- Ersetzen Sie bei Bedarf richtungsabhängige Außenabstände durch logische Ränder.
- Verwenden Sie
gapdes übergeordneten Elements für gewöhnliche Abstände zwischen Flex-Elementen und entfernen Sie Ränder, die zuvor denselben Abstand erzeugt haben. - Wiederholen Sie die Vergleiche mit ungleichen Innenabständen und schmalem Fenster in beiden Richtungen.
Achten Sie bei der Umstellung auf alte physische Deklarationen und spätere Kurzschreibweisen. Logische und physische Eigenschaften, die derselben Seite zugeordnet sind, nehmen gemeinsam an der Kaskade teil; eine logische Eigenschaft gewinnt nicht automatisch, weil sie logisch ist. Eine spätere Deklaration von padding kann zuvor über logische Eigenschaften festgelegte Innenabstände zurücksetzen, wenn alle anderen Kaskadenfaktoren gleich sind. CSS Logical Properties and Values Level 1: Box-Model-Eigenschaften.
Beachten Sie auch die Richtungsgrenze. Eine verschachtelte Komponente mit eigenem dir="ltr" sollte selbst innerhalb einer RTL-Seite LTR-Zuordnungen verwenden. Umgekehrt wird margin-inline selbst nicht vererbt. Geben Sie daher jeder Komponente die benötigten Abstandsdeklarationen, statt zu erwarten, dass der Rand eines übergeordneten Elements auf sie übergeht. MDN: Vererbung der Richtung, MDN: formale Definition von margin-inline.
Welche Browser-Einschränkungen beeinflussen diesen Ansatz?
MDN kennzeichnet padding-inline und margin-inline seit April 2021 als breit browserübergreifend verfügbar. Das spricht für ihre Verwendung in aktuellen Desktop-Browsern, ist aber keine Garantie für jeden älteren Browser oder jede neuere Syntax auf den Referenzseiten. Dieses Beispiel verwendet gewöhnliche Längen und auto, keine neueren Größenfunktionen. MDN: padding-inline, MDN: margin-inline.
Flexbox gap hat eine eigene Versionsgeschichte. Safari hat es mit Version 14.1 hinzugefügt; Grid gap wurde bereits seit Safari 12 unterstützt. WebKit weist ausdrücklich darauf hin, dass sich diese Kontexte nicht mit einer Property-Feature-Abfrage unterscheiden ließen. Daher reicht @supports (gap: 16px) allein nicht aus, um die Unterstützung von Flexbox gap in älteren Safari-Versionen zu erkennen. WebKit: Neue WebKit-Funktionen in Safari 14.1.
Wenn Ihr Zielbrowser logische Ränder unterstützt, aber Flexbox gap nicht, fügen Sie dieses Ersatzfragment nach den Hauptregeln des Stylesheets ein. Es stellt Abstände für diese spezielle Komponente mit einer einzelnen Zeile bereit. Verwenden Sie es wie gezeigt anstelle des aktiven gap-Abstands; für Zeilenumbrüche ist es keine allgemeine Lösung.
/* Optional single-row replacement for Flexbox gap. */
.sample-card {
gap: 0;
}
.sample-card > * + * {
margin-inline-start: var(--space-medium);
}
Für Browser, denen auch logische Eigenschaften fehlen, reicht dieser Fallback nicht aus. Verwenden Sie für die lokale Aufgabe einen aktuellen Browser oder erstellen und testen Sie für das ältere Ziel explizite physische Regeln für LTR und RTL. Treffen Sie diese browserspezifische Entscheidung unabhängig vom Hauptentwurf des gemeinsamen Stylesheets.
Der abgeschlossene Vergleich sollte einen einheitlichen Vertrag zeigen: Das HTML gibt die Richtung vor, das gemeinsame CSS legt die Abstände fest und der führende Einzug der Komponente folgt dem Inline-Anfang. Bewahren Sie die beiden lokalen Seiten als kompakte Regressionstestvorlage auf, wenn Sie Abstände oder Layout der Komponente ändern.
Quellen
- HTML-Standard — Linktyp „stylesheet“ — WHATWG.
- Globales HTML-Attribut dir — MDN Web Docs.
- Logische Eigenschaften für Ränder, Rahmen und Innenabstände — MDN Web Docs.
- CSS-Eigenschaft padding-inline — MDN Web Docs.
- CSS-Eigenschaft margin-inline — MDN Web Docs.
- CSS-Eigenschaft gap — MDN Web Docs.
- CSS-Eigenschaft flex-direction — MDN Web Docs.
- CSS Logical Properties and Values Module Level 1 — W3C.
- Neue WebKit-Funktionen in Safari 14.1 — WebKit.