Back to Blog
CSSTypographyInternationalizationLayout

CSS Writing Modes

Master CSS writing modes for vertical text, RTL layouts, and international typography.

B
Bootspring Team
Engineering
May 21, 2020
5 min read

Writing modes control text direction and flow for international layouts. Here's how to use them.

Basic Writing Modes#

1/* Horizontal, top-to-bottom (default for English) */ 2.horizontal-tb { 3 writing-mode: horizontal-tb; 4} 5 6/* Vertical, right-to-left (traditional Chinese, Japanese) */ 7.vertical-rl { 8 writing-mode: vertical-rl; 9} 10 11/* Vertical, left-to-right */ 12.vertical-lr { 13 writing-mode: vertical-lr; 14} 15 16/* Sideways modes */ 17.sideways-rl { 18 writing-mode: sideways-rl; 19} 20 21.sideways-lr { 22 writing-mode: sideways-lr; 23}

Vertical Text#

1/* Vertical Japanese text */ 2.japanese-vertical { 3 writing-mode: vertical-rl; 4 height: 300px; 5} 6 7/* Vertical sidebar label */ 8.sidebar-label { 9 writing-mode: vertical-rl; 10 transform: rotate(180deg); 11 white-space: nowrap; 12} 13 14/* Book spine effect */ 15.book-spine { 16 writing-mode: vertical-lr; 17 text-orientation: mixed; 18 padding: 1rem; 19} 20 21/* Rotated text */ 22.rotated-text { 23 writing-mode: vertical-rl; 24 text-orientation: upright; 25}

Text Orientation#

1/* Mixed - default, keeps Latin upright in vertical text */ 2.mixed { 3 writing-mode: vertical-rl; 4 text-orientation: mixed; 5} 6 7/* Upright - all characters upright */ 8.upright { 9 writing-mode: vertical-rl; 10 text-orientation: upright; 11} 12 13/* Sideways - all characters rotated 90° */ 14.sideways { 15 writing-mode: vertical-rl; 16 text-orientation: sideways; 17}

RTL Languages#

1/* Right-to-left direction */ 2.rtl { 3 direction: rtl; 4} 5 6/* Arabic/Hebrew layout */ 7.arabic-content { 8 direction: rtl; 9 text-align: right; 10 font-family: 'Noto Sans Arabic', sans-serif; 11} 12 13/* Bidirectional text */ 14.bidi-text { 15 direction: rtl; 16 unicode-bidi: bidi-override; 17} 18 19/* Isolate bidirectional content */ 20.isolated { 21 unicode-bidi: isolate; 22} 23 24/* Embed direction */ 25.embed { 26 unicode-bidi: embed; 27}

Logical Properties#

1/* Physical properties */ 2.physical { 3 margin-left: 20px; 4 padding-top: 10px; 5 border-right: 1px solid; 6 text-align: left; 7} 8 9/* Logical properties (RTL-aware) */ 10.logical { 11 margin-inline-start: 20px; 12 padding-block-start: 10px; 13 border-inline-end: 1px solid; 14 text-align: start; 15} 16 17/* Block and inline axes */ 18.block-inline { 19 /* Block axis (vertical in horizontal-tb) */ 20 margin-block: 1rem; 21 padding-block: 1rem; 22 border-block: 1px solid; 23 24 /* Inline axis (horizontal in horizontal-tb) */ 25 margin-inline: 1rem; 26 padding-inline: 1rem; 27 border-inline: 1px solid; 28} 29 30/* Start and end */ 31.start-end { 32 margin-inline-start: 1rem; 33 margin-inline-end: 2rem; 34 margin-block-start: 1rem; 35 margin-block-end: 2rem; 36} 37 38/* Logical sizing */ 39.logical-size { 40 inline-size: 300px; /* width in horizontal-tb */ 41 block-size: 200px; /* height in horizontal-tb */ 42 min-inline-size: 100px; 43 max-block-size: 500px; 44}
1/* Vertical navigation */ 2.vertical-nav { 3 writing-mode: vertical-rl; 4 display: flex; 5 gap: 1rem; 6 padding: 1rem; 7} 8 9.vertical-nav a { 10 text-orientation: mixed; 11 padding: 0.5rem; 12} 13 14/* Tab labels */ 15.tab-label { 16 writing-mode: vertical-lr; 17 transform: rotate(180deg); 18 padding: 1rem 0.5rem; 19 cursor: pointer; 20} 21 22/* Sidebar titles */ 23.sidebar-title { 24 writing-mode: vertical-rl; 25 text-orientation: mixed; 26 font-size: 0.75rem; 27 letter-spacing: 0.1em; 28 text-transform: uppercase; 29}

Creative Typography#

1/* Vertical headline */ 2.vertical-headline { 3 writing-mode: vertical-rl; 4 font-size: 4rem; 5 font-weight: bold; 6 letter-spacing: 0.2em; 7} 8 9/* Stacked text */ 10.stacked-text { 11 writing-mode: vertical-rl; 12 text-orientation: upright; 13 letter-spacing: 0.5em; 14} 15 16/* Magazine layout */ 17.magazine-layout { 18 display: grid; 19 grid-template-columns: 50px 1fr; 20} 21 22.magazine-title { 23 writing-mode: vertical-rl; 24 font-size: 1.5rem; 25 text-align: center; 26} 27 28/* Pull quote */ 29.pull-quote { 30 writing-mode: vertical-rl; 31 font-size: 2rem; 32 font-style: italic; 33 border-inline-start: 4px solid #333; 34 padding-inline-start: 1rem; 35}

Form Layouts#

1/* Vertical form labels */ 2.vertical-form-label { 3 writing-mode: vertical-lr; 4 transform: rotate(180deg); 5 margin-inline-end: 0.5rem; 6} 7 8/* RTL form */ 9.rtl-form { 10 direction: rtl; 11} 12 13.rtl-form label { 14 display: block; 15 margin-block-end: 0.25rem; 16} 17 18.rtl-form input { 19 direction: rtl; 20 text-align: right; 21} 22 23/* Bi-directional form */ 24.bidi-form { 25 direction: rtl; 26} 27 28.bidi-form input[type="email"], 29.bidi-form input[type="tel"] { 30 direction: ltr; 31 text-align: left; 32}

Card Layouts#

1/* Vertical card */ 2.vertical-card { 3 display: flex; 4 flex-direction: column; 5 writing-mode: vertical-rl; 6 height: 400px; 7} 8 9.vertical-card-title { 10 font-size: 1.5rem; 11 text-orientation: mixed; 12} 13 14/* Side label card */ 15.side-label-card { 16 display: grid; 17 grid-template-columns: 30px 1fr; 18} 19 20.card-label { 21 writing-mode: vertical-rl; 22 transform: rotate(180deg); 23 background: #333; 24 color: white; 25 display: flex; 26 align-items: center; 27 justify-content: center; 28}

Responsive Writing Modes#

1/* Change writing mode based on viewport */ 2.adaptive-text { 3 writing-mode: horizontal-tb; 4} 5 6@media (min-width: 768px) { 7 .adaptive-text { 8 writing-mode: vertical-rl; 9 } 10} 11 12/* Responsive sidebar label */ 13.responsive-label { 14 writing-mode: horizontal-tb; 15} 16 17@media (max-width: 640px) { 18 .responsive-label { 19 writing-mode: vertical-rl; 20 transform: rotate(180deg); 21 } 22}

Japanese/Chinese Layouts#

1/* Traditional vertical Japanese */ 2.japanese-text { 3 writing-mode: vertical-rl; 4 font-family: 'Noto Sans JP', sans-serif; 5 line-height: 1.8; 6 letter-spacing: 0.05em; 7} 8 9/* Ruby annotations */ 10.ruby-text { 11 writing-mode: vertical-rl; 12} 13 14.ruby-text ruby { 15 ruby-align: center; 16} 17 18/* Manga panel */ 19.manga-panel { 20 writing-mode: vertical-rl; 21 direction: rtl; 22 text-align: start; 23} 24 25/* Newspaper column */ 26.newspaper-column { 27 writing-mode: vertical-rl; 28 columns: 3; 29 column-gap: 2rem; 30 height: 80vh; 31}

Flexbox and Grid#

1/* Flex with vertical writing */ 2.flex-vertical { 3 display: flex; 4 writing-mode: vertical-rl; 5} 6 7/* Grid adapts to writing mode */ 8.grid-rtl { 9 display: grid; 10 grid-template-columns: repeat(3, 1fr); 11 direction: rtl; /* Grid items flow right-to-left */ 12} 13 14/* Using logical properties in grid */ 15.grid-logical { 16 display: grid; 17 gap: 1rem; 18 padding-inline: 1rem; 19 margin-block: 2rem; 20}

Best Practices#

Internationalization: ✓ Use logical properties for RTL support ✓ Test with actual language content ✓ Consider text expansion ✓ Use appropriate fonts Typography: ✓ Adjust line-height for vertical text ✓ Use text-orientation appropriately ✓ Consider letter-spacing ✓ Test readability Layout: ✓ Use inline-size/block-size ✓ Think in terms of flow ✓ Test responsive behavior ✓ Consider scroll direction Avoid: ✗ Hardcoded left/right values ✗ Assuming horizontal text ✗ Ignoring reading direction ✗ Mixing physical and logical inconsistently

Conclusion#

Writing modes enable proper international typography and creative layouts. Use vertical modes for Asian languages and creative designs, logical properties for RTL support, and text-orientation for character rendering. Always test with real content in target languages.

Share this article

Help spread the word about Bootspring