The dir attribute in HTML and the dir property in CSS can be used to set the direction of text and horizontal flow. Some languages are written Left-To-Right (LTR), while others are written Right-To-Left (RTL). So having this level of control is vital for creating documents and interfaces for the web.
Building an interface to support both LTR and RTL layouts is a challenge. Flexbox and Grid certainly makes things easier, but they don't cover all our styling needs.
There are many CSS rules we write in which we specify a physical direction or side. For instance, when we write CSS to layout horizontal elements, it is common to set a margin only on a single side and set a margin of 0
(on the same side) to the first or last sibling element.
.element {
margin-right: 1rem;
}
.element:last-child {
margin-right: 0;
}
Or
.element:not(:last-child) {
margin-right: 1rem;
}
In the above example we are adding a margin on the right side of each element except the last. That's how it is written. Though what we mean when we write this is to add a margin after the element in the direction of the horizontal flow of the document (or the parent element).
A common way to style blockquote
is to add a border to one side of the quote; the side we consider to come before the quote.
This is Bulma's <blockquote>
styling:
.content blockquote {
background-color: #f5f5f5;
border-left: 5px solid #dbdbdb;
padding: 1.25em 1.5em;
}
And there are many other styling choices we make in which we specify a side/direction (left/right) in CSS, but what we actually mean is before/after.
So when building interfaces that support both LTR and RTL layouts, one option would be to write CSS rules like:
.class {}
html[dir="rtl"] .class {}
Or perhaps even load different stylesheets for LTR and RTL layouts. However, both options require we either write more CSS or set up our tooling to generate the appropriate flipped styles. And there are also tools that convert LTR to RTL styles for you.
Wouldn't it be nice to work with a lower level of abstraction instead? What if we can tell the browser we are targeting the side before/after an element instead of referring to the physical directions left/right? At the end of the day this is what we mean a lot of the times. This reminds me of this tweet:
When you code CSS, you’re writing abstract rules to take *unknown* content and organize it in an *unknown* medium. That shit is hard.13:26 PM - 17 Mar 2017
CSS has what is called logical properties. We can now tell the browser what we actually mean. Instead of using -left
and -right
, we can use -inline-start
and -inline-end
:
.element:not(:last-child) {
margin-inline-end: 1rem;
}
Similarly instead of using -top
and -bottom
, we can use -block-start
and -block-end
.
This means we can write one set of rules that target both LTR and RTL layouts. Here is an example using the margin-inline-end
property:
Using the border-inline-start
and padding-inline-start
properties:
Firefox also supports border-*-*-radius
so you can target different corners with border-start-start-radius
, border-end-start-radius
, etc.
All demos:
For a deeper explanation, you can refer to Rachel Andrew's article Understanding Logical Properties And Values. This is not just about RTL interfaces or horizontal bidirectional CSS rules. Rachel's article also covers logical dimensions.
Browser Support
Can I Use?:
Top comments (3)
So much to learn in such a small lifetime.. Thanks mate. You have just reduced my css file by half. I actually used to build 2 separate css file from scss. One for left, and one for right. But if someone set's to right, We actually had to load both. Now I can suggests improvements to my boss for his clients.
It's good to know a lot of css accessibility features are gaining popularity.
Great to hear! Note that logical properties are not supported in IE11. The Chromium-based Edge will support logical properties though: caniuse.com/#feat=css-logical-props
Thank you for sharing. Extremely useful. Always good to learn some new CSS properties!