Supporting CSS Multi Direction Languages in 2023

Elad Shechter
Appwrite
Published in
7 min readFeb 6, 2023

Supporting a website with the most common language directions (left-to-right and right-to-left) has historically required a lot of work.

However, in 2023, after obtaining most of the main features of CSS Logical Properties, supporting multi-direction language websites is now much easier.

Despite this, CSS Logical Properties still need to be improved and require additional solutions.

In this post, I want to examine how we solved the missing parts of supporting a multi-direction language website.

What are CSS Logical Properties?

Currently, most websites work with fixed axes according to physical directions, such as top/right/bottom/left.

We have our old, familiar CSS Physical Properties from those physical directions, such as margin-right, padding-bottom, border-left, and so on.

The Problem with Physical Properties

When enabling support for a language that goes right-to-left (direction: rtl), as well as left-to-right (direction: ltr), you need to create a kind of horizontal mirror of the website.

Creating the mirror requires a different set of CSS files if using Physical Properties.

Example of How a Multi-Direction Website Can Look Like:

CSS Logical Directions

This problem can be solved with CSS Logical Properties. Instead of the physical directions, we now have two axes:

  • Inline axis — this is the axis of the text.
  • Block axis — this is the axis of the flow of the website.

Each of those axes has a start and an end direction.

Inline-axis:
To describe the inline axis, we have its two directions:

  • Inline-start — describes the start of the line of text; in English, this is the left.
  • Inline-end — describes the end of the line of text; in English, this is the right.

Block-axis:
To describe the block axis, we have its two directions:

  • Block-start — describes the start of the flow of the website; in English and most languages today, this is the top.
  • Block-end — describes the end of the flow of the website; in English, and most languages today, this is the bottom.
From CSS Physical direction to Logical Directions

CSS Logical Properties

From these logical directions, we obtain updates for most of our physical properties, for example:

margin-left => margin-inline-start
padding-top => padding-block-start

/* position properties - for example for: position: fixed; */

top => inset-block-start
bottom => inset-block-end
left => inset-inline-start
right => inset-inline-end

When using the new CSS Logical Properties, the values flip according to the direction property value: ltr (left-to-right [default]) or rtl (right-to-left).

Example of left-to-right:

html {
direction: ltr; /* default value */
}

div {
margin-inline-start: 20px; /* = margin-left: 20px */
}

Example of right-to-left:

html {
direction: rtl;
}

div {
margin-inline-start: 20px; /* = margin-right: 20px */
}

What is Top and Bottom?

The top and bottom directions represent the block-axis, which is the main flow of the website.

Although it is not commonly used on the web, we can use the writing-mode property to affect the block-axis.

Note: Affecting the main flow of the website is made for Far East languages such as Chinese, in which the line of the text can be written from top to bottom.

writing-mode: horizontal-tb; /* top to bottom (default value) */
writing-mode: vertical-rl; /* right to left */
writing-mode: vertical-lt; /* left to right */

Changing the writing-mode value into vertical-lr or vertical-rl values will change to flow of the website from top-to-bottom to right-to-left or left-to-right. This means that the top is not the top anymore! The scroll is now horizontal instead of vertical, and the text goes from top to bottom.

Demo (by HJ Chen):

The writing-mode property is mostly unused; 99.99% of websites only work with direction set to ltr or rtl.

This also means that using the main axis/block axis properties, such as margin-block-start, does not typically affect us. However, I still prefer to use CSS Logical Properties throughout a website to be consistent.

Are CSS Logical Properties Good Enough?

CSS Logical Properties will do most of the job, but I encountered a few problems after using them. Let’s talk about those problems and how you can solve them.

Transform Properties

These days, we do most of the layout alignment with modules of CSS Flexbox and CSS Grid. However, in some cases, we want to position things via the transform property using the translateX() function, for example.

The problem with the transform property is that its axes do not work in logical directions. For example, transform: translateX(100px) will always move to the right, regardless of the direction value of the website.

transform: translateX(100px); /* will move the element always right */

Solution

If we need to translate an element based on the type of language, we need the value to change to a negative value instead of a positive value, or if it is negative, it will need to change to a positive one.

To do so, I create a CSS variable that by default has a value of 1.

:root {
--transform-direction: 1;
}

I multiply this value with the translateX value using the CSS calc() function.

transform: translateX( calc(100px * var(--transform-direction)) );

With the default value of 1, the translation behaves the same.

Support for RTL languages:
Now, the only thing left for me to do is to change the value of the --transform-direction variable to -1.

To do so, I simply create another :root selector, which overrides only when the main <html> element has the native dir=”rtl” attribute on it.

:root[dir="rtl"] {
--transform-direction: -1;
}

This will take effect only when the <html> element has the dir=”rtl” attribute:

<html dir="rtl">

Related Direction Arrows Icons

When changing the website direction, arrows can point in the wrong direction.

To solve this issue, we can again use the --transform-direction variable, but now in a slightly different way.

To flip the icon horizontally, I’m using the scaleX function of the transform property with the --transform-direction value.

Now, when the scaleX value of the transform property is equal to -1, this value will flip the arrows in the horizontal direction in their place.

.icon-arrow-left,
.icon-arrow-right {
transform: scaleX(var(--transform-direction));
}

This opposite direction can look strange to us, but remember that this is to support right-to-left languages such as Arabic and Hebrew.

More Things

Some CSS Logical Properties, or more precisely, logical values, are currently not widely supported.

The float property has 2 new logical values: inline-start and inline-end. Unfortunately, for now, they are only supported in Firefox.

To solve this, I am adding two new variables that represent the start and the end of the line.

The default values, are for left-to-right languages, with the ability to override those values in case we have the dir=“rtl” attribute of the <html> element.

CSS Code Example:

/* default - left-to-right languages */
:root {
--start-direction: left;
--end-direction: right;
}

/* Support for right-to-left languages */
:root[dir="rtl"] {
--start-direction: right;
--end-direction: left;
}

Now the only thing left for me to do is to use the variables according to my need. Example:

float: var(--start-direction);

Those variables can be useful in more cases, such as setting the background-position property, for example:

background-position: var(--end-direction) top;
background-repeat: no-repeat;

CSS Variables for Help

As we saw here, I defined three CSS variables that helped me to complete the support of CSS Logical Properties.

The CSS code looks like this:

/* default - left-to-right languages */
:root {
--transform-direction: 1;
--start-direction: left;
--end-direction: right;
}

/* Support for right-to-left languages */
:root[dir="rtl"] {
--transform-direction: -1;
--start-direction: right;
--end-direction: left;
}

If you are using Sass preprocessor, you can write it in this way:

:root {
/* default - left-to-right languages */
--transform-direction: 1;
--start-direction: left;
--end-direction: right;

/* Support for right-to-left languages */
&[dir="rtl"] {
--transform-direction: -1;
--start-direction: right;
--end-direction: left;
}
}

To Summarize

In this post, we examined how you can support a multi-direction website.

The first step is to use native CSS Logical Properties wherever you can. The second step is to use additional CSS variables for the less supported CSS Logical Properties.

Final Words

Pink Design is finally out today. Pink Design was built with new inventive CSS methods, and prioritizes accessibility and developer experience. As a company developing an open-source product, this is a big step for Appwrite’s community of contributors. As always, we will keep improving Pink Design, allowing it to grow alongside Appwrite.

Thank you for being a part of our journey! If you haven’t already, browse the 💻 Pink Design GitHub Repository or check out our 🚀 Getting Started Guide to use Pink Design in your projects or when contributing to Appwrite.

Until next time!

--

--