Skip to content
UI Brok

Loading…

No results

Browse catalog

Direction (RTL)

Every component ships right-to-left support out of the box. Like shadcn/ui, Direction is a guide rather than an installable component: set the document dir attribute and the components mirror automatically, because they are authored with CSS logical properties instead of physical left/right utilities. No extra CSS, no wrapper components, no post-processing — it just works.

Enabling RTL

Set dir="rtl" on the <html> element to apply RTL to the entire page. The lang attribute should match the language you are rendering.

resources/views/layouts/app.blade.php Blade
<html lang="ar" dir="rtl">

You can also scope the direction to any subtree. This is useful for rendering a single RTL widget inside an otherwise LTR page, or for language-switcher previews.

resources/views/components/my-widget.blade.php Blade
{{-- Scope RTL to a single component, not the whole page --}}
<div dir="rtl">
    <x-ui.card>…</x-ui.card>
</div>

Switch the preview workbench on any component page to RTL to see it mirror live — no code changes required.

Side by side

The same markup, rendered once LTR and once RTL. Both panels share identical HTML — only the dir attribute differs.

Left to right (dir="ltr")

Search… ⌘K

Right to left (dir="rtl")

Search… ⌘K

How it works

CSS logical properties replace the concept of "left" and "right" with inline-start and inline-end. The browser resolves those to physical directions based on the element's writing direction, so the same class list works in both LTR and RTL contexts.

Use this (logical) Not this (physical) Resolves to
ps-4 / pe-4 pl-4 / pr-4 padding-inline-start/end
ms-2 / me-2 ml-2 / mr-2 margin-inline-start/end
start-0 / end-0 left-0 / right-0 inset-inline-start/end
text-start / text-end text-left / text-right text-align: start/end
border-s / border-e border-l / border-r border-inline-start/end
rounded-s-* / rounded-e-* rounded-l-* / rounded-r-* border-start/end-radius

All primitives in this system follow this rule. If you are building a custom component on top of them, use the same logical utilities so your component automatically inherits RTL support.

  • Interactive components mirror keyboard semantics too — arrow keys in tabs, menus, sliders, carousels, and the calendar swap with the writing direction automatically.
  • Every primitive exposes a stable data-slot attribute, making CSS overrides direction-aware without targeting physical sides.

Writing RTL-safe custom components

Follow the same conventions when building your own Blade components on top of these primitives.

Use logical spacing utilities

Replace every pl-*, pr-*, ml-*, mr-* with their logical equivalents. Tailwind ships these out of the box — no plugin required.

Mirror directional icons

Chevrons, arrows, and other direction-sensitive icons need an explicit flip. Use the rtl:-scale-x-100 utility (visible in the live demo above on the breadcrumb chevron).

Keep numbers and code LTR

Numeric values, code snippets, phone numbers, and URLs must remain left-to-right. Wrap them in <bdi> or apply dir="ltr" to the specific element.

Test with the RTL toggle

Open any component page in the docs and flip the preview workbench to RTL. No code change required — it injects dir="rtl" onto the preview frame and the component should mirror cleanly.

Gotchas

Warning

Directional icons are not mirrored automatically. Chevrons, arrows, "back" buttons, and progress indicators are directional — CSS logical properties only affect spacing and position, not SVG shape or transform. Add rtl:-scale-x-100 to every icon that points left or right. Icons that are symmetric (search, close, spinner) need no change.
resources/views/components/my-nav.blade.php Blade
{{-- chevron that mirrors in RTL --}}
<svg class="size-4 rtl:-scale-x-100" …>…</svg>

{{-- search icon — symmetric, no mirroring needed --}}
<svg class="size-4" …>…</svg>

Note

Numbers, code, and URLs stay LTR. Even inside an RTL context the Unicode bidirectional algorithm keeps numeric strings left-to-right, but explicit dir="ltr" or a <bdi> tag removes any ambiguity and prevents odd wrapping in mixed-direction sentences.

Note

Third-party libraries may not respect dir. Chart libraries, date-pickers from other ecosystems, and embedded iframes may have their own internal LTR assumptions. Test each integration independently.

Note

Avoid mixing logical and physical utilities on the same axis. Writing both pl-4 and ps-4 on the same element creates specificity confusion. Pick one convention and be consistent — all shipped primitives use logical-only.