# CSS Writing Modes and Direction: Vertical Text, RTL, and Inline Flow

Source: https://devdocs10.com/articles/css/css-writing-modes  
By Murat Bo · Published 2026-09-08 · DevDocs10 (https://devdocs10.com)

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

The most important property is `writing-mode`. It changes how lines are stacked and where inline text begins.

### Basic writing-mode values

```css
.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.

```css
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.

```css
.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.

```css
.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.

```css
.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.

```css
.label {
  direction: rtl;
}
```

**Fix:** Use `writing-mode` when you want the text axis to change.

```css
.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.

```css
.menu-item {
  text-align: left;
}
```

**Fix:** Use a logical alignment value so the browser follows the writing direction.

```css
.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.

```css
.product-code {
  direction: rtl;
}
```

**Fix:** Add bidi isolation when the content must stay self-contained.

```css
.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.

```css
.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.

```css
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.

```css
.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.

```css
.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:**

```css
.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.

## Browser Support

| Feature | Status | Chrome | Edge | Firefox | Safari | Safari iOS |
| --- | --- | --- | --- | --- | --- | --- |
| writing-mode | Widely available since Sep 2019 | 48+ | 12+ | 41+ | 10.1+ | 10.3+ |

Data: web-features 3.43.0 (MDN Baseline).
