CSS Writing Modes and Direction: Vertical Text, RTL, and Inline Flow
CSS writing modes and direction control how text flows across a page, including left-to-right, right-to-left, and vertical layouts. They are essential for internationalized interfaces, document layouts, and any design that needs to support languages such as Arabic, Hebrew, Japanese, or Mongolian.
Quick answer: Use writing-mode to choose the text flow direction and axis, and use direction to set left-to-right or right-to-left inline text order. Together, they control how lines, blocks, and alignment behave in multilingual layouts.
Difficulty: Intermediate
You'll understand this better if you know: basic CSS selectors, how the box model works, and the difference between inline and block layout.
1. What Is CSS Writing Modes and Direction?
CSS writing modes define the direction in which content is laid out, while direction sets the inline text direction within that layout. In simple terms, these properties tell the browser whether text should flow left-to-right, right-to-left, or top-to-bottom.
- writing-mode controls the overall flow axis.
- direction controls whether inline content starts on the left or right in horizontal modes.
- text-orientation controls how characters rotate in vertical writing.
- These properties are especially important for multilingual and internationalized websites.
Without them, browsers use the default horizontal left-to-right flow for most languages, which is not enough for every script or layout requirement.
2. Why CSS Writing Modes and Direction Matters
Modern websites often support more than one writing system. A single interface may need English, Arabic, and Japanese text on the same page, and each can have different reading directions and layout expectations.
These properties matter because they let you:
- display content naturally for right-to-left languages;
- build vertical titles, labels, or editorial layouts;
- keep form controls, tables, and navigation readable in mixed-language documents;
- avoid hard-coded left/right assumptions that break localization.
They are not just about aesthetics. They affect readability, accessibility, and whether your UI feels native to users in different regions.
3. Basic Syntax or Core Idea
The most important property is writing-mode. It changes how lines are stacked and where inline text begins.
Basic writing-mode values
.example {
writing-mode: horizontal-tb;
direction: ltr;
}This example uses the default horizontal top-to-bottom block flow with left-to-right inline text. The two declarations are common together in Western-language layouts.
How the core values behave
- horizontal-tb means horizontal text lines with blocks stacked top to bottom.
- vertical-rl means vertical lines with block progression from right to left.
- vertical-lr means vertical lines with block progression from left to right.
- direction: rtl changes inline content order in horizontal or vertical writing modes where direction applies.
Think of writing-mode as the main layout axis and direction as the inline starting side.
4. Step-by-Step Examples
Example 1: Default horizontal English layout
This is the normal layout most developers start with. It helps show what changes when you switch writing modes later.
p {
writing-mode: horizontal-tb;
direction: ltr;
}This keeps the text horizontal and flowing naturally from left to right.
Example 2: Right-to-left paragraph
Use this when content is written in Arabic or Hebrew, or when a localized section needs RTL flow.
.rtl {
direction: rtl;
}The browser will start inline content from the right side instead of the left side. This affects text, punctuation placement, and inline alignment behavior.
Example 3: Vertical Japanese-style text
Vertical writing is common in some East Asian layouts, especially for labels, side notes, and editorial designs.
.vertical-title {
writing-mode: vertical-rl;
text-orientation: mixed;
}This stacks lines vertically and allows characters to remain readable according to their script rules. The text-orientation value helps control how individual characters appear in vertical text.
Example 4: Mixed content inside a localized page
Sometimes only part of a page needs a different direction, such as a quoted phrase or a product code in an RTL article.
.quote {
direction: rtl;
unicode-bidi: isolate;
}This keeps the quoted content’s ordering separate from surrounding text. It is helpful when combining different scripts on the same line.
5. Practical Use Cases
- Localizing a navigation bar for Arabic or Hebrew users.
- Creating vertical headings for a magazine-style layout.
- Displaying side labels, badges, or annotations in vertical text.
- Supporting bilingual interfaces where one region uses RTL and another uses LTR.
- Preserving readable punctuation and numbers inside mixed-direction content.
In practice, these properties are often used on larger containers, not just isolated words. That makes the whole component behave consistently.
6. Common Mistakes
Mistake 1: Using direction when you need vertical layout
direction changes inline ordering, but it does not switch text from horizontal to vertical. Developers sometimes expect it to rotate the layout, which it does not do.
Problem: This code only changes text flow direction, so the content still lays out horizontally instead of vertically.
.label {
direction: rtl;
}Fix: Use writing-mode when you want the text axis to change.
.label {
writing-mode: vertical-rl;
}The corrected version works because writing-mode changes the layout flow itself, not just the inline reading order.
Mistake 2: Hard-coding left and right alignment in RTL layouts
Using physical values like left and right can produce layouts that feel wrong in RTL languages. Logical properties usually adapt better.
Problem: This text stays pinned to the physical left, which can look unnatural or inconsistent in an RTL interface.
.menu-item {
text-align: left;
}Fix: Use a logical alignment value so the browser follows the writing direction.
.menu-item {
text-align: start;
}The corrected version respects the document’s writing direction and is easier to internationalize.
Mistake 3: Forgetting isolation for mixed-direction inline text
When RTL and LTR text are mixed on the same line, the browser may reorder punctuation or numbers in surprising ways. Isolation helps prevent the surrounding text from influencing that segment.
Problem: This snippet may render unexpectedly when it sits inside content with the opposite direction.
.product-code {
direction: rtl;
}Fix: Add bidi isolation when the content must stay self-contained.
.product-code {
direction: rtl;
unicode-bidi: isolate;
}The corrected version keeps the inline run more predictable when it appears inside surrounding text with a different direction.
7. Best Practices
Use logical properties instead of physical ones where possible
Logical properties adapt to writing mode better than left/right-based styles. This reduces the amount of CSS you need when supporting localization.
.card {
padding-inline-start: 1rem;
margin-block: 0 1rem;
}This approach follows the document’s flow instead of assuming a left-to-right page.
Set direction at the right scope
Apply direction on the container that actually needs it, such as a localized section or the root element for a full page locale.
html [dir="rtl"] body {
direction: rtl;
}Scoping the direction correctly keeps the rest of the page from inheriting unintended behavior.
Use text-orientation deliberately in vertical text
Vertical writing often looks broken if character orientation is not considered. Some scripts and content types need a specific orientation to remain readable.
.vertical-note {
writing-mode: vertical-rl;
text-orientation: upright;
}Use this when the content should stay visually upright rather than rotating with the line flow.
8. Limitations and Edge Cases
- Not every component looks good in vertical writing; forms, long code samples, and dense tables often remain easier to read horizontally.
- Some layout assumptions in third-party widgets rely on left-to-right flow and may need extra styling.
- Physical properties such as left, right, margin-left, and border-left do not automatically adapt to writing mode.
- Mixed-direction text can create confusing punctuation placement if you do not isolate the segment properly.
- Vertical text support is strong in modern browsers, but some typographic details can differ by font and platform.
For internationalized layouts, test with real content in the target language instead of placeholder text. Layout problems often appear only with actual scripts, punctuation, and number patterns.
9. Practical Mini Project
Here is a small example of a multilingual article card that supports both a standard English layout and a vertical label. It combines the key properties in one usable component.
.article-card {
padding: 1.5rem;
border: 1px solid #ccc;
max-width: 28rem;
}
.article-card header {
display: flex;
gap: 1rem;
align-items: flex-start;
}
.label-vertical {
writing-mode: vertical-rl;
text-orientation: mixed;
font-weight: bold;
}
.content {
direction: ltr;
}This example shows how a single component can combine normal horizontal content with a vertical label. The key idea is that writing mode can be localized to only the part of the layout that needs it.
10. Key Points
- writing-mode changes the layout axis and line flow.
- direction controls left-to-right or right-to-left inline ordering.
- text-orientation matters when you use vertical text.
- Logical properties are usually better than physical left/right properties in internationalized layouts.
- Mixed-direction content often needs bidi isolation to render predictably.
11. Practice Exercise
- Create a small card with a title, subtitle, and a vertical status label.
- Make the status label read vertically while the main content stays horizontal.
- Then switch the card to RTL and verify that the text alignment still feels natural.
Expected output: A card with a vertical badge on one side and correctly flowing body text that adapts when the page direction changes.
Hint: Apply writing-mode only to the label, and use logical alignment values for the content area.
Solution:
.card {
display: flex;
gap: 1rem;
padding: 1rem;
border: 1px solid #ddd;
}
.status {
writing-mode: vertical-rl;
text-orientation: upright;
font-size: 0.875rem;
font-weight: bold;
}
.body {
text-align: start;
}
html [dir="rtl"] .card {
direction: rtl;
}This solution keeps the vertical label isolated from the main content and lets the content area respond naturally to the page direction.
12. Final Summary
CSS writing modes and direction let you control how text flows across the page for different languages and layouts. They are central to building interfaces that work well in both left-to-right and right-to-left scripts, as well as in special vertical text designs.
Use writing-mode when you need to change the layout axis, direction when you need RTL or LTR inline flow, and text-orientation when vertical text needs character-level control. In most real projects, these properties work best when paired with logical properties and tested with real localized content.
As a next step, try localizing a small component on your site and compare how it behaves with horizontal-tb, vertical-rl, and direction: rtl. That hands-on testing is the fastest way to build confidence with internationalized CSS.