How to check your site in different languages and writing modes
Tags: css, webdev, a11y, i18n
Published: 2024-05-23 09:56:51

Building sites that support multiple writing modes and languages is challenging. You don't always know the language or even the script, and changing your OS to trigger certain conditions is cumbersome.

Even if you're willing to make that change on your device, during development you might not even have the other languages available to test with.

This post will show you how to test your site in different languages and writing modes without changing your OS settings or having access to your content in other languages (and without having to learn a new language).

## Quick terms

When we talk about multi-lingual sites, there are a few terms you should be familiar with:

- **Writing mode**: The direction in which text is written. For example, English is written from left to right, while Arabic is written from right to left.
- **Page language**: The language in which the content of the page is written.
- **Browser Locale**: This defines the user's language and region.

All of these fall under two terms that are also worth knowing:

- **Localization** (often shortened to l10n): The process of adapting a product or content to a specific locale or market: using the right spelling, number formatting, currency, etc.
- **Internationalization** (often shortened to i18n): The process of designing and developing a product or content in a way that it can be easily localized: using the right encoding, designing for multiple text directions, having a resilient layout, etc.

This post dives into how you can test your site in different languages and writing modes without changing your OS settings, so it focuses on the _i18n part_ of the process.

## Challenges

When building a site that supports multiple languages and writing modes, you need to consider the following:

1. **Language-dependent Browser APIs** like the I18n API, which is used to format dates, numbers, and currencies according to the user's (browser) locale.
1. **Text direction**: Some languages are written from left to right, while others are written from right to left. Your site can adapt to this when you take it into account during development.
1. **Text length**: Compared to English, some languages have much longer words and sentences while others have much shorter words and sentences. This can cause your layout to break if you don't account for it.

## The basics

To make sure your site adapts well to multiple languages and writing modes, you need to make sure that you have the following in place:

1. **The `lang` attribute**: This attribute is used to specify the language of the content of the page.
1. **The `dir` attribute**: This attribute is used to specify the direction of the text of the page.

Both of these attributes go on your `<html>` tag. From these two attributes, the browser can infer the language and writing mode of the page and adjust accordingly.

### The `lang` attribute

The lang attribute should have as its value the language code of the language you are using. It's important to set because it helps search engines know what language your page is in, and assistive technology like screen readers use it to pick the right voice and to make sure pronunciations are correct.

For example, for English you would use `en`, for Arabic you would use `ar`, and for Japanese you would use `ja`.

If you're targeting a specific dialect, you can use the language code followed by a dash and the dialect code. For example, for American English, you would use `en-US` while for British English you would use `en-GB`. The general advice though is to use the language code _without_ the region code unless there is a reason why the specific regional dialect is important for this page.

> Keep in mind that this doesn't mean you're targeting the USA or the UK specifically, since other countries also use either American English (like Canada) or British English (like Australia).

Occasionally you'll see the language code using an underscore to separate the language and region code, like `en_GB`. While Firefox normalizes this for you, both Safari and Chrome will not recognize this as a valid language code and so also not expose it to assistive technology.

### The `dir` attribute

The dir attribute should have as value either `ltr` (left-to-right) or `rtl` (right-to-left) and is used to specify the direction of the text of the page.

The default value on the web is `ltr`, so you usually only see this added for languages that are written from right to left as `<html dir="rtl">`.

With these two in place, you've told the browser everything it needs to know about your page.

## Testing different languages and writing modes

Now to test for different writing modes and languages, you can change the `lang` and `dir` attributes of your page. You could open the element inspector and change these manually but in Polypane, the emulations panel gives you easy access to these features along with the ability to change the browser locale.

### Changing the reading direction

To change the reading direction of your page, you can use the `dir` attribute.

Changing this from `ltr` to `rtl` will update the default styling in browsers such that text becomes right-aligned and the "start" value (for example, for flexbox and grid alignment) evaluates to the right. It does this even if your content is still in English.

In Polypane, you can change the reading direction of your page by selecting the desired direction from the emulations dropdown.

With the `dir` attribute set to `rtl`, you can test how your site looks when the text is right-aligned. If we check out the screenshot comparing the left-to-right and right-to-left versions we can see that it has done a pretty good job: the navigation is now on the right-hand side and the text mostly still has the correct padding, but we can spot a few things that we should fix:


![Two panes, one with ltr and one with rtl.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1hlg2q28w5yqmql5c8n1.png)

Visual issues here are:

- The 100% bar is still filled to the right.
- The "dismiss" button is still on the right side, and the "hide this block" image is no longer pointing at it.
- The checkmarks next to each list item are flush against the text and have too much space.

Almost all of these are the result of me using non-logical margins and alignments. Instead of `text-align: right` on the 100% in the bar, I should be using `text-align: end`. And instead of `margin-right` on the checkmarks, I should be using `margin-inline-end`.

Lastly, the dismiss button is positioned using a `float: right`. Instead of that, I should be using `float: inline-end`. The "hide this block" image is a little more involved since the text is baked into the graphic. You would probably switch this out for a different image or decouple the arrow from the text and position them separately.

All in all, the changes you would make here are mostly small and easy to test.

### Changing the language

While the `lang` attribute tells you what language the page is in, it won't change how your page is being displayed.

Browser APIs like the I18n API by default use the browser locale to determine how to format dates, numbers, and currencies. When you emulate the browser locale in Polypane it will update the places where that locale is being used. For example, here's an excerpt with a date from the Polypane blog in English and in Spanish:

![Two panes, one with an English date and one with a Spanish date.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jsbjqzrfek3hpuq89r1w.png)

To set the language and locale in Polypane you can use the dropdowns in the emulations dropdown. Polypane will autosuggest shortcodes as well as language names so that, for example, you don't have to remember that the language tag for Greenlandic is `kl`. You type "greenlandic" and Polypane sorts the rest.

![The emulations popup with a focused locale input. 'Gree' is typed into it and 'greek' and 'greenlandic' are provided as suggestions.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7hm9j5jkcrf7kqd64up.png)


## Testing your layout

Changing the browser locale or the page `lang` attribute doesn't change the text itself though. If you want to test how your layout behaves with different text lengths, you'll need to change the text itself.

English text is often shorter than other languages also using the Latin script (like German), but longer than languages like Chinese or Japanese where the characters used often represent more than a single letter in latin script, and sometimes a single character can even be an entire word (For example, 母 is "mother" in Chinese).

### Emulating text length

Rather than doing a full-page translation, potentially in a language you can't read, you can use the [Content Chaos feature](/docs/debug-tools/#content-chaos-test) in Polypane to replace all text on your page with random text. This way you can test how your layout behaves with different text lengths without translating the entire page.

> Content Chaos testing is not just useful for testing different languages, but also for making sure that once the perfectly designed text is replaced with real content, your layout still holds up.

To check if your layout handles longer titles well, you can use the "More text" option:

![A page with long content.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68e50b06zgr8bcxwfrz1.png)

You can see that the list of buttons on the left side responds well to more text: the content wraps and stays centered in the button, without having a weird line-height.

The main content is overflowing though, and that's because the button is not constrained in width. I can fix this by adding a `max-width` to the button, or by using `overflow-wrap: break-word` on the text.

If you want to test how your layout behaves with shorter text, you can use the "Less text" option:

![A page with short content.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kjs2ur19v7vju7e5vb8z.png)

Here you can see that the layout is still working well. Even with little text the buttons are still easily clickable and the layout doesn't break. I don't have to fix anything here to accommodate for languages with shorter text.

### Checking the line length

Another thing to keep in mind is the number of characters in a line. While the specific recommendations differ quite widely between sources, the general consensus is that you want to keep the line length short enough that it's easy to read, but long enough that you're not wasting space: between 45 to 70 characters per line, or (roughly) 10 words for English. To check these values, highlight a line and right-click to [see the number of characters and words in that line](/docs/measure-text-length/).

![Measure text length context menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tfzxdfxv0azm5xp747p.jpg)

This feature is aware of the language the page is in so will correctly detect real characters and words, as well as emoji and sentences.

for CJK (Chinese, Japanese and Korean) characters you want to aim for roughly half the number of characters per line as you would for Latin characters. This is because CJK characters are about twice as wide as those in the Latin script. This advice comes from the [WCAG 1.4.8 Visual Presentation Understanding page](https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html). Those are not part of WCAG itself, but meant to help you understand them.

## Conclusion

To check your layout and implementation for multiple languages, you'll want to check with different `dir`, `lang`, and browser locales. You can change these on an OS level, or emulate them in Polypane.

Rather than translating your entire page into a language you don't understand, you can use the Content Chaos feature to test how your layout behaves with different text lengths and make sure there aren't any errors when the text is longer or shorter than you expected.