Learn Tailwind CSS - Accessibility & Internationalization
Episode 17 of 23

Learn Tailwind CSS - Accessibility & Internationalization

This episode covers accessibility and internationalization: focus rings and color contrast, reduced motion support using the motion-safe and motion-reduce variants, and handling RTL layout and localization with the rtl and ltr variants.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

A good application must be usable by everyone, including with a keyboard, screen reader, and reduced motion preferences — then adapt to languages read right to left. Episode 17 covers accessibility and internationalization: focus rings, contrast, reduced motion, and RTL support.

Tailwind provides dedicated variants for all of these needs: focus-visible for keyboard indicators, motion-safe and motion-reduce for animations, and rtl and ltr for text direction. Using them correctly makes your app inclusive without writing custom CSS.

Focus Rings and Contrast

Focus Indicators for the Keyboard

During keyboard navigation, the focus indicator is the primary cue. Don't remove it carelessly; use focus-visible so the ring only appears during keyboard navigation, not on a mouse click:

HTMLSafe focus ring
<button
  class="rounded bg-blue-600 px-4 py-2 text-white
         focus:outline-none
         focus-visible:ring-2 focus-visible:ring-blue-500
         focus-visible:ring-offset-2"
>
  Aksi
</button>

focus:outline-none followed by focus-visible:ring-2 is the standard pattern: the default outline is removed, then replaced with a custom ring that's only active for keyboard input.

Text Contrast

The minimum contrast ratio is 4.5:1 for normal text and 3:1 for large text. Token choices must account for the background:

HTMLSafe contrast
<p class="text-gray-900 dark:text-gray-100">Teks utama di latar putih dan gelap.</p>
<p class="text-gray-400">Kontras rendah — hati-hati, sering gagal audit.</p>

text-gray-900 on white and text-gray-100 on dark meet the ratio; text-gray-400 often falls below the threshold. Always test your color pairings.

Reduced Motion

Some users are sensitive to animation. Respect system preferences with the motion-safe and motion-reduce variants:

HTMLAnimation that respects preferences
<div class="motion-safe:animate-bounce motion-reduce:animate-none">
  Elemen beranimasi, kecuali saat pengguna menonaktifkan animasi.
</div>

motion-safe:animate-bounce only runs the animation if the system allows it; motion-reduce:animate-none disables it when not. The best pattern: start with no animation, then add it with motion-safe: — not the other way around.

Smooth transitions are also safer:

HTMLSafe transitions
<div class="transition-transform motion-reduce:transition-none">
  Konten yang bergeser dengan mulus, tanpa animasi saat dilarang.
</div>

RTL Support

Arabic, Hebrew, and other languages are read right to left. Prepare your layout with the dir attribute and the rtl and ltr variants:

HTMLRTL-ready layout
<div dir="rtl" class="flex gap-4 rtl:flex-row-reverse">
  <div>Pertama</div>
  <div>Kedua</div>
</div>

rtl:flex-row-reverse flips the flex order when the document is right-to-left, without duplicating markup. The rtl and ltr variants activate based on the dir value on the element or an ancestor.

For spacing between text and icons, space-x-reverse keeps the gap correct:

HTMLCorrect spacing in RTL
<div dir="rtl" class="flex space-x-2 rtl:space-x-reverse">
  <span>Item 1</span>
  <span>Item 2</span>
</div>

rtl:space-x-reverse flips the margin direction from space-x, so the gap lands on the right side. Don't hardcode left or right padding for layouts read in both directions — use direction variants or logical properties like ms- and me-.

Manage the dir attribute at the document root level (<html dir="rtl">), not on random elements, so browsers and screen readers interpret the text correctly. When the language is chosen at runtime, set dir together with the lang change so the pair stays consistent and aligned with the layout.

Also make sure menus, dialogs, and tooltips don't rely on visual order alone: focus elements and labels must remain meaningful when the layout is flipped to the opposite direction.

Accessibility testing isn't enough with just visual checks. Run keyboard-only testing to make sure the focus order makes sense, and use tools like axe to find failing contrast and missing ARIA attributes. This simple checklist catches most issues before code touches production. Make it part of your pipeline, not a seasonal activity, so accessibility regressions can't sneak in through an innocent-looking PR.

Warning

Avoid left-0 or right-0 for elements that should shift with the language direction. It's safer to use logical properties (start-0, end-0) or the rtl: and ltr: variants so the layout doesn't break when the language changes.

Conclusion

Episode 17 made your application inclusive and internationalization-ready: keyboard-friendly focus rings, contrast that passes audits, animations that respect reduced motion, and layouts that are correct in both RTL and LTR reading directions.

Key takeaways:

  • Use focus-visible:ring-* as a safe replacement for the default outline.
  • Ensure a minimum contrast ratio of 4.5:1 for normal text.
  • Start without animation, then add it with motion-safe:.
  • motion-reduce:transition-none turns off transitions when forbidden.
  • rtl: and ltr: adapt the layout to the language direction.
  • space-x-reverse keeps spacing correct in RTL mode.

Next, in episode 18, we'll cover modern framework integration & tooling — Tailwind integration in Next.js App Router, Vite, SvelteKit, Astro, and Remix, plus compatibility with hybrid CSS-in-JS approaches.

Learn Tailwind CSS - Accessibility & Internationalization | Learn Tailwind CSS