Back to Blog
CSSLogical Propertiesi18nLayout

CSS Logical Properties Guide

Master CSS logical properties. From writing modes to internationalization to modern layout patterns.

B
Bootspring Team
Engineering
May 4, 2021
6 min read

Logical properties adapt layouts for different writing modes and languages. Here's how to use them.

Physical vs Logical#

1/* Physical properties (direction-dependent) */ 2.physical { 3 margin-left: 1rem; 4 margin-right: 1rem; 5 padding-top: 2rem; 6 padding-bottom: 2rem; 7 border-left: 2px solid blue; 8 width: 200px; 9 height: 100px; 10} 11 12/* Logical properties (writing-mode-aware) */ 13.logical { 14 margin-inline-start: 1rem; 15 margin-inline-end: 1rem; 16 padding-block-start: 2rem; 17 padding-block-end: 2rem; 18 border-inline-start: 2px solid blue; 19 inline-size: 200px; 20 block-size: 100px; 21}

Block and Inline Axes#

1/* 2 Block axis: Direction blocks stack (vertical in LTR/RTL) 3 Inline axis: Direction text flows (horizontal in LTR/RTL) 4 5 In horizontal writing modes: 6 block = vertical (top/bottom) 7 inline = horizontal (left/right) 8 9 In vertical writing modes: 10 block = horizontal (left/right) 11 inline = vertical (top/bottom) 12*/ 13 14.element { 15 /* Block axis (top/bottom in horizontal modes) */ 16 margin-block: 1rem; /* margin-top + margin-bottom */ 17 margin-block-start: 1rem; /* margin-top */ 18 margin-block-end: 2rem; /* margin-bottom */ 19 20 /* Inline axis (left/right in horizontal modes) */ 21 margin-inline: 1rem; /* margin-left + margin-right */ 22 margin-inline-start: 1rem; /* margin-left in LTR, margin-right in RTL */ 23 margin-inline-end: 2rem; /* margin-right in LTR, margin-left in RTL */ 24}

Sizing Properties#

1.element { 2 /* Physical */ 3 width: 300px; 4 height: 200px; 5 min-width: 100px; 6 max-height: 400px; 7 8 /* Logical equivalents */ 9 inline-size: 300px; /* width in horizontal modes */ 10 block-size: 200px; /* height in horizontal modes */ 11 min-inline-size: 100px; /* min-width */ 12 max-block-size: 400px; /* max-height */ 13} 14 15/* Responsive with logical properties */ 16.card { 17 inline-size: 100%; 18 max-inline-size: 400px; 19 block-size: auto; 20 min-block-size: 200px; 21}

Padding and Margin#

1/* Shorthand logical properties */ 2.element { 3 /* Two values: block | inline */ 4 margin: 1rem 2rem; 5 /* Logical equivalent */ 6 margin-block: 1rem; 7 margin-inline: 2rem; 8 9 /* All four sides */ 10 padding: 1rem 2rem 3rem 4rem; 11 /* Logical: start/end are direction-aware */ 12 padding-block-start: 1rem; 13 padding-inline-end: 2rem; 14 padding-block-end: 3rem; 15 padding-inline-start: 4rem; 16} 17 18/* Common patterns */ 19.container { 20 padding-inline: 1rem; /* Left and right padding */ 21 padding-block: 2rem; /* Top and bottom padding */ 22} 23 24.section { 25 margin-block-end: 3rem; /* Space below section */ 26} 27 28.list-item { 29 padding-inline-start: 1.5rem; /* Indent from start */ 30}

Border Properties#

1.element { 2 /* Physical */ 3 border-top: 1px solid black; 4 border-right: 2px solid red; 5 border-bottom: 1px solid black; 6 border-left: 2px solid red; 7 border-top-left-radius: 4px; 8 9 /* Logical */ 10 border-block-start: 1px solid black; 11 border-inline-end: 2px solid red; 12 border-block-end: 1px solid black; 13 border-inline-start: 2px solid red; 14 border-start-start-radius: 4px; /* top-left in LTR */ 15} 16 17/* Border radius logical values */ 18.rounded { 19 /* start-start = top-left in LTR, top-right in RTL */ 20 border-start-start-radius: 8px; 21 /* start-end = top-right in LTR, top-left in RTL */ 22 border-start-end-radius: 8px; 23 /* end-start = bottom-left in LTR, bottom-right in RTL */ 24 border-end-start-radius: 8px; 25 /* end-end = bottom-right in LTR, bottom-left in RTL */ 26 border-end-end-radius: 8px; 27}

Position Properties#

1.element { 2 position: absolute; 3 4 /* Physical */ 5 top: 0; 6 right: 0; 7 bottom: auto; 8 left: auto; 9 10 /* Logical */ 11 inset-block-start: 0; /* top */ 12 inset-inline-end: 0; /* right in LTR */ 13 inset-block-end: auto; /* bottom */ 14 inset-inline-start: auto; /* left in LTR */ 15} 16 17/* Shorthand */ 18.cover { 19 position: absolute; 20 inset: 0; /* All sides 0 */ 21} 22 23.sidebar { 24 position: fixed; 25 inset-block: 0; /* top: 0; bottom: 0; */ 26 inset-inline-start: 0; /* left: 0 in LTR */ 27 inline-size: 250px; 28}

Text Alignment#

1.element { 2 /* Physical */ 3 text-align: left; 4 5 /* Logical */ 6 text-align: start; /* left in LTR, right in RTL */ 7} 8 9/* Text alignment values */ 10.text { 11 text-align: start; /* Beginning of text direction */ 12 text-align: end; /* End of text direction */ 13} 14 15/* Float logical values */ 16.float-start { 17 float: inline-start; /* float: left in LTR */ 18} 19 20.float-end { 21 float: inline-end; /* float: right in LTR */ 22} 23 24/* Clear logical values */ 25.clear-start { 26 clear: inline-start; 27}

Writing Modes#

1/* Horizontal top-to-bottom (default) */ 2.horizontal-tb { 3 writing-mode: horizontal-tb; 4 /* Block flows top to bottom */ 5 /* Inline flows left to right (or right to left) */ 6} 7 8/* Vertical right-to-left (Japanese, Traditional Chinese) */ 9.vertical-rl { 10 writing-mode: vertical-rl; 11 /* Block flows right to left */ 12 /* Inline flows top to bottom */ 13} 14 15/* Vertical left-to-right */ 16.vertical-lr { 17 writing-mode: vertical-lr; 18 /* Block flows left to right */ 19 /* Inline flows top to bottom */ 20} 21 22/* Example: Vertical sidebar labels */ 23.sidebar-label { 24 writing-mode: vertical-rl; 25 text-orientation: mixed; 26 padding-block: 1rem; 27 padding-inline: 0.5rem; 28}

RTL Support#

1/* Direction property */ 2html[dir="rtl"] { 3 direction: rtl; 4} 5 6/* With logical properties, no direction-specific CSS needed */ 7.card { 8 padding-inline-start: 1rem; 9 border-inline-start: 4px solid blue; 10 margin-inline-end: 2rem; 11} 12 13/* Flexbox is already logical */ 14.flex-row { 15 display: flex; 16 flex-direction: row; 17 /* Items flow in text direction automatically */ 18 gap: 1rem; 19} 20 21/* Grid is also logical */ 22.grid { 23 display: grid; 24 grid-template-columns: 1fr 2fr; 25 /* Columns follow inline direction */ 26}

Practical Examples#

1/* Navigation with icon */ 2.nav-link { 3 display: flex; 4 align-items: center; 5 gap: 0.5rem; 6 padding-block: 0.75rem; 7 padding-inline: 1rem; 8} 9 10.nav-link .icon { 11 margin-inline-end: 0.5rem; 12} 13 14/* Card component */ 15.card { 16 border-radius: 8px; 17 padding: 1.5rem; 18 margin-block-end: 1rem; 19} 20 21.card-header { 22 border-block-end: 1px solid #eee; 23 padding-block-end: 1rem; 24 margin-block-end: 1rem; 25} 26 27/* Sidebar layout */ 28.layout { 29 display: flex; 30} 31 32.sidebar { 33 inline-size: 250px; 34 border-inline-end: 1px solid #ddd; 35 padding-inline-end: 1rem; 36} 37 38.main-content { 39 flex: 1; 40 padding-inline-start: 2rem; 41} 42 43/* Quote with border */ 44blockquote { 45 border-inline-start: 4px solid #3b82f6; 46 padding-inline-start: 1rem; 47 margin-inline: 0; 48 margin-block: 1rem; 49}

Scroll Properties#

1.element { 2 /* Physical */ 3 overflow-x: auto; 4 overflow-y: hidden; 5 scroll-padding-left: 1rem; 6 7 /* Logical */ 8 overflow-inline: auto; 9 overflow-block: hidden; 10 scroll-padding-inline-start: 1rem; 11} 12 13/* Scroll snap with logical properties */ 14.carousel { 15 display: flex; 16 overflow-inline: auto; 17 scroll-snap-type: inline mandatory; 18 scroll-padding-inline: 1rem; 19} 20 21.carousel-item { 22 scroll-snap-align: start; 23 flex: 0 0 auto; 24 inline-size: 300px; 25}

Migration Strategy#

1/* Gradual adoption */ 2 3/* Old code */ 4.element { 5 margin-left: 1rem; 6 margin-right: 1rem; 7 padding-top: 2rem; 8 padding-bottom: 2rem; 9} 10 11/* Step 1: Add logical properties alongside */ 12.element { 13 margin-left: 1rem; 14 margin-right: 1rem; 15 margin-inline: 1rem; /* Overrides in supporting browsers */ 16 17 padding-top: 2rem; 18 padding-bottom: 2rem; 19 padding-block: 2rem; /* Overrides in supporting browsers */ 20} 21 22/* Step 2: Remove physical properties when support is sufficient */ 23.element { 24 margin-inline: 1rem; 25 padding-block: 2rem; 26}

Best Practices#

Adoption: ✓ Use logical properties for new code ✓ Migrate gradually ✓ Test with RTL languages ✓ Consider writing mode changes Naming: ✓ block = vertical (in horizontal modes) ✓ inline = horizontal (in horizontal modes) ✓ start/end instead of left/right ✓ Use shorthand when possible Avoid: ✗ Mixing physical and logical for same property ✗ Assuming left-to-right only ✗ Forgetting border-radius logical values ✗ Ignoring writing-mode contexts

Conclusion#

Logical properties create layouts that adapt to different writing modes and text directions. Use them for international-ready designs, replacing physical properties like margin-left with margin-inline-start. They're well-supported in modern browsers and essential for RTL language support.

Share this article

Help spread the word about Bootspring