DEV Community

Hussein Al Hammad
Hussein Al Hammad

Posted on

Bidirectional horizontal rules in CSS

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;
}

Enter fullscreen mode Exit fullscreen mode

Or

.element:not(:last-child) {
    margin-right: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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 {}
Enter fullscreen mode Exit fullscreen mode

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:

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;
}
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
abhinav1217 profile image
Abhinav Kulshreshtha

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.

Collapse
 
hus_hmd profile image
Hussein Al Hammad

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

Collapse
 
jabranr profile image
Jabran Rafique

Thank you for sharing. Extremely useful. Always good to learn some new CSS properties!