Blog3 min read
How I Reduced RTL CSS Code Using Logical Properties
I share how I simplified Arabic RTL support at Travelwings by replacing duplicated left/right CSS overrides with logical properties such as margin-inline-start, making one layout work naturally in both LTR and RTL.

While working on Arabic RTL support at Travelwings, I faced a common frontend issue: a lot of our existing UI had been built with left, right, margin-left, and padding-right values.
Previously, RTL support was handled with separate CSS rules targeting the page direction, something like this:
[dir='rtl'] .flight-card {
margin-right: 16px;
margin-left: 0;
text-align: right;
}
[dir='ltr'] .flight-card {
margin-left: 16px;
margin-right: 0;
text-align: left;
}This worked, but it meant I had to write and maintain extra RTL overrides for many components. As the product grew, those overrides became difficult to manage. A small UI change could require checking both the default CSS and the RTL-specific CSS.
Then I started using CSS logical properties.
Instead of writing CSS based on physical directions like left and right, logical properties work according to the document direction. So the same CSS automatically adapts for English (LTR) and Arabic (RTL).
For example, instead of this:
.card {
margin-left: 16px;
}I used:
.card {
margin-inline-start: 16px;
}In an English LTR layout, margin-inline-start means margin-left.
In an Arabic RTL layout, it automatically becomes margin-right.
That means one line of CSS supports both directions without an extra [dir='rtl'] override.
Here are some of the logical properties I started using regularly:
Traditional CSS | Logical CSS |
|---|---|
margin-left | margin-inline-start |
margin-right | margin-inline-end |
padding-left | padding-inline-start |
padding-right | padding-inline-end |
border-left | border-inline-start |
border-right | border-inline-end |
left | inset-inline-start |
right | inset-inline-end |
top | inset-block-start |
bottom | inset-block-end |
width | inline-size |
height | block-size |
For example, a search input icon that previously needed separate rules can become much cleaner:
.search-input__icon {
position: absolute;
inset-inline-start: 12px;
}
.search-input {
padding-inline-start: 40px;
}Now the icon appears on the left in English and on the right in Arabic automatically. The input padding also follows it correctly.
Another useful example is borders:
.item {
border-inline-start: 3px solid #ff7a00;
padding-inline-start: 12px;
}In LTR, the orange border appears on the left. In RTL, it moves to the right without writing any Arabic-specific CSS.
This approach helped me remove a large amount of duplicated RTL CSS from the project. It also made components easier to reuse, because their layout was no longer tied to one writing direction.
I still needed direction-specific styling in a few cases, especially where an icon itself needed to be flipped or where a layout had a very specific visual requirement. But for spacing, positioning, borders, and many alignment cases, logical CSS properties made RTL support much more maintainable.
For any product that supports both English and Arabic, I would strongly recommend considering logical properties from the start. It saves time, reduces CSS duplication, and makes the codebase much easier to maintain as the product grows.
Useful MDN references: