mcpField
A
arabic-rtl-best-practices

arabic-rtl-best-practices

github.com/almubarmijDesign & UI350 installsUpdated 18w ago
Repository

About arabic-rtl-best-practices

A design skill for building and reviewing Arabic interfaces, covering RTL document direction, CSS logical properties, bidirectional text, and typography. It helps adapt LTR pages for RTL and check common directional layout issues.

Key features

  1. 01Set HTML RTL document direction
  2. 02Use CSS logical properties
  3. 03Handle Arabic bidirectional text
  4. 04Apply Arabic font and typography guidance
  5. 05Check common RTL component pitfalls

Use cases

  1. 01Adapt an LTR page layout for RTL
  2. 02Fix number direction in Arabic text
  3. 03Check direction handling in navigation, tables, and icons

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/almubarmij/arabic-ai-skills --skill arabic-rtl-best-practices

After installing, type/arabic-rtl-best-practicesin Claude Code to confirm it loaded.

Bundled filesreferences/css-logical-properties.mdSKILL_AR.md

Details

From the project README

Arabic RTL Best Practices

Instructions

Step 1: Set Up Document Direction

Always start with the HTML attribute (not just CSS):

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

This tells browsers, screen readers, and CSS to use RTL as the base direction.

Step 2: Use CSS Logical Properties

NEVER use physical directional properties for layout:

Physical (avoid)Logical (use)
margin-leftmargin-inline-start
margin-rightmargin-inline-end
padding-leftpadding-inline-start
padding-rightpadding-inline-end
border-leftborder-inline-start
text-align: lefttext-align: start
text-align: righttext-align: end
float: leftfloat: inline-start
left: 10pxinset-inline-start: 10px

This ensures the layout automatically mirrors in RTL mode.

Step 3: Handle Bidirectional Text

When mixing Arabic and English/numbers:

/* Isolate embedded LTR content */
.ltr-content {
  unicode-bidi: isolate;
  direction: ltr;
}

/* For inline elements with mixed content */
.bidi-override {
  unicode-bidi: bidi-override;
}

Common bidi issues:

  • Phone numbers appearing reversed: Wrap in <bdo dir="ltr">
  • Punctuation at wrong end of sentence: Use unicode-bidi: isolate
  • URLs/emails in Arabic text: Wrap in <span dir="ltr">
Step 4: Arabic Typography

Recommended font stack:

font-family: 'Tajawal', 'Assistant', 'Rubik', 'Noto Sans Arabic', sans-serif;

Typography settings:

body[dir="rtl"] {
  font-size: 16px; /* Arabic needs slightly larger than Latin */
  line-height: 1.7;
  letter-spacing: normal; /* NEVER add letter-spacing for Arabic */
  word-spacing: 0.05em; /* Slight word spacing improves readability */
}
Step 5: Framework-Specific Setup

Tailwind CSS RTL (v3.3+ / v4):

Prefer logical property utilities over rtl:/ltr: variants:

Physical classLogical classCSS property
ml-4ms-4margin-inline-start
mr-4me-4margin-inline-end
pl-4ps-4padding-inline-start
pr-4pe-4padding-inline-end
left-4start-4inset-inline-start
right-4end-4inset-inline-end
rounded-l-lgrounded-s-lgborder-start-start-radius + border-end-start-radius
rounded-r-lgrounded-e-lgborder-start-end-radius + border-end-end-radius
<!-- Bad: requires two classes, breaks without dir attribute -->
<div class="ltr:ml-4 rtl:mr-4">...</div>

<!-- Good: single class, auto-mirrors based on dir -->
<div class="ms-4">...</div>

Reserve rtl: / ltr: variants only for cases logical properties cannot handle (e.g., directional icons, transforms).

Tailwind v4 note: v4 uses CSS-first configuration (@import "tailwindcss" in CSS) instead of tailwind.config.js. Logical utilities work identically in both v3 and v4.

Next.js App Router:

// app/layout.tsx
import { Tajawal } from 'next/font/google';

const tajawal = Tajawal({
  subsets: ['arabic', 'latin'],
  weight: ['400', '500', '700'],
});

export default async function RootLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: Promise<{ locale: string }>;
}) {
  const { locale } = await params;
  const isRTL = locale === 'he';

  return (
    <html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>
      <body className={tajawal.className}>{children}</body>
    </html>
  );
}

next/font self-hosts the font (no external Google Fonts requests, zero layout shift).

React with MUI:

import { createTheme, ThemeProvider } from '@mui/material/styles';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import rtlPlugin from 'stylis-plugin-rtl';
import { prefixer } from 'stylis';

const cacheRtl = createCache({
  key: 'muirtl',
  stylisPlugins: [prefixer, rtlPlugin],
});

const theme = createTheme({ direction: 'rtl' });
Step 6: Common Pitfalls to Check
  1. Icons with directional meaning (arrows, back buttons) -- mirror them
  2. Progress bars -- should fill from right to left
  3. Sliders/carousels -- swipe direction should reverse
  4. Form labels -- should be right-aligned
  5. Breadcrumbs -- separator direction should reverse
  6. Tables -- header alignment and cell alignment
  7. Charts -- x-axis may need to reverse for Arabic readers

Examples

Example 1: Convert LTR Component to RTL

User says: "Make this card component work in Arabic"

Before (LTR-only):

.card {
  margin-left: 16px;
  padding-right: 12px;
  text-align: left;
  border-left: 3px solid blue;
}

After (RTL-compatible):

.card {
  margin-inline-start: 16px;
  padding-inline-end: 12px;
  text-align: start;
  border-inline-start: 3px solid blue;
}

With Tailwind, replace ml-4 pr-3 text-left border-l-4 with ms-4 pe-3 text-start border-s-4.

Example 2: Bidi Text Issue

User says: "Numbers are showing backwards in my Arabic text"

<!-- Wrong: phone number renders as 0544-123-050 -->
<p>התקשרו אלינו: 050-321-4450</p>

<!-- Correct: isolate the LTR content -->
<p>התקשרו אלינו: <span dir="ltr">050-321-4450</span></p>

Use unicode-bidi: isolate on the containing span for CSS-only solutions.

Example 3: Tailwind RTL Navigation

User says: "My sidebar is on the wrong side in Arabic"

<!-- Bad: sidebar stuck on left -->
<aside class="fixed left-0 w-64">...</aside>

<!-- Good: sidebar auto-mirrors -->
<aside class="fixed start-0 w-64">...</aside>

<!-- Back arrow icon still needs rtl: variant -->
<button class="rtl:rotate-180">
  <ArrowLeftIcon />
</button>

Bundled Resources

References
  • references/css-logical-properties.md — Complete physical-to-logical CSS property mapping table (margin, padding, border, positioning, text alignment, sizing) plus Arabic font stack recommendations for sans-serif, serif, and monospace. Consult when converting any LTR stylesheet to RTL-compatible logical properties or choosing Arabic web fonts.

Gotchas

  • CSS text-align: left is wrong for Arabic. Use text-align: start which respects the document direction. Agents frequently hardcode left alignment in CSS.
  • margin-left and padding-right do not flip in RTL mode. Use CSS logical properties: margin-inline-start and padding-inline-end instead. Agents trained on LTR CSS will generate physical properties.
  • Flexbox row direction auto-reverses in RTL, but row-reverse also reverses, causing a double-flip back to LTR order. Agents may add row-reverse thinking it creates RTL, but it actually creates LTR within an RTL context.
  • Phone numbers, credit card numbers, and code snippets must remain LTR even inside RTL containers. Wrap them in <bdo dir="ltr"> or use direction: ltr on the containing element. Agents often let these inherit RTL.

Reference Links

SourceURLWhat to Check
MDN CSS Logical Propertieshttps://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_valuesFull property list, browser support tables
Tailwind CSS RTL Supporthttps://tailwindcss.com/docs/hover-focus-and-other-states#rtl-supportrtl: / ltr: variant syntax
Tailwind Logical Propertieshttps://tailwindcss.com/docs/margin#logical-propertiesms-*, me-*, ps-*, pe-* utilities
Google Fonts Arabichttps://fonts.google.com/?subset=arabicAvailable Arabic font families
W3C Internationalizationhttps://www.w3.org/International/articles/inline-bidi-markup/Unicode bidi algorithm, markup best practices

Troubleshooting

Error: "Text alignment looks wrong"

Cause: Using text-align: left instead of text-align: start Solution: Replace all left/right in text-align with start/end.

Error: "Layout not mirroring"

Cause: Using physical margin/padding instead of logical properties Solution: Replace all margin-left/margin-right with margin-inline-start/margin-inline-end.

Comments

Markdown supported