CSS writing-mode Property
This property controls the direction of text flow and the direction in which block-level elements are stacked.
| horizontal-tb | Sets the content to flow horizontally from left to right, with lines stacking from top to bottom. |
| vertical-rl | Sets the content to flow vertically from top to bottom, with lines stacking from right to left. |
| vertical-lr | Sets the content to flow vertically from top to bottom, with lines stacking from left to right. |
| sideways-rl | Rotates the entire line of text to the right, used primarily in vertical layouts for non-typographic reasons. |
| sideways-lr | Rotates the entire line of text to the left, used primarily in vertical layouts for non-typographic reasons. |
Code Examples
A basic example showing a container with text flowing vertically from right to left.
<div style="writing-mode: vertical-rl; background: #eeeeee; padding: 20px; border: 1px solid #333333;">
<h2 style="margin: 0;">Vertical Title</h2>
<p>This text flows from top to bottom.</p>
</div>An advanced example using JavaScript to toggle the writing mode and demonstrating how logical padding adapts to the new orientation.
<div id="layoutBox" style="writing-mode: horizontal-tb; padding-inline-start: 50px; transition: all 0.5s;">
<h1 style="color: #0066cc;">Dynamic Orientation</h1>
<button onclick="toggleFlow()">Toggle Layout</button>
</div>
<script>
function toggleFlow() {
const box = document.getElementById("layoutBox");
const isHorizontal = box.style.writingMode === "horizontal-tb";
box.style.writingMode = isHorizontal ? "vertical-lr" : "horizontal-tb";
box.style.backgroundColor = isHorizontal ? "#f4f4f4" : "#ffffff";
}
</script>Pro Tip
If you need to create a vertical sidebar title that is perfectly aligned, don't reach for transform: rotate(). Use writing-mode: vertical-rl; because it keeps the element in the normal document flow, meaning you won't have to deal with the annoying white space or overlapping issues that transforms usually leave behind.
Deep Dive
Think of writing-mode as the master switch for your layout's orientation. By default, web pages work like a standard printer paper where you write top-to-bottom. When you change this property, you are rotating the internal coordinate system. If you switch to vertical-rl, your inline axis (where characters go) runs top-to-bottom, and your block axis (where new lines or paragraphs stack) runs right-to-left. This is the foundation of logical properties. Instead of thinking about top, bottom, left, and right, you start thinking about block-start, block-end, inline-start, and inline-end. This allows a single CSS layout to adapt automatically to different languages like Japanese or Arabic without rewriting every margin and padding rule.
Best Practices
Always use logical properties like margin-inline and padding-block in conjunction with writing-mode. If you hard-code margin-left: 20px and then flip the writing-mode to vertical, that margin stays on the left, which might now be the top of your text flow. Using margin-inline-start ensures the spacing stays relative to the beginning of the sentence regardless of the orientation. Use this property for vertical headers in tables or side-tabs rather than using CSS transforms, as writing-mode handles box model calculations much more cleanly.
Common Pitfalls
A common headache is forgetting that writing-mode affects the behavior of percentage-based widths and heights. Also, centering with margin: 0 auto only works on the horizontal axis in the default mode. If you flip to a vertical mode, you would need to adjust how you handle centering because the block axis has moved. Another one is that some form elements and legacy layout techniques might not play nice when the world is turned on its side.
Accessibility
Ensure that if you use vertical text for decorative purposes, it remains legible. Screen readers generally handle writing-mode changes well because it is a structural CSS property, not just a visual paint trick. However, long passages of vertical text can be difficult for some users to read if they are not accustomed to that flow in their native language.
Dev Data Table: writing-mode property
| default | horizontal-tb |
| animatable | no |
| inherited | yes |
| experimental | no |
| year_intro | 1999 |
| year_standard | 2016 |
| js_syntax_1 | element.style.writingMode = "vertical-rl"; |
| js_syntax_2 | element.style.setProperty("writing-mode", "vertical-rl"); |
| js_note | When manipulating this via JavaScript, remember that changing the writing mode will instantly affect the layout calculations for offsetWidth and offsetHeight. |
| browsers | { "Chrome": 48, "Edge": 12, "Firefox": 41, "Safari": 10.9, "Opera": 35, "Chrome Android": 48, "Safari on iOS": 10.3, "Samsung Internet": 5, "Opera Mobile": 35 } |