CSS Logical Properties

Introduction to Logical Properties

CSS Logical Properties provide a way to control layout through logical, rather than physical, direction and dimension mappings. This makes creating internationalized layouts much easier, especially for languages that use different writing modes.

Browser Support: CSS Logical Properties are supported in all modern browsers including Chrome, Firefox, Safari, and Edge. Some older browser versions may require vendor prefixes or lack support for certain properties.

Why Logical Properties Matter

Traditional CSS properties like margin-left or border-right are based on physical directions. This creates challenges when supporting languages with different writing directions:

Left-to-right (LTR)

Languages that read from left to right.

Examples:
  • English
  • Spanish
  • French
  • German
  • Italian
  • Portuguese
Hello World

Right-to-left (RTL)

Languages that read from right to left.

Examples:
  • Arabic
  • Hebrew
  • Persian (Farsi)
  • Urdu
  • Kurdish
  • Yiddish
مرحبا بالعالم

Top-to-bottom

Languages that can be written vertically.

Examples:
  • Traditional Chinese
  • Japanese
  • Korean
  • Mongolian
こんにちは世界

The Problem with Physical Properties

When building multilingual websites, physical properties create several challenges:

Without Logical Properties

/* LTR Styles */
.sidebar {
  float: left;
  margin-right: 20px;
  border-right: 1px solid gray;
  text-align: left;
}

/* RTL Styles - Duplicate code needed */
[dir="rtl"] .sidebar {
  float: right;
  margin-left: 20px;
  margin-right: 0;
  border-left: 1px solid gray;
  border-right: none;
  text-align: right;
}
Problems:
  • Duplicate code maintenance
  • Easy to miss properties when updating
  • Complex selectors with direction attributes
  • Prone to inconsistencies

With Logical Properties

/* Works for both LTR and RTL */
.sidebar {
  float: inline-start;
  margin-inline-end: 20px;
  border-inline-end: 1px solid gray;
  text-align: start;
}

/* No duplicate code needed! */
Benefits:
  • Single codebase for all languages
  • Automatically adapts to writing direction
  • Simpler maintenance
  • More robust internationalization

Logical Property Concepts

Logical properties use these key concepts to replace physical directions:

Logical Concept Description LTR Equivalent RTL Equivalent Vertical Writing Mode
Inline The direction text flows within a line Horizontal (left-to-right) Horizontal (right-to-left) Vertical
Block The direction blocks stack Vertical (top-to-bottom) Vertical (top-to-bottom) Horizontal
Start The beginning of a flow Left Right Top (or side, depending on writing mode)
End The end of a flow Right Left Bottom (or side, depending on writing mode)
Key Insight: With logical properties, you define layout relative to text flow, not physical screen directions. This means your layout automatically adapts to different writing modes and directions without requiring separate stylesheets or conditional code.

Historical Context

CSS Logical Properties evolved from the need to better support international layouts:

  • Early CSS (1990s): Focused primarily on LTR languages with physical properties only
  • CSS 2.1 (2011): Added direction and unicode-bidi properties, but still required duplicate styles
  • CSS Writing Modes Level 3 (2015): Introduced logical properties as a working draft
  • CSS Logical Properties Level 1 (2018-present): Formalized the specification, now widely implemented

Physical vs. Logical Properties

Mapping Physical to Logical Properties

Physical Property Logical Property LTR Equivalent RTL Equivalent
margin-top margin-block-start margin-top margin-top
margin-bottom margin-block-end margin-bottom margin-bottom
margin-left margin-inline-start margin-left margin-right
margin-right margin-inline-end margin-right margin-left
padding-top padding-block-start padding-top padding-top
padding-bottom padding-block-end padding-bottom padding-bottom
padding-left padding-inline-start padding-left padding-right
padding-right padding-inline-end padding-right padding-left
border-top border-block-start border-top border-top
border-bottom border-block-end border-bottom border-bottom
border-left border-inline-start border-left border-right
border-right border-inline-end border-right border-left

Dimension Properties

Physical Property Logical Property LTR Equivalent
width inline-size width
height block-size height
min-width min-inline-size min-width
min-height min-block-size min-height
max-width max-inline-size max-width
max-height max-block-size max-height

Using Logical Properties

Practical Benefit: By using logical properties, you can maintain a single codebase that works correctly across different languages and writing modes, reducing maintenance overhead and ensuring consistent layouts.

Basic Usage

Physical Properties

/* Traditional physical properties */
.box-physical {
  margin-top: 10px;
  margin-right: 20px;
  margin-bottom: 10px;
  margin-left: 20px;
  
  padding-top: 15px;
  padding-right: 25px;
  padding-bottom: 15px;
  padding-left: 25px;
  
  border-top: 1px solid black;
  border-right: 2px solid black;
  border-bottom: 1px solid black;
  border-left: 2px solid black;
}

Logical Properties

/* Equivalent logical properties */
.box-logical {
  margin-block-start: 10px;
  margin-inline-end: 20px;
  margin-block-end: 10px;
  margin-inline-start: 20px;
  
  padding-block-start: 15px;
  padding-inline-end: 25px;
  padding-block-end: 15px;
  padding-inline-start: 25px;
  
  border-block-start: 1px solid black;
  border-inline-end: 2px solid black;
  border-block-end: 1px solid black;
  border-inline-start: 2px solid black;
}

Shorthand Properties

CSS Logical Properties offer convenient shorthands similar to their physical counterparts:

Block Axis Shorthands

Controls the block direction (usually top/bottom in horizontal writing modes):

/* Block axis shorthands */
.element {
  /* Sets both block-start and block-end */
  margin-block: 10px;
  padding-block: 15px;
  border-block: 1px solid;
  
  /* Individual sides with values */
  margin-block: 10px 20px; /* start end */
  padding-block: 15px 25px; /* start end */
}
Block axis example (margin-block, padding-block, border-block)

Inline Axis Shorthands

Controls the inline direction (left/right in LTR, right/left in RTL):

/* Inline axis shorthands */
.element {
  /* Sets both inline-start and inline-end */
  margin-inline: 20px;
  padding-inline: 25px;
  border-inline: 2px solid;
  
  /* Individual sides with values */
  margin-inline: 20px 30px; /* start end */
  padding-inline: 25px 35px; /* start end */
}
Inline axis example (margin-inline, padding-inline, border-inline)

Individual Border Properties

You can control individual aspects of borders using logical properties:

/* Individual border properties */
.element {
  /* Long-form individual properties */
  border-block-start-width: 1px;
  border-block-start-style: solid;
  border-block-start-color: black;
  
  /* Shorthand for a single edge */
  border-block-start: 1px solid black;
  
  /* Different borders for different edges */
  border-block-start: 2px solid blue;
  border-inline-end: 1px dashed red;
  border-block-end: 2px dotted green;
  border-inline-start: 1px solid orange;
}
Different border styles on each logical edge
Same CSS, but in RTL mode (notice how inline borders switch)

Logical Values for Float and Clear

Float and clear properties also have logical counterparts:

Physical Values

/* Physical values */
.float-left {
  float: left;
}

.clear-right {
  clear: right;
}

Logical Values

/* Logical values */
.float-start {
  float: inline-start;  /* left in LTR, right in RTL */
}

.clear-end {
  clear: inline-end;    /* right in LTR, left in RTL */
}

Logical Properties for Layout

Logical properties are particularly useful for layout components:

Navigation Bar Example

/* Logical navigation bar */
.navbar {
  display: flex;
  padding-block: 1rem;
  padding-inline: 2rem;
  background-color: #f8f9fa;
}

.navbar-brand {
  margin-inline-end: 2rem;
  font-weight: bold;
}

.navbar-nav {
  display: flex;
  gap: 1rem;
}

/* Works in both LTR and RTL without changes */

Card Component Example

/* Logical card component */
.card {
  border-radius: 8px;
  border: 1px solid #dee2e6;
  overflow: hidden;
}

.card-header {
  padding-block: 1rem;
  padding-inline: 1.5rem;
  border-block-end: 1px solid #dee2e6;
  background-color: #f8f9fa;
}

.card-body {
  padding-block: 1.5rem;
  padding-inline: 1.5rem;
}

.card-footer {
  padding-block: 1rem;
  padding-inline: 1.5rem;
  border-block-start: 1px solid #dee2e6;
  background-color: #f8f9fa;
}

Real-World Use Case: Multilingual Form

Here's a practical example of a form that works in both LTR and RTL languages:

/* Multilingual form using logical properties */
.form-group {
  margin-block-end: 1.5rem;
}

.form-label {
  display: block;
  margin-block-end: 0.5rem;
  font-weight: 500;
}

.form-control {
  display: block;
  width: 100%;
  padding-block: 0.5rem;
  padding-inline: 0.75rem;
  border: 1px solid #ced4da;
  border-radius: 0.25rem;
}

.form-text {
  display: block;
  margin-block-start: 0.25rem;
  font-size: 0.875rem;
  color: #6c757d;
}

.form-check {
  display: flex;
  align-items: center;
}

.form-check-input {
  margin-inline-end: 0.5rem;
}

.btn-submit {
  padding-block: 0.5rem;
  padding-inline: 1rem;
  background-color: #0d6efd;
  color: white;
  border: none;
  border-radius: 0.25rem;
  cursor: pointer;
}

LTR Form Preview

We'll never share your email.

RTL Form Preview

لن نشارك بريدك الإلكتروني أبدًا.
Key Takeaway: Notice how the same CSS code works perfectly in both LTR and RTL contexts. The checkbox remains on the correct side, padding and margins adapt automatically, and text alignment follows the appropriate direction—all without writing any direction-specific CSS rules.

Text Alignment and Direction

Internationalization Insight: Using logical text alignment properties is crucial for creating truly internationalized interfaces that respect the natural reading direction of different languages.

Text Alignment

CSS provides logical values for text alignment that automatically adapt to the text direction:

Physical Alignment

/* Physical alignment */
.align-left {
  text-align: left;
}

.align-right {
  text-align: right;
}

.align-center {
  text-align: center;
}

.align-justify {
  text-align: justify;
}

Logical Alignment

/* Logical alignment */
.align-start {
  text-align: start;  /* left in LTR, right in RTL */
}

.align-end {
  text-align: end;    /* right in LTR, left in RTL */
}

/* These remain the same */
.align-center {
  text-align: center;
}

.align-justify {
  text-align: justify;
}

LTR Example

This text is aligned to the start (left in LTR).

This text is aligned to the end (right in LTR).

This text is centered.

This is justified text. It will stretch to fill the width of the container, creating even left and right edges. This is commonly used for long paragraphs of text in print media and some websites.

RTL Example

هذا النص محاذى إلى البداية (اليمين في RTL).

هذا النص محاذى إلى النهاية (اليسار في RTL).

هذا النص في الوسط.

هذا نص مبرر. سيمتد لملء عرض الحاوية ، مما يؤدي إلى حواف يمنى ويسرى متساوية. يستخدم هذا بشكل شائع للفقرات الطويلة من النص في وسائل الإعلام المطبوعة وبعض مواقع الويب.

Direction and Writing Mode

CSS provides properties to control text direction and writing mode:

Direction Property

/* Set text direction */
.rtl-text {
  direction: rtl;  /* Right to left */
}

.ltr-text {
  direction: ltr;  /* Left to right (default) */
}

/* Often used with unicode-bidi */
.rtl-text-bidi {
  direction: rtl;
  unicode-bidi: bidi-override;
}

Writing Mode Property

/* Set writing mode */
.horizontal-tb {
  writing-mode: horizontal-tb;  /* Default: horizontal, top to bottom */
}

.vertical-rl {
  writing-mode: vertical-rl;    /* Vertical, right to left */
}

.vertical-lr {
  writing-mode: vertical-lr;    /* Vertical, left to right */
}

/* With text orientation */
.vertical-upright {
  writing-mode: vertical-rl;
  text-orientation: upright;  /* Characters upright */
}

Writing Mode Examples

horizontal-tb (Default)

This is the default writing mode used in most languages. Text flows horizontally from left to right (or right to left in RTL languages) and blocks stack from top to bottom.

vertical-rl

This writing mode is used in traditional East Asian typography. Text flows vertically from top to bottom, and blocks stack from right to left. Common in traditional Chinese, Japanese, and Korean texts.

vertical-lr

Similar to vertical-rl, but blocks stack from left to right. This is less common in traditional typography but can be used for creative layouts or for languages like Mongolian.

Text Orientation in Vertical Writing Modes

When using vertical writing modes, you can control how characters are oriented:

text-orientation: mixed

Mixed (default): Characters from horizontal-only scripts are rotated sideways. 漢字 remain upright.

{
  writing-mode: vertical-rl;
  text-orientation: mixed;
}

text-orientation: upright

Upright: All characters are displayed upright, including those from horizontal-only scripts.

{
  writing-mode: vertical-rl;
  text-orientation: upright;
}

text-orientation: sideways

Sideways: All characters are rotated sideways, including those from vertical scripts like 漢字.

{
  writing-mode: vertical-rl;
  text-orientation: sideways;
}

Real-World Use Case: Multilingual Navigation

Here's how logical properties can be used to create a navigation menu that works in both LTR and RTL contexts:

/* Multilingual navigation with logical properties */
.nav {
  display: flex;
  padding-block: 1rem;
  padding-inline: 1.5rem;
  background-color: #f8f9fa;
  border-block-end: 1px solid #dee2e6;
}

.nav-brand {
  font-weight: bold;
  margin-inline-end: 2rem;
}

.nav-items {
  display: flex;
  gap: 1.5rem;
}

.nav-item {
  position: relative;
}

/* Dropdown menu */
.dropdown-menu {
  position: absolute;
  top: 100%;
  inset-inline-start: 0; /* Logical version of left/right */
  min-width: 10rem;
  padding-block: 0.5rem;
  padding-inline: 0;
  margin-block-start: 0.125rem;
  background-color: white;
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 0.25rem;
}

.dropdown-item {
  display: block;
  padding-block: 0.25rem;
  padding-inline: 1rem;
  text-align: start;
}

LTR Navigation Preview

Brand
Home
Products
About
Contact

RTL Navigation Preview

العلامة التجارية
الرئيسية
المنتجات
من نحن
اتصل بنا
Key Insight: When you change the writing mode, the meaning of inline and block also changes. In vertical writing modes, inline runs vertically and block runs horizontally. This is why logical properties are so powerful—they automatically adapt to the writing mode context.

Combining Direction and Logical Properties

The real power comes when combining the dir attribute or direction property with logical CSS properties:

/* HTML */
<div class="container">
  <div class="card" dir="ltr">...</div>
  <div class="card" dir="rtl">...</div>
</div>

/* CSS - Same styles work for both directions */
.card {
  padding-block: 1rem;
  padding-inline: 1.5rem;
  border-start-start-radius: 0.5rem;
  border-start-end-radius: 0.5rem;
  border-end-start-radius: 0.5rem;
  border-end-end-radius: 0.5rem;
  box-shadow: 0.25rem 0 0.5rem rgba(0, 0, 0, 0.1);
}

Interactive Logical Properties Demo

This interactive demo allows you to experiment with CSS logical properties in different writing modes and directions. Toggle between settings to see how the same CSS adapts to different contexts.

Box Model Demo

This box demonstrates how logical properties affect the box model (margin, padding, border).

This element uses logical properties for its box model. Change the text direction and writing mode to see how it adapts.
Current Properties:
padding-block: 1rem padding-inline: 1.5rem margin-block: 1rem margin-inline: 1.5rem border-block: 2px solid border-inline: 4px solid border-start-start-radius: 12px border-end-end-radius: 12px
Text Alignment

This text is aligned to the start.

This text is aligned to the end.

This text is always aligned left.

This text is always aligned right.

Floating Elements
float: inline-start
float: inline-end

This paragraph demonstrates how elements float using logical properties. The blue boxes use float: inline-start and float: inline-end, which adapt to the text direction.

Try it: Change the text direction and writing mode to see how logical properties automatically adapt to different writing systems, while physical properties remain fixed to their physical directions.

Practical Examples

Bidirectional Navigation Menu

LTR Navigation (English)


/* HTML */
<nav class="main-nav">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>

/* CSS with logical properties */
.main-nav ul {
  display: flex;
  list-style: none;
  padding-inline-start: 0;  /* Removes default padding */
  margin-block: 0;          /* Removes top and bottom margins */
}

.main-nav li:not(:last-child) {
  margin-inline-end: 20px;  /* Space between items */
}

.main-nav a {
  padding-block: 10px;
  padding-inline: 15px;
  border-inline-start: 3px solid transparent;
}

.main-nav a:hover {
  border-inline-start-color: blue;
}

/* This menu will work correctly in both LTR and RTL contexts */
Key Benefit: Using logical properties for this navigation menu means you only need to write the CSS once. When the page direction changes (using dir="rtl" on the HTML element), all spacing, borders, and alignment automatically adjust to match the reading direction.

Card Component with Icon

LTR Card (English)

Feature Title

This is a description of the amazing feature that our product offers.

RTL Card (Arabic)

عنوان الميزة

هذا وصف للميزة الرائعة التي يقدمها منتجنا.


/* HTML */
<div class="card">
  <div class="card-icon">
    <i class="icon"></i>
  </div>
  <div class="card-content">
    <h3>Card Title</h3>
    <p>Card description text goes here.</p>
  </div>
</div>

/* CSS with logical properties */
.card {
  display: flex;
  padding: 15px;
  border-radius: 8px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.card-icon {
  margin-inline-end: 15px;  /* Space between icon and content */
}

.card-content {
  padding-inline-start: 10px;
  border-inline-start: 2px solid #eee;
}

/* In LTR: Icon on left, content on right */
/* In RTL: Icon on right, content on left */
                        

Form Layout


/* HTML */
<form class="contact-form">
  <div class="form-group">
    <label for="name">Name:</label>
    <input type="text" id="name">
  </div>
  <div class="form-group">
    <label for="email">Email:</label>
    <input type="email" id="email">
  </div>
  <div class="form-actions">
    <button type="submit">Submit</button>
    <button type="reset">Reset</button>
  </div>
</form>

/* CSS */
.form-group {
  margin-block-end: 15px;
  display: flex;
  flex-wrap: wrap;
}

.form-group label {
  flex: 0 0 100px;
  text-align: end;
  padding-inline-end: 10px;
}

.form-group input {
  flex: 1;
  min-inline-size: 200px;
}

.form-actions {
  margin-inline-start: 100px;  /* Align with inputs */
  padding-block-start: 10px;
}

.form-actions button:first-child {
  margin-inline-end: 10px;
}
                        

Logical Properties in Grid and Flexbox

Grid Layout with Logical Properties


.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);  /* Still using columns */
  gap: 20px;
}

/* Using logical properties for item placement */
.header {
  grid-column: 1 / -1;  /* Spans all columns */
  padding-block: 20px;
  border-block-end: 1px solid #ddd;
}

.sidebar {
  grid-row: 2 / 4;
  padding-inline: 15px;
  border-inline-end: 1px solid #ddd;
}

.content {
  grid-column: 2 / -1;
  padding: 20px;
}

.footer {
  grid-column: 1 / -1;
  padding-block: 20px;
  border-block-start: 1px solid #ddd;
}
                        

Flexbox with Logical Properties


.flex-container {
  display: flex;
  flex-direction: row;  /* Default */
  justify-content: space-between;
  padding-block: 20px;
  padding-inline: 15px;
}

.flex-item {
  margin-inline-end: 10px;
  padding-inline: 15px;
  border-inline-start: 2px solid #ddd;
}

.flex-item:last-child {
  margin-inline-end: 0;
}

/* For RTL support, no changes needed to the flex layout */
/* Just add dir="rtl" to the HTML element or set direction: rtl; in CSS */
                        

Browser Support and Fallbacks

Current Browser Support

Logical properties have good support in modern browsers, but you may need fallbacks for older browsers:

  • Chrome: Full support since version 89
  • Firefox: Full support since version 66
  • Safari: Full support since version 15
  • Edge: Full support since version 89

Providing Fallbacks


/* Method 1: Cascade - Physical properties first, then logical */
.element {
  /* Fallback for older browsers */
  margin-left: 20px;
  margin-right: 20px;
  
  /* Modern browsers will use these */
  margin-inline-start: 20px;
  margin-inline-end: 20px;
}

/* Method 2: Feature detection with @supports */
.element {
  /* Fallback for all browsers */
  margin-left: 20px;
  margin-right: 20px;
}

@supports (margin-inline-start: 20px) {
  .element {
    margin-left: 0;  /* Reset physical property */
    margin-right: 0;
    margin-inline-start: 20px;
    margin-inline-end: 20px;
  }
}
                        

Using PostCSS for Automatic Fallbacks

The postcss-logical plugin can automatically generate physical fallbacks for logical properties:


/* Your CSS with logical properties */
.element {
  margin-inline: 20px;
  padding-block: 10px;
  border-inline-start: 1px solid black;
}

/* After PostCSS processing */
.element {
  margin-left: 20px;
  margin-right: 20px;
  padding-top: 10px;
  padding-bottom: 10px;
  border-left: 1px solid black;
  
  margin-inline: 20px;
  padding-block: 10px;
  border-inline-start: 1px solid black;
}

/* In RTL contexts, the physical fallbacks may be incorrect, 
   but the logical properties will work correctly */
                        

Best Practices

When to Use Logical Properties

  • Multilingual websites that support both LTR and RTL languages
  • International applications where content direction may change
  • Components that need to adapt to different writing modes
  • Design systems that aim for maximum flexibility and reusability

Migration Strategy

  1. Start with new components: Apply logical properties to new code first
  2. Identify direction-sensitive components: Focus on components that need to work in multiple writing directions
  3. Use automated tools: Consider using PostCSS or similar tools to help with the transition
  4. Test thoroughly: Verify layouts in both LTR and RTL contexts

Common Pitfalls

  • Mixing logical and physical properties: Be consistent to avoid confusion
  • Forgetting about images and icons: These may need to be flipped or adjusted for RTL
  • Assuming all languages read top-to-bottom: Some languages use vertical writing modes
  • Hardcoding values in JavaScript: Ensure JS also respects the document direction
Pro Tip: When building internationalized interfaces, test early and often with real content in different languages. What works well for Latin scripts might not work as well for Arabic, Hebrew, or Asian languages.

Resources and Further Reading

Documentation

Tools

Articles and Tutorials

Final Thought: Logical properties represent a significant improvement in how we handle layout in CSS. As global audiences become increasingly important, building layouts that work seamlessly across different writing systems is no longer optional but essential.