enforce-logical
Enforce logical (RTL-friendly) Tailwind CSS properties instead of physical ones
What this rule does
Rewrites physical-direction Tailwind utilities (ml-4, pr-2, left-0, rounded-tl-md, …) into their logical, writing-direction aware equivalents (ms-4, pe-2, start-0, rounded-ss-md, …). Logical utilities resolve to margin-inline-start / padding-inline-end / … in CSS, which means they flip automatically in RTL contexts without any extra code. Required if your app ships in Arabic, Hebrew, Farsi, or any other RTL language. Autofix on the first offender per location, editor suggestion on subsequent ones.
DS-independent — works without settings.tailwindcss.entryPoint. The mapping table is static and lives in the rule's source; no design system lookup needed.
enforce-logical and enforce-physical are sibling rules — they share a mapping table that one inverts. Enable only one at a time.
Options
direction
'inline' | 'block' | 'both', default 'both'.
Restricts conversion to one axis. Today every mapping in the table is inline-axis (left/right become start/end), so 'block' effectively disables the rule and 'inline' / 'both' behave identically. The option is in place for when Tailwind ships block-axis logical utilities.
{ "tailwindcss/enforce-logical": ["error", { "direction": "inline" }] }allowlist
string[], default [].
Regex patterns (compiled lazily, invalid ones silently skipped). Classes whose full string matches any pattern bypass the rewrite. Use this for one-off cases where you genuinely want a physical direction — e.g. an icon that should always sit on the visual left regardless of writing direction.
{ "tailwindcss/enforce-logical": ["error", { "allowlist": ["^ml-icon$", "^rounded-tl-special$"] }] }Examples
✗ Incorrect
// Physical margins/padding
<div className="ml-4 pr-2" />
// ~~~~ ~~~~ → ms-4 pe-2
// Positioning
<div className="left-0 right-0" />
// ~~~~~~ ~~~~~~~ → start-0 end-0
// Borders and radii
<div className="border-l rounded-tl-md" />
// ~~~~~~~~ ~~~~~~~~~~~~~ → border-s rounded-ss-md✓ Correct
// Logical equivalents
<div className="ms-4 pe-2" />
<div className="start-0 end-0" />
<div className="border-s rounded-ss-md" />
// Already logical — variants and important round-trip cleanly
<div className="hover:ms-4 ps-(--gutter) me-4!" />Interactions with other rules
enforce-physical: the inverse. They share the mapping table; enabling both at the same time will autofix in a loop. Pick one based on whether your app supports RTL (useenforce-logical) or is LTR-only (useenforce-physical).enforce-canonical: orthogonal. Canonical normalizes utility shape; this rule swaps physical for logical along one axis.enforce-shorthand: runs on plainm-*/p-*shorthands, which are already direction-neutral, so the two don't overlap.
When to disable it
- LTR-only applications where you're sure RTL will never be needed. Use
enforce-physicalinstead if you want consistency in the other direction. - Pixel-perfect layouts where physical direction is part of the design (rare, but happens with icons or decoration). Reach for
allowlistbefore disabling globally.