The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Use horizontal lines.copy { writing-mode: horizontal-tb; }View examples
Set vertical right-to-left flow.vertical-copy { writing-mode: vertical-rl; }View examples
Set vertical left-to-right flow.vertical-copy { writing-mode: vertical-lr; }View examples
Declare RTL content<html lang="ar" dir="rtl">View examples
Detect unknown text direction<bdi dir="auto">اسم المستخدم</bdi>View examples
Set direction outside HTML.xml-rtl { direction: rtl; }View examples
Set vertical-flow margins.section { margin-block: 2rem 1rem; }View examples
Center along the inline axis.panel { margin-inline: auto; }View examples
Pad inline edges.button { padding-inline: 1rem; }View examples
Mark the leading edge.note { border-inline-start: 0.25rem solid #2563eb; }View examples
Set inline size.avatar { inline-size: 3rem; }View examples
Limit readable measure.prose { max-inline-size: 65ch; }View examples
Set minimum block size.empty-state { min-block-size: 12rem; }View examples
Position from logical edges.badge { inset-block-start: 0.5rem; inset-inline-end: 0.5rem; }View examples
Align text to line start.label { text-align: start; }View examples
Float with reading direction.thumbnail { float: inline-start; }View examples
Round the starting corner.card { border-start-start-radius: 1rem; }View examples
Keep vertical glyphs upright.vertical-copy { text-orientation: upright; }View examples
Combine short vertical text.digits { text-combine-upright: all; }View examples
Feature-query a migration@supports (margin-inline-start: 1rem) { .item { margin-inline-start: 1rem; }; }View examples

Logical CSS describes geometry in terms of the inline and block flows instead of assuming left-to-right, horizontal text. That lets the same component adapt to localization, right-to-left direction, and vertical typography. Put language and direction in HTML, use writing-mode only when the design genuinely calls for another block flow, and test real content rather than treating RTL as a mirrored screenshot.

Step by step

Detailed examples

01

Reason in inline and block axes

The inline axis follows text within a line; the block axis follows the progression of line boxes and block-level content. In horizontal-tb, inline is horizontal and block progression is downward. vertical-rl and vertical-lr make the inline axis vertical, then stack lines toward the right or left respectively. Direction still controls inline start versus inline end. writing-mode inherits, so scope it deliberately and test embedded controls, tables, media, and inline SVG rather than applying it as a cosmetic rotation.

Horizontal and vertical editorial regions
.article {
  writing-mode: horizontal-tb;
}

.japanese-sidebar {
  writing-mode: vertical-rl;
}

.mongolian-sidebar {
  writing-mode: vertical-lr;
}
Back to quick reference ↑
02

Put text direction in markup

For HTML, use dir=ltr or dir=rtl on the nearest element whose content has that base direction; use dir=auto for text whose first strong character is not known in advance. This survives missing styles and participates in the Unicode bidirectional algorithm and form-control behavior. bdi isolates an unknown inline value so it cannot reorder surrounding punctuation. CSS direction is primarily for document languages without equivalent markup; do not use it merely to move an icon or reverse a layout.

A right-to-left document with isolated user data
<html lang="ar" dir="rtl">
  <body>
    <p>مرحبًا <bdi dir="auto">Alex_42</bdi></p>
  </body>
</html>
Direction rule for a custom XML vocabulary
chapter[dir="rtl"] {
  direction: rtl;
  unicode-bidi: isolate;
}

Note: HTML documents should use the native dir attribute instead of author CSS for content direction.

Back to quick reference ↑
03

Express the box model relative to content flow

block-start, block-end, inline-start, and inline-end map to physical sides using the element's computed writing mode and direction. Axis shorthands such as margin-block and padding-inline set their start and end longhands in that order. Logical borders are especially useful for callouts and selected states whose leading edge should move with reading direction. Use physical properties only when the physical side itself matters, such as a safe-area inset tied to a device edge.

One callout for LTR, RTL, and vertical flow
.callout {
  margin-block: 1.5rem;
  margin-inline: 0;
  padding-block: 0.75rem;
  padding-inline: 1rem;
  border-inline-start: 0.25rem solid #2563eb;
}
Back to quick reference ↑
04

Size components by the axis they occupy

inline-size and block-size are flow-relative counterparts to width and height. Their min- and max- variants make intent clearer: max-inline-size constrains readable line measure, while min-block-size reserves room in the direction blocks accumulate. Percentages and intrinsic sizing still follow the rules of the underlying sizing module, so logical names do not make a fixed size responsive by themselves. Prefer max constraints and intrinsic content where localization can expand labels.

A resilient card and fixed-size avatar
.card {
  inline-size: min(100%, 38rem);
  min-block-size: 12rem;
  padding: 1rem;
}

.avatar {
  inline-size: 3rem;
  block-size: 3rem;
  object-fit: cover;
}
Readable measure in any writing mode
.prose {
  max-inline-size: 65ch;
  margin-inline: auto;
}
Back to quick reference ↑
05

Anchor and align interfaces without left/right assumptions

Logical inset properties position an absolutely, fixed, sticky, or relatively positioned box from flow-relative edges. text-align:start follows the line's base direction, and float:inline-start uses the inline start side of the containing block. These tools are not automatic mirroring: imagery, charts, media controls, clocks, and recognizable symbols may need to retain their physical orientation. Test interaction targets and focus order independently of their visual placement.

Direction-aware notification card
.notice {
  position: relative;
  padding: 1.5rem;
  text-align: start;
}

.notice__badge {
  position: absolute;
  inset-block-start: 0.5rem;
  inset-inline-end: 0.5rem;
}

.notice__thumbnail {
  float: inline-start;
  margin-inline-end: 1rem;
}
Back to quick reference ↑
06

Name corners by the two edges that meet

Logical corner properties combine a block side and an inline side: start-start, start-end, end-start, and end-end. For example, border-start-start-radius is the corner where block-start meets inline-start, so it maps to a different physical corner in RTL or vertical text. This is useful for speech bubbles, attached panels, and asymmetric cards. Use border-radius when every physical corner deliberately receives the same treatment.

Flow-relative asymmetric card
.card {
  border-start-start-radius: 1.25rem;
  border-start-end-radius: 0.25rem;
  border-end-start-radius: 0.25rem;
  border-end-end-radius: 1.25rem;
}
Back to quick reference ↑
07

Control glyph orientation only inside vertical writing

text-orientation affects vertical typographic modes. Its initial mixed value keeps characters with a natural vertical orientation upright and rotates others sideways; upright forces all characters upright and also makes the used direction ltr. text-combine-upright compresses a short inline sequence—commonly two digits—into the space of one upright character. Apply these features according to the typographic conventions of the content language, not as decorative rotation.

Vertical Japanese date with combined digits
<p class="date" lang="ja">令和<span class="digits">08</span>年</p>
<style>
  .date {
    writing-mode: vertical-rl;
    text-orientation: mixed;
  }
  .digits { text-combine-upright: all; }
</style>
Back to quick reference ↑
08

Do not casually mix logical and physical declarations

A logical longhand and the physical longhand it maps to share a computed value, so cascade priority and declaration order decide which one wins. The mapping changes with writing mode and direction, which can leave an intended physical fallback active on a different side. For modern targets, use logical properties consistently. If legacy support requires physical fallbacks, isolate the migration with @supports and reset any physical side that would otherwise remain set; then test both LTR and RTL rather than relying on declaration order alone.

Explicit fallback migration
.item {
  margin-left: 1rem;
}

@supports (margin-inline-start: 1rem) {
  .item {
    margin-left: 0;
    margin-inline-start: 1rem;
  }
}
Preferred modern rule
.item {
  margin-inline-start: 1rem;
  padding-inline: 1rem;
  text-align: start;
}
Back to quick reference ↑

Local code tester

Test one card across writing directions

Compare the same logical spacing, border, sizing, corner, positioning, and alignment rules in LTR, RTL, and vertical flows.

Runs in your browser
Preview

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. World Wide Web ConsortiumCSS Logical Properties and Values Module Level 1w3.org
  2. World Wide Web ConsortiumCSS Writing Modes Level 4w3.org
  3. World Wide Web ConsortiumCSS Text Module Level 3w3.org
  4. World Wide Web ConsortiumCSS Values and Units Module Level 4w3.org
  5. WHATWGHTML Standard: The dir attributehtml.spec.whatwg.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback