Articles

CSS Writing-Mode: Vertical Text and Logical Direction

The CSS writing-mode property switches text flow between horizontal and vertical, and it's the foundation logical properties like margin-inline build on.

Takina Takina · · 5 min read
CSS code shown in close-up on a screen

The CSS writing-mode property controls which direction text and layout flow in — horizontally or vertically, and in which order. Most web content uses the default horizontal-tb (top-to-bottom lines of horizontal text), but writing-mode also supports vertical scripts and vertical typographic layouts, and it’s the property that gives meaning to CSS’s logical directions — block and inline — which don’t always map to “top/bottom” and “left/right” the way physical properties like top and left do.

The three writing-mode values

  • horizontal-tb (the default) — lines run left-to-right or right-to-left depending on text direction, and new lines stack top-to-bottom. This is how English, Arabic, and most Latin- and Cyrillic-script content is laid out.
  • vertical-rl — lines run top-to-bottom, and new lines stack right-to-left. This is the traditional layout for Japanese and Chinese vertical text, and it’s also used stylistically in horizontal-script design for things like sidebar labels or pull quotes.
  • vertical-lr — lines run top-to-bottom, and new lines stack left-to-right. Less common than vertical-rl, but used for Mongolian traditional script and occasionally for design effect.
.vertical-label {
  writing-mode: vertical-rl;
  text-orientation: mixed;
}

text-orientation typically accompanies writing-mode in vertical layouts — it controls whether individual characters are rotated sideways (mixed, the default, which keeps Latin characters upright while rotating them into the vertical flow) or kept fully upright (upright).

Why this matters beyond CJK typography

Even on sites that never display vertical text, writing-mode matters because it defines the meaning behind CSS’s logical properties — margin-inline, padding-block, inset-inline-start, and the rest of the family covered in CSS logical properties. Those properties are defined relative to the current writing mode rather than to fixed physical directions:

  • Block direction — the direction blocks stack in (paragraphs, sections). In horizontal-tb, block flows top-to-bottom. In vertical-rl, block flows right-to-left.
  • Inline direction — the direction text flows within a line. In horizontal-tb, inline flows left-to-right (in LTR languages). In vertical-rl, inline flows top-to-bottom.

So margin-block-start means “the margin at the start of the block direction” — which is margin-top under horizontal-tb, but becomes a horizontal margin under a vertical writing mode. This is why logical properties exist at all: they let a single stylesheet adapt automatically to a writing mode or text direction change, instead of needing a parallel set of physical-property overrides for every layout direction a site supports.

Writing-mode and internationalization

For sites supporting web accessibility across right-to-left languages like Arabic or Hebrew, the more commonly used property is direction, not writing-mode — direction flips inline flow between left-to-right and right-to-left while staying in a horizontal writing mode. writing-mode is specifically about switching between horizontal and vertical flow, which matters for a narrower set of scripts and design cases. But both interact with the same logical-property system: a stylesheet written entirely in logical properties (padding-inline, border-inline-start) automatically adapts to direction: rtl without any additional rules, the same way it would adapt to a vertical writing-mode.

Practical use cases

Vertical writing mode shows up in a narrower set of situations than most CSS layout properties, but it’s not purely academic:

  • CJK-language sites — Japanese, Traditional Chinese, and Simplified Chinese content is sometimes laid out vertically, particularly for literary or editorial content, following typographic conventions carried over from print.
  • Design accents on Latin-script sites — a vertical section label, a rotated table of contents, or a sidebar heading, styled with writing-mode: vertical-rl instead of a manual CSS transform-based rotation. Using writing-mode rather than transform: rotate() keeps the text’s flow (and its accessibility semantics) correct, rather than just visually rotating a horizontal block.
  • CSS Grid and Flexbox interaction — both layout modules respect the current writing mode for their main and cross axes, so a flex-direction: row flex container lays its children out along whichever direction is “inline” for the current writing mode, not always literally left-to-right. See CSS Grid vs Flexbox for how each module defines its own axes.

Browser support and fallback behavior

writing-mode and text-orientation are well supported across modern browsers, but it’s worth checking rendering carefully when combining vertical writing modes with other layout features — scrollbars, form controls, and some third-party widgets don’t always adapt cleanly to a non-default writing mode, since much of the web’s tooling assumes horizontal-tb implicitly even when it isn’t stated. If a component looks wrong under vertical-rl, the fix is often to scope the vertical writing mode narrowly, to just the element that needs it, rather than applying it at the document or section level and fighting every child element’s assumptions about horizontal flow.

It’s also worth distinguishing writing-mode from simply rotating a block with a transform for a “vertical text” visual effect without changing the actual flow direction. A transform: rotate(90deg) on a horizontally-flowing block rotates the rendered pixels but leaves the underlying inline and block directions untouched — line wrapping, text selection, and any nested logical-property layout inside that block still behave as if the text were horizontal, just rotated after the fact. writing-mode changes the flow itself, so wrapping, hyphenation, and nested layout all follow the new direction correctly. The two approaches can look identical for a single line of static text and diverge noticeably for anything that wraps or contains further layout.

A quick comparison

horizontal-tb (default)vertical-rlvertical-lr
Line directionHorizontalVerticalVertical
New-line stackingTop to bottomRight to leftLeft to right
Typical useNearly all web contentTraditional CJK vertical text, design accentsMongolian script, rare design use

The takeaway

writing-mode switches a page’s flow between horizontal and vertical, which matters directly for a narrow set of scripts and design patterns — but its bigger, quieter role is defining what “block” and “inline” mean for the rest of CSS’s logical properties. A stylesheet built on logical properties rather than physical ones (margin-inline-start instead of margin-left) adapts automatically to a different writing mode or text direction, which is exactly the kind of internationalization work that’s painful to retrofit and nearly free to build in from the start.

Takina Takina · · 4 min read

Container Query Units: cqw, cqh, and cqi Explained

Container query units like cqw and cqi size elements relative to their containing element, not the viewport — here's how and when to use them.

#CSS #Web Development #Frontend