Back to Blog
CSSLogical PropertiesInternationalizationRTL

CSS Logical Properties Guide

Master CSS logical properties for writing-mode aware layouts that adapt to different languages and directions.

B
Bootspring Team
Engineering
March 12, 2019
6 min read

Logical properties provide writing-mode aware alternatives to physical properties like left, right, top, and bottom. Here's how to use them for better internationalization.

Physical vs Logical#

1/* Physical properties (direction-specific) */ 2.physical { 3 margin-left: 1rem; 4 padding-right: 2rem; 5 border-top: 1px solid; 6 text-align: left; 7} 8 9/* Logical properties (flow-relative) */ 10.logical { 11 margin-inline-start: 1rem; 12 padding-inline-end: 2rem; 13 border-block-start: 1px solid; 14 text-align: start; 15} 16 17/* Logical adapts to RTL automatically */ 18html[dir="rtl"] .logical { 19 /* margin-inline-start becomes right margin 20 padding-inline-end becomes left padding */ 21}

Inline and Block Axes#

1/* 2 * Block axis: vertical in horizontal writing modes 3 * Inline axis: horizontal in horizontal writing modes 4 * 5 * In vertical writing modes, these swap! 6 */ 7 8.box { 9 /* Block dimension (height in horizontal mode) */ 10 block-size: 200px; 11 min-block-size: 100px; 12 max-block-size: 400px; 13 14 /* Inline dimension (width in horizontal mode) */ 15 inline-size: 300px; 16 min-inline-size: 200px; 17 max-inline-size: 500px; 18} 19 20/* Equivalent to width/height but flow-aware */

Margin Properties#

1.element { 2 /* Individual sides */ 3 margin-block-start: 1rem; /* top in LTR horizontal */ 4 margin-block-end: 1rem; /* bottom in LTR horizontal */ 5 margin-inline-start: 1rem; /* left in LTR */ 6 margin-inline-end: 1rem; /* right in LTR */ 7 8 /* Shorthand for block axis */ 9 margin-block: 1rem 2rem; /* block-start block-end */ 10 margin-block: 1rem; /* both block sides */ 11 12 /* Shorthand for inline axis */ 13 margin-inline: 1rem 2rem; /* inline-start inline-end */ 14 margin-inline: auto; /* center horizontally in LTR */ 15} 16 17/* Center element */ 18.centered { 19 margin-inline: auto; 20 inline-size: max-content; 21}

Padding Properties#

1.element { 2 /* Individual sides */ 3 padding-block-start: 1rem; 4 padding-block-end: 1rem; 5 padding-inline-start: 1rem; 6 padding-inline-end: 1rem; 7 8 /* Shorthands */ 9 padding-block: 2rem; 10 padding-inline: 1rem; 11} 12 13/* Card with logical padding */ 14.card { 15 padding-block: 1.5rem; 16 padding-inline: 2rem; 17} 18 19/* Navigation item */ 20.nav-item { 21 padding-inline: 1rem; 22 padding-block: 0.5rem; 23}

Border Properties#

1.element { 2 /* Individual borders */ 3 border-block-start: 1px solid #e5e7eb; 4 border-block-end: 2px solid #3b82f6; 5 border-inline-start: 3px solid #10b981; 6 border-inline-end: 1px dashed #f59e0b; 7 8 /* Border width */ 9 border-block-width: 1px 2px; 10 border-inline-width: 0 1px; 11 12 /* Border style */ 13 border-block-style: solid; 14 border-inline-style: dashed; 15 16 /* Border color */ 17 border-block-color: #e5e7eb; 18 border-inline-color: #3b82f6; 19 20 /* Shorthand */ 21 border-block: 1px solid #e5e7eb; 22 border-inline: 1px solid #3b82f6; 23} 24 25/* Underline effect */ 26.underline { 27 border-block-end: 2px solid currentColor; 28} 29 30/* Sidebar border */ 31.sidebar { 32 border-inline-end: 1px solid #e5e7eb; 33}

Border Radius#

1.element { 2 /* Logical border radius */ 3 border-start-start-radius: 8px; /* top-left in LTR */ 4 border-start-end-radius: 8px; /* top-right in LTR */ 5 border-end-start-radius: 8px; /* bottom-left in LTR */ 6 border-end-end-radius: 8px; /* bottom-right in LTR */ 7} 8 9/* Card with rounded top */ 10.card { 11 border-start-start-radius: 12px; 12 border-start-end-radius: 12px; 13} 14 15/* Pill button */ 16.pill { 17 border-start-start-radius: 999px; 18 border-end-start-radius: 999px; 19 border-start-end-radius: 999px; 20 border-end-end-radius: 999px; 21}

Inset Properties#

1.positioned { 2 position: absolute; 3 4 /* Logical inset */ 5 inset-block-start: 0; /* top in LTR horizontal */ 6 inset-block-end: 0; /* bottom in LTR horizontal */ 7 inset-inline-start: 0; /* left in LTR */ 8 inset-inline-end: 0; /* right in LTR */ 9 10 /* Shorthands */ 11 inset-block: 0; /* both block sides */ 12 inset-inline: 0; /* both inline sides */ 13 14 /* All sides */ 15 inset: 0; /* all four sides */ 16} 17 18/* Sticky header */ 19.sticky-header { 20 position: sticky; 21 inset-block-start: 0; 22} 23 24/* Sidebar */ 25.sidebar { 26 position: fixed; 27 inset-block: 0; 28 inset-inline-start: 0; 29 inline-size: 250px; 30}

Text Alignment#

1.text { 2 /* Logical text alignment */ 3 text-align: start; /* left in LTR, right in RTL */ 4 text-align: end; /* right in LTR, left in RTL */ 5} 6 7/* RTL-aware alignment */ 8.article { 9 text-align: start; 10} 11 12.price { 13 text-align: end; 14} 15 16/* Center remains center */ 17.centered { 18 text-align: center; 19}

Float and Clear#

1.element { 2 /* Logical float */ 3 float: inline-start; /* left in LTR */ 4 float: inline-end; /* right in LTR */ 5} 6 7.clearfix { 8 clear: inline-start; 9 clear: inline-end; 10} 11 12/* Image float */ 13.article img { 14 float: inline-start; 15 margin-inline-end: 1rem; 16 margin-block-end: 1rem; 17}

Overflow#

1.scrollable { 2 /* Logical overflow */ 3 overflow-block: auto; 4 overflow-inline: hidden; 5} 6 7/* Horizontal scroll container */ 8.carousel { 9 overflow-inline: auto; 10 overflow-block: hidden; 11} 12 13/* Vertical scroll container */ 14.list { 15 overflow-block: auto; 16 overflow-inline: hidden; 17}

Complete Component Example#

1/* Card component with logical properties */ 2.card { 3 inline-size: 100%; 4 max-inline-size: 400px; 5 padding-block: 1.5rem; 6 padding-inline: 2rem; 7 border-block-start: 4px solid #3b82f6; 8 border-start-start-radius: 8px; 9 border-start-end-radius: 8px; 10 border-end-start-radius: 8px; 11 border-end-end-radius: 8px; 12} 13 14.card-header { 15 margin-block-end: 1rem; 16 padding-block-end: 1rem; 17 border-block-end: 1px solid #e5e7eb; 18} 19 20.card-title { 21 text-align: start; 22 margin-block: 0; 23} 24 25.card-content { 26 margin-block-end: 1rem; 27} 28 29.card-footer { 30 display: flex; 31 justify-content: flex-end; 32 gap: 1rem; 33 padding-block-start: 1rem; 34 border-block-start: 1px solid #e5e7eb; 35}
1.nav { 2 display: flex; 3 padding-inline: 1rem; 4 border-block-end: 1px solid #e5e7eb; 5} 6 7.nav-item { 8 padding-block: 1rem; 9 padding-inline: 1.5rem; 10 border-block-end: 2px solid transparent; 11 text-align: center; 12} 13 14.nav-item.active { 15 border-block-end-color: #3b82f6; 16} 17 18.nav-item:first-child { 19 margin-inline-start: 0; 20} 21 22.nav-item:last-child { 23 margin-inline-end: 0; 24}

Form Layout#

1.form-group { 2 margin-block-end: 1.5rem; 3} 4 5.form-label { 6 display: block; 7 margin-block-end: 0.5rem; 8 text-align: start; 9} 10 11.form-input { 12 inline-size: 100%; 13 padding-block: 0.75rem; 14 padding-inline: 1rem; 15 border: 1px solid #d1d5db; 16 border-start-start-radius: 6px; 17 border-start-end-radius: 6px; 18 border-end-start-radius: 6px; 19 border-end-end-radius: 6px; 20} 21 22.form-hint { 23 margin-block-start: 0.25rem; 24 text-align: start; 25 color: #6b7280; 26} 27 28.form-actions { 29 display: flex; 30 justify-content: flex-end; 31 gap: 1rem; 32 margin-block-start: 2rem; 33 padding-block-start: 1rem; 34 border-block-start: 1px solid #e5e7eb; 35}

Best Practices#

When to Use: ✓ Multi-language applications ✓ RTL language support ✓ Component libraries ✓ New projects from scratch Migration: ✓ Start with new components ✓ Replace gradually ✓ Test with dir="rtl" ✓ Use CSS logical shorthands Naming Reference: block-start → top (horizontal-tb) block-end → bottom (horizontal-tb) inline-start → left (LTR) / right (RTL) inline-end → right (LTR) / left (RTL) Avoid: ✗ Mixing physical and logical randomly ✗ Forgetting vertical writing modes ✗ Ignoring browser support ✗ Over-complicating simple layouts

Conclusion#

CSS logical properties provide writing-mode aware alternatives to physical properties, making layouts automatically adapt to RTL languages and vertical writing modes. Use inline-* for horizontal flow, block-* for vertical flow, and start/end instead of left/right. This approach simplifies internationalization and creates more maintainable, direction-agnostic CSS for modern multilingual applications.

Share this article

Help spread the word about Bootspring