Starting Point
v0.26.0
Start typing to search...
Go to Page
escClose

RTL

Every component supports right-to-left layouts out of the box, so interfaces for languages like Arabic, Hebrew, and Persian look and behave the way their readers expect. Layout, alignment, overlay positioning, and keyboard navigation all mirror automatically, with nothing to install or configure.

<div id="card-rtl-demo" dir="rtl">
  <div class="card">
    <div class="card-header">
      <h3 class="card-title" data-i18n="title">تسجيل الدخول إلى حسابك</h3>
      <p class="card-description" data-i18n="description">أدخل بريدك الإلكتروني أدناه لتسجيل الدخول إلى حسابك</p>
      <div class="card-action">
        <button class="btn btn-link" data-i18n="signUp">إنشاء حساب</button>
      </div>
    </div>
    <div class="card-content">
      <form class="flex flex-col gap-6">
        <div class="field">
          <label class="label" for="card-rtl-email" data-i18n="email">البريد الإلكتروني</label>
          <input class="input" id="card-rtl-email" type="email" placeholder="[email protected]" required />
        </div>
        <div class="field">
          <div class="flex w-full items-center">
            <label class="label" for="card-rtl-password" data-i18n="password">كلمة المرور</label>
            <a href="#" class="ms-auto inline-block text-sm underline-offset-4 hover:underline" data-i18n="forgotPassword">نسيت كلمة المرور؟</a>
          </div>
          <input class="input" id="card-rtl-password" type="password" required />
        </div>
      </form>
    </div>
    <div class="card-footer flex-col gap-2">
      <button type="submit" class="btn w-full" data-i18n="login">تسجيل الدخول</button>
      <button class="btn btn-outline w-full" data-i18n="loginWithGoogle">تسجيل الدخول باستخدام Google</button>
    </div>
  </div>
</div>
 
<script>
  const translations = {
    ar: { dir: "rtl", title: "تسجيل الدخول إلى حسابك", description: "أدخل بريدك الإلكتروني أدناه لتسجيل الدخول إلى حسابك", signUp: "إنشاء حساب", email: "البريد الإلكتروني", password: "كلمة المرور", forgotPassword: "نسيت كلمة المرور؟", login: "تسجيل الدخول", loginWithGoogle: "تسجيل الدخول باستخدام Google" },
    he: { dir: "rtl", title: "התחבר לחשבון שלך", description: "הזן את האימייל שלך למטה כדי להתחבר לחשבון שלך", signUp: "הירשם", email: "אימייל", password: "סיסמה", forgotPassword: "שכחת את הסיסמה?", login: "התחבר", loginWithGoogle: "התחבר עם Google" },
    en: { dir: "ltr", title: "Login to your account", description: "Enter your email below to login to your account", signUp: "Sign Up", email: "Email", password: "Password", forgotPassword: "Forgot your password?", login: "Login", loginWithGoogle: "Login with Google" },
  };
  window.addEventListener("message", (e) => {
    const t = translations[e.data?.lang];
    if (e.data?.type !== "sp-language" || !t) return;
    document.getElementById("card-rtl-demo").dir = t.dir;
    document.querySelectorAll("[data-i18n]").forEach((el) => {
      el.textContent = t[el.dataset.i18n];
    });
  });
</script>

Usage

Add dir="rtl" to the <html> element, or any container, and everything inside follows the text direction.

<html dir="rtl">
  <!-- every component in the page now renders right-to-left -->
</html>

How it works

The component styles use CSS logical properties instead of physical ones: paddings, margins, insets, borders, and text alignment are all expressed as start and end rather than left and right. The browser resolves them against the element's direction, so the same stylesheet renders correctly in both directions with no separate build and no RTL flag.

The JavaScript follows the same rule. Overlay placements resolve their start and end alignments against the text direction, arrow-key navigation in tabs follows the reading direction, and dropdown submenus open and close with the arrows pointing toward them. Direction is read at the moment of each interaction, so switching languages at runtime just works.

What you control

A few things are choices only you can make:

  • Side classes. Sheet and sidebar default to the logical start and end sides (sheet-end, sidebar-start), which follow the text direction. Use sheet-left, sheet-right, sidebar-left, or sidebar-right when you want a fixed physical edge instead.
  • Placements. data-sp-placement accepts the logical sides inline-start and inline-end alongside the physical Floating UI values, so a submenu authored once opens toward the reading direction in both modes.
  • Icons. Directional icons in your markup, like chevrons pointing into a submenu, need the rtl:rotate-180 utility. Symmetric icons need nothing.
  • Toasts. Toaster positions like toaster-bottom-right are physical viewport anchors by design; pick the corner you want per direction.

Examples

Every component page has an RTL example at the end of its examples section, with a language picker in the preview toolbar to switch between English, Arabic, and Hebrew.