What is Logical properties?

Logical properties: Logical properties are CSS properties defined relative to writing direction, like margin-inline-start rather than margin-left, so layouts mirror in RTL.

Physical CSS properties name a side of the screen: margin-left, padding-right, border-top, left: 0. Logical properties name a side of the text flow instead: margin-inline-start, padding-inline-end, border-block-start, inset-inline-start: 0. In a left-to-right language the two sets mean the same thing. In Arabic, Hebrew, Persian or Urdu, where dir="rtl" flips the inline direction, the logical versions flip with it, so a sidebar's margin, a chevron's offset and a chip's padding all end up on the correct side without a second stylesheet.

The vocabulary

  • Inline is the direction text runs in a line; block is the direction lines stack. In English, inline is horizontal and block is vertical. In vertical writing modes, as in traditional Japanese, they swap.
  • Start and end replace left and right, and top and bottom: margin-inline-start, padding-block-end.
  • Sizes: inline-size and block-size replace width and height, with min- and max- variants.
  • Shorthands: margin-inline: 1rem 2rem sets start and end at once; inset-inline and inset-block replace the left and right and top and bottom pairs.
  • Corners: border-start-start-radius is the corner where the block start meets the inline start, the top left corner in English.
  • Values too: text-align: start, float: inline-start, clear: inline-end.

In Tailwind CSS v4

Tailwind has logical utilities beside the physical ones: ms-4 and me-4 for inline margins, ps- and pe- for padding, start-0 and end-0 for insets, rounded-s-lg and rounded-e-lg for corners, border-s and border-e, and text-start and text-end. The rtl: and ltr: variants exist for the few cases that cannot be expressed logically.

tsx
import { ChevronRightIcon } from "lucide-react"

export function NavRow() {
  return (
    <li className="flex items-center gap-2 border-s-2 border-accent ps-3 pe-2">
      <span className="me-auto">Invoices</span>
      <ChevronRightIcon className="size-4 rtl:-scale-x-100" />
    </li>
  )
}

What stays physical

  • Icons with a direction. A "next" chevron must point the other way in RTL; mirror it with rtl:-scale-x-100. Icons that depict a physical thing, such as a clock or a check, do not mirror.
  • Light and shadow. A drop shadow falls where the light says, not where the text flows. MiniDev's shadows come from the LightProvider, which is physical by design.
  • Charts. Time axes usually keep running left to right even in RTL interfaces; follow the convention of the data, not the text.
  • Keyboard arrows. Left Arrow should still move left visually, so primitives need to know the direction to map keys. MiniDev's Slider and RangeSlider need Base UI's DirectionProvider under dir="rtl", or dragging and arrow keys run backwards.

Set dir on the html element, or on the container that changes language, and use logical properties by default. The cost is nothing in LTR, and the first RTL customer becomes a translation job instead of a layout rewrite. LanguagePicker is where a product usually switches direction, and the layout primitives Inset, Stack and Cluster use symmetric spacing that reads the same either way. The tailwind-css-v4 entry lists the rest of the utility names.

SlideruiSlider on Base UI with a hairline rail, a keycap thumb, a value bubble while dragging, optional labelled marks, Intl number formatting and vertical support.npx shadcn@latest add @minidev/sliderLanguage PickeruiA grid of language options exposed as an accessible listbox, with the selected language outlined in the accent color. Plug it into locale or profile settings.npx shadcn@latest add @minidev/language-picker