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.