Teaching AI Agents to Write RTL-Safe CSS

Web DevelopmentAIRTL

Teaching AI Agents to Write RTL-Safe CSS

The ESLint plugin catches mistakes after they're written. But what if the thing writing the code already knew the rules?

Most AI coding tools (Claude, Cursor, OpenCode, Copilot) default to physical direction classes because that's what 99% of tutorials show. ml-4. text-left. left-0. They work in English and break in Arabic.

The fix isn't better prompting at generation time. It's giving the agent a single, non-negotiable rule and the mapping to follow it.

Teaching AI Agents to Write RTL-Safe CSS

The One Rule

Always use CSS logical properties and RTL-safe Tailwind classes. Never use physical direction properties (left, right, margin-left, margin-right) unless the positioning is intentionally physical and should NOT mirror.

That's it. One rule. Everything else is a lookup table.

Tailwind Mapping

Never useAlways useWhy
ml-*ms-*margin-left → margin-inline-start
mr-*me-*margin-right → margin-inline-end
pl-*ps-*padding-left → padding-inline-start
pr-*pe-*padding-right → padding-inline-end
left-*start-*left positioning
right-*end-*right positioning
text-lefttext-starttext alignment
text-righttext-endtext alignment
border-l-*border-s-*border start
border-r-*border-e-*border end
rounded-l-*rounded-s-*border-radius start
rounded-r-*rounded-e-*border-radius end
<!-- Bad -->
<div class="ml-4 mr-2 pl-3 pr-1 text-left rounded-l-lg border-l-2">
  <!-- Good -->
  <div class="ms-4 me-2 ps-3 pe-1 text-start rounded-s-lg border-s-2"></div>
</div>

CSS & CSS-in-JS Mapping

PhysicalLogical
marginLeftmarginInlineStart
marginRightmarginInlineEnd
paddingLeftpaddingInlineStart
paddingRightpaddingInlineEnd
borderLeftborderInlineStart
borderRightborderInlineEnd
leftinsetInlineStart
rightinsetInlineEnd
textAlign: "left"textAlign: "start"
float: "left"float: "inline-start"

The dir Attribute

Always set dir and lang on <html>, not via CSS direction alone:

<html dir="rtl" lang="ar"></html>
<!-- OR -->
<html dir="ltr" lang="en"></html>

Use dir="auto" on user-generated content where language is unknown. For mixed-content elements, set dir on the element.

Flexbox & Grid Auto-Flip

Flexbox and CSS Grid automatically respect the writing mode. Items reorder when dir="rtl" is set. Never use flex-direction: row-reverse to "fix" RTL — it causes a double-flip.

The :dir() Pseudo-Class

Use :dir(rtl) for direction-based styling. It matches elements that inherit direction from ancestors (unlike [dir="rtl"]).

.element:dir(rtl) {
  /* RTL styles */
}
.element:dir(ltr) {
  /* LTR styles */
}

Bidirectional Isolation

  • <bdi> isolates user-generated content whose direction is unknown
  • <bdo dir="ltr"> forces LTR for phone numbers, credit cards, code
<p>Welcome back, <bdi>Ahmed</bdi>! Score: <bdi>۳۵۰</bdi></p>
<bdo dir="ltr">+1 (555) 123-4567</bdo>

When NOT to Flip

Never flip symmetrical icons (home, search, user, settings), media controls, data visualizations, images, code blocks, phone numbers, or math expressions. Force LTR when needed:

<span dir="ltr">+1 (555) 123-4567</span>
<code dir="ltr">console.log("hello");</code>

Bidirectional Icons

Flip these (they indicate direction): arrows, breadcrumb separators, send icon, undo/redo, sort indicators.

Don't flip these (universal/symmetrical): play/pause, search, menu, close, plus, checkmark, home, settings.

Arabic Typography Rules

  1. letter-spacing: 0 — spacing breaks connected letters
  2. Use solid colors — rgba() and opacity cause rendering artifacts
  3. Underlines overlap dots — use text-decoration-skip-ink: auto or box-shadow
  4. Line height 1.6-1.8 (vs Latin 1.4-1.5)
  5. Never word-break: break-all on Arabic
  6. No abbreviations — letters must stay connected
  7. Provide min-width on buttons — Arabic translations vary in length

Component Patterns

Icon position flips. Form inputs (email/URL stay LTR, name/address RTL). Breadcrumbs auto-flip. Tables, tabs, cards, toasts, blockquotes, and toggle switches all need direction-aware treatment.

Testing RTL

  1. Toggle dir="rtl" on <html> in DevTools
  2. Test every component in both directions
  3. Check text overflow, alignment, icon orientation, scrollbar position, truncation
  4. Test with actual Arabic content — not mirrored Lorem Ipsum

The Companion Tool

The eslint-plugin-tailwind-rtl catches physical classes in CI. Use both: the skill teaches agents to write correctly the first time; the plugin catches anything that slips through.

How to Use This With AI Agents

Install the skill directly:

npx skills add AmmarCodes/rtl-web-development-skill

It contains the complete reference tables, component patterns, and Arabic typography rules. One rule, one lookup, zero RTL bugs.

If the thing writing your code already knows logical properties, you never have a mess to clean up.


GitHub: https://github.com/AmmarCodes/eslint-plugin-tailwind-rtl