Codeskill

Learn to code, step by step

Logical properties and writing-mode UI

Logical properties and writing-mode aware UI. Physical properties like margin-left and width assume horizontal left-to-right text. Logical properties describe start, end, block, and inline edges so the same CSS works when direction or writing mode changes.

Block and inline axes

In horizontal writing (English, most European languages):

  • Inline – left to right (the direction text flows)
  • Block – top to bottom (lines stack vertically)

In vertical writing modes, those axes swap relative to the screen. Logical properties follow the text, not the monitor.

Common logical replacements

/* Physical to Logical */
/* margin-top/bottom     to margin-block */
/* margin-left/right     to margin-inline */
/* padding-top/bottom    to padding-block */
/* padding-left/right    to padding-inline */
/* width                 to inline-size */
/* height                to block-size */
/* top/bottom            to inset-block */
/* left/right            to inset-inline */
/* border-left           to border-inline-start */
/* text-align: left      to text-align: start */

Shorthands exist: margin-block: 1rem 2rem is start then end; margin-inline: auto centres horizontally in LTR.

Example: a component in logical properties

.callout {
  padding-block: 1rem;
  padding-inline: 1.25rem;
  border-inline-start: 4px solid var(--color-accent);
  margin-block-end: 1.5rem;
  max-inline-size: 40rem;
}

.callout__title {
  margin-block: 0 0.5rem;
  text-align: start;
}

The accent border sits on the ‘start’ side – left in LTR, right in RTL. No separate RTL stylesheet for this pattern.

direction and dir

Right-to-left languages use dir="rtl" on html or a section, or direction: rtl in CSS:

<html lang="ar" dir="rtl">
  …
</html>

Prefer the HTML dir attribute when content direction is document-wide; CSS direction for local overrides. Logical properties then mirror automatically.

writing-mode

Vertical layouts – sidebar labels, Japanese-style headings, decorative type – use writing-mode:

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

.sidebar-nav {
  writing-mode: vertical-lr;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

vertical-rl flows top to bottom, lines progress right to left. vertical-lr flows top to bottom, lines progress left to right. Flex and Grid follow the writing mode: ‘row’ and ‘column’ flip meaning relative to the block and inline axes.

Logical borders and radii

.tab {
  border-block-end: 2px solid transparent;
  border-end-end-radius: 0.25rem;
}

.tab[aria-selected="true"] {
  border-block-end-color: var(--color-accent);
}

Corner radii use start-start, start-end, end-start, end-end instead of top-left and friends. Easier to get wrong on first use – check in DevTools with direction toggled.

Flexbox and Grid with logical values

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding-inline: 1.5rem;
  padding-block: 0.75rem;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem;
}

justify-content and align-items already respect writing mode in modern browsers. Physical padding on the same component does not – that is the migration target.

Migration strategy

You do not rewrite an entire codebase overnight. Use logical properties in new components and when you touch existing rules. Symmetric vertical spacing (margin-block) and horizontal padding (padding-inline) are the highest-value swaps for LTR-only sites because they read clearly and future-proof RTL.

Keep physical properties where a design truly means ‘always the left edge’ – rare, but a full-bleed image anchored to the viewport left might be intentional.

The next tutorial covers scroll-driven effects and sticky patterns – headers that stay put, scroll snapping, and not breaking UX in the process.

PreviousFlexbox gotchas and debugging