Skip to Content
Course content

134: Handling RTL Layouts in JavaScript Apps

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you've spent your whole life driving in the United States. You know instinctively that the passing lane is on the left and you merge from the right. Now, imagine you fly to London. The rules of the road—stopping at red lights, yielding to pedestrians—are exactly the same. But the spatial orientation is mirrored. If you try to apply your "always merge from the right" habit in London, you're going to cause a pile-up.

Handling RTL (Right-to-Left) layouts in JavaScript is exactly like that. The "logic" of your app—how a user logs in, how data is fetched—doesn't change. But the "road" the user travels on flips. If your code explicitly says "move this element 20px to the right," it might work for an English speaker, but for an Arabic or Hebrew speaker, you've just driven them straight into a wall.

Flipping the Global Switch

In a modern app, you don't want to manually flip every single element. Instead, you treat the dir attribute on the html tag as your global "driving side" setting. When a user selects an RTL language, your JavaScript should update this attribute. Everything else should flow from that one source of truth.

// A simple way to handle the direction switch
function setAppDirection(lang) {
  const rtlLanguages = ['ar', 'he', 'fa'];
  const direction = rtlLanguages.includes(lang) ? 'rtl' : 'ltr';
  
  document.documentElement.dir = direction;
  document.documentElement.lang = lang;
  
  // I usually save this to localStorage so the user doesn't 
  // see a "flash" of LTR layout on the next page load.
  localStorage.setItem('preferred-lang', lang);
}

Escaping the "Left" and "Right" Mindset

Here is where most developers mess up: they write JavaScript that manipulates marginLeft or right. Once you move into RTL territory, "left" and "right" are no longer reliable concepts. We need to start thinking in terms of Start and End.

In LTR, "start" is left. In RTL, "start" is right. CSS Logical Properties (like margin-inline-start) handle this automatically, but when you're calculating positions in JS—say, for a custom tooltip or a drag-and-drop library—you have to be explicit.

function getStartOffset(element) {
  const isRtl = document.documentElement.dir === 'rtl';
  const rect = element.getBoundingClientRect();
  
  // Instead of always returning rect.left, we check the direction
  return isRtl ? window.innerWidth - rect.right : rect.left;
}

Handling Mirrored UI Components

Not everything flips automatically. Some elements, like a "Back" arrow, must be mirrored because the concept of "going back" is visually tied to the direction of the text. If the text flows right-to-left, "back" is now a right-pointing arrow.

I've found that the cleanest way to handle this in JS is to toggle a data attribute on the body. This allows you to write specific CSS overrides for icons that shouldn't just move, but actually rotate.

// When switching directions, update a data attribute for CSS targeting
function updateUIMirroring(direction) {
  document.body.setAttribute('data-dir', direction);
}

// In your CSS, you can then do:
// [data-dir="rtl"] .back-button { transform: rotate(180deg); }

One last tip: be careful with text-align: left. If you've hardcoded that in your styles or JS, it will override the natural RTL behavior and leave your Arabic text hugging the left wall, which looks broken to a native speaker. Stick to text-align: start.




📋 Practical Task

Exercise: Building a Bi-Directional Language Toggle for a User Dashboard

You are tasked with adding a language switcher to a dashboard. The dashboard contains a sidebar and a main content area. When the user switches from English to Arabic, the entire layout must flip, and a specific "Notification" icon (represented by a div with the class .notif-icon) must be mirrored.

Requirements:

  • Create a function toggleLanguage(lang) that updates the dir attribute of the html element.
  • The function must also set a data-dir attribute on the body to 'rtl' or 'ltr'.
  • Implement a simple check: if the language is 'ar', the direction is 'rtl'; otherwise, it is 'ltr'.
  • Ensure the localStorage is updated so the preference persists.
  • Write a small piece of logic that logs to the console whether the "Start" of the page is currently the left or right side of the screen based on the current state.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.