Logical Properties: Building Layouts That Adapt to Language Direction

Building websites that support both left-to-right (LTR) and right-to-left (RTL) languages typically means maintaining separate stylesheets or meticulously flipping every property value. CSS logical properties and values—a W3C working draft now shipped in many browsers—offer a more sustainable approach by letting layout properties respond to the document's writing direction automatically.

Understanding Direction in HTML

The foundation of multi-directional layout is the dir attribute on the <html> element, which accepts ltr (the default) or rtl. The browser uses this value to determine text rendering, punctuation placement, and even table cell ordering. Modern CSS specifications like Grid and Flexbox follow the same pattern, so elements reflow without requiring markup changes.

HTML5 also introduced an auto value for dir, which detects the direction of the first character in the element's content. While the W3C recommends server-side detection for production sites, auto is useful for user-generated content like comment threads where participants may write in different languages. It's widely supported except in Internet Explorer and Edge.

The :dir() Pseudo-Class

The :dir() selector targets elements based on their computed direction, whether set explicitly or via auto:

<style>
  p:dir(ltr) {
    background: green;
  }
  p:dir(rtl) {
    background: red;
  }
</style>


<!-- The following paragraph will have a green background -->
<p dir="auto">This is a paragraph that starts with a latin character</p>
<!-- The following paragraph will have a red background -->
<p dir="auto">هذا النص يستخدم حروف عربية</p>

Despite its utility, browser support for :dir() is currently limited to Firefox. Even with broader support, the manual approach—flipping margins, paddings, floats, and positions for each direction—remains tedious.

Logical Values: Replacing Left and Right

Consider aligning text opposite to the natural language direction. For an English (LTR) paragraph, you might write:

.opposite {
  text-align: right;
}

For the RTL version, you'd need a separate override:

html[dir="rtl"] .opposite {
  text-align : left;
}

Logical values eliminate this duplication. Instead of left and right, use start and end, which evaluate based on the element's direction:

.opposite {
  text-align: end;
}

In an LTR context, start maps to left; in RTL, it maps to right. The same CSS works for both directions.

Logical Properties: Margins, Padding, and More

Logical properties extend this concept to full CSS properties. Instead of writing margin-left for one direction and margin-right for the other:

html[dir="rtl"] article img {
  margin-left: 0;
  margin-right: 15px;
}

You can use a single property that adapts automatically:

article img {
  margin-inline-start: 15px;
}

The suffix -inline-start refers to the beginning of the horizontal axis—left for LTR, right for RTL.

Understanding Block and Inline Axes

The terms block and inline come from CSS writing modes, which accommodate vertical scripts like those used in Chinese, Japanese, and Korean. In standard horizontal writing, the block axis is vertical (block-start = top, block-end = bottom), and the inline axis is horizontal (inline-start = left, inline-end = right). When a layout is rotated using writing modes, these axes rotate with it, keeping logical terminology consistent:

This axis system also enables shorthand properties. For instance, margin-inline applies to both left and right margins in horizontal writing, while margin-block targets top and bottom. Padding follows the same pattern:

PropertyLogical Property
margin-topmargin-block-start
margin-leftmargin-inline-start
margin-rightmargin-inline-end
margin-bottommargin-block-end
PropertyLogical Property
padding-toppadding-block-start
padding-leftpadding-inline-start
padding-rightpadding-inline-end
padding-bottompadding-block-end

Positioning with Logical Properties

Positioning properties get entirely new names. Physical properties like top, right, bottom, and left are replaced:

.element {
  position: absolute;
  inset-block-start: 0;  /* evaluates to top */
  inset-block-end: 0;    /* evaluates to bottom */
  inset-inline-start: 0; /* evaluates to left in ltr and right in rtl */
  inset-inline-end: 0;   /* evaluates to right in ltr and left in rtl */
}

The new inset shorthand consolidates these, and it too supports block and inline variations:

/* Shorthand FTW! */
.element {
  position: absolute;
  inset: logical 10px 20px 30px 40px;
}


/* It evaluates to this */
.element {
  position: absolute;
  inset-block-start: 10px;
  inset-inline-start: 20px;
  inset-block-end: 30px;
  inset-inline-end: 40px;
}
PropertyLogical Property
topinset-block-start
leftinset-inline-start
rightinset-inline-end
bottominset-block-end

Logical Borders

Border properties also accept logical suffixes such as -inline-start and -block-start:

PropertyLogical Property
border-top{-size|style|color}border-block-start{-size|style|color}
border-left{-size|style|color}border-inline-start{-size|style|color}
border-right{-size|style|color}border-inline-end{-size|style|color}
border-bottom{-size|style|color}border-block-end{-size|style|color}

Using Logical Properties Today

While full browser support is still maturing, a PostCSS plugin by Jonathan Neal translates logical syntax into CSS that current browsers understand. It works in three stages:

  • Converts new property syntax to existing standards, using the :dir() pseudo-class to generate separate output for LTR and RTL.
  • Translates :dir() selectors into attribute selectors:
 .element:dir(ltr) {
   ...
 }
 [dir="ltr"] .element {
   ...
 }
  • Flattens nested selectors via postcss-nested.

PostCSS integrates with Grunt, Gulp, and webpack, fitting into virtually any existing workflow.

The shift to logical properties does require learning new names and testing both directions, but it eliminates the dual-stylesheet burden of multi-directional development. You write the layout once, and it correctly adapts to any language direction without special handling.