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.

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:

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

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

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

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

11. Practice Exercise

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.