CSS logical properties and why they're awesome
Tags: css, webdev
Published: 2021-03-07 18:05:12

If you regularly read news about upcoming CSS features, you've probably heard of [CSS logical properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties). But if you haven't, here's the long story short: instead of the usual directions top-to-bottom and left-to-right, we define two directions: `block` (which normally replaces the "vertical" direction) and `inline` (which is normally equivalent to "horizontal"), vaguely reminiscent of the `display` property.

Why? Because we don't *always* render content in the usual top-to-bottom, then left-to-right way! This is pretty common if you live in a culture that writes from *right to left*, like Arabic, or even *vertically*, like Japanese. If that's your case, you've probably had to deal with the Western-centric CSS properties that give a little too much for granted.

So, from now on, we should use `padding-inline-start` instead of `padding-left`. It *is* more verbose, but the point is that if we have to change the language of our application, i.e. from English to Arabic, we won't have to redefine our paddings because the padding we've meant to be *before* the text (i.e., on the left with English) will *still* be before the text and not after.

For example, we won't do this anymore:

```css
p {
  padding-left: 1em;
}
[dir="rtl"] p, p[dir="rtl"] {
  padding-left: initial;
  padding-right: 1em;
}
```

but rather this:

```css
p {
  padding-inline-start: 1em;
}
```

So, in the bigger picture, logical properties allow us to be *less* verbose! Also we don't have to set the opposite value to a reset value that could be the wrong one.

> If you were wondering, it's the [`writing-mode`](https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode) property that affects the logical axes. Be sure to use the *new* values, and not the old ones from the Internet Explorer era.

And another nice thing that's been available in the latest Chrome 89 is the ability to set the initial and final values of a property *at the same time* using a shorthand. Remember when we used to set the left and right margins independently, because we didn't want to touch the top and bottom ones using just `margin`?

```css
p {
  margin-left: 1em;
  margin-right: 2em;
}
```

Now we can do that in just a line:

```css
p {
  margin-inline: 1em 2em;
}
```

Isn't this awesome?

Other properties that support logical variants:

* `border` (together with `border-width`, `border-style` and `border-color`);
* `border-radius` (which is extra-awesome since we have `border-end-end-radius` instead of the longer `border-bottom-right-radius`);
* `float` and `clear` (only for the values `inline-start` instead of `left` and `inline-end` instead of `right`);
* `height` and `width` (and all their variants, e.g. `max-width`) become `block-size` and `inline-size`, respectively;
* [`inset`](https://developer.mozilla.org/en-US/docs/Web/CSS/inset) (a shorthand property that should replace the old `top`, `right`, `bottom` and `left`);
* `overflow` (as in `overflow-inline`/`block` instead of `overflow-x`/`y`);
* `text-align` (with the values `start` instead of `left` and `end` instead of `right`);
* other less known properties line `caption-side` and `overscroll-behavior`.

The only thing left behing is that we don't have a shorthand for setting all four sides of properties like `margin` or `border-width` *all at once* and *logically*. This syntax has been proposed:

```css
h1 {
  margin: logical 2em 1em;
}
```

but this is yet to be finalized (let alone implemented).