Proper websites, done properly

CSS logical properties and new units

6 minute read time.

Help keep your CSS forward-thinking and flexible with logical properties and forget whether or not you mean left, right, top or bottom

Logical properties

In the past, you'd always do margin-top, width or border-right. This is fairly clear to people building sites for Left to Right (LtR) languages such as English, French, or Spanish. But what about Right to Left (RtL) like Arabic, Urdu, or Hewbrew? Or languages written top to bottom from right to left, like Chinese, Vietnamese, Korean or Japanese?

Think how much additional CSS you'd have to write for each of these language directions if you were building a multilingual site. Every single instance of margin-left might need replacing with margin-top if you were doing a Chinese translation.

Logical properties fix this problem. You can write your properties once, and your CSS will just work.

Replace any 'top' with 'block-start', 'bottom' with 'block-end', 'left' with 'inline-start', and 'right' with 'inline-end'. In English, for example, 'block' is the vertical property, and 'inline' is the horizontal property. For Japanese, 'block' would be the horizontal property, and 'inline' would be the vertical.

So, again using English as an example, here's a bigger list (but not quite the complete one!) of how logical properties replace the old method.

For margin and padding:

  • [margin/padding]-block-start replaces [margin/padding]-top
  • [margin/padding]-block-end replaces [margin/padding]-blottom
  • [margin/padding]-inline-start replaces [margin/padding]-left
  • [margin/padding]-inline-end replaces [margin/padding]-right

For positioning:

  • inset-block-start replaces top
  • inset-block-end replaces bottom
  • inset-inline-start replaces left
  • inset-inline-end replaces right

For sizing:

  • block-size replaces height
  • min-block-size replaces min-height
  • max-block-size replaces max-height
  • inline-size replaces width
  • min-inline-size replaces min-width
  • max-inline-size replaces max-width

There are a few others, such as for border, border-radius and some overflow properties. MDN has the full list of logical properties.

Some of these feel like they're a bit too verbose when you first start to use them, and for many sites they may not be necessary as they will never need to consider translations. From a developer point of view though, it's a great mentality to get yourself in, and even if you start with the most handy properties, you're still working better and smarter.

[margin/padding]-inline and [margin/padding]-block allow you to shorthand both start and end properties for an axis. So instead of having to write both a margin-top and a margin-bottom, or having to write a full shorthand margin (possibly overriding some values you don't want to), you can now just do: margin-block: 10px.

New CSS viewport units

There's so many different unit types you can use in CSS already, and all have a place somewhere, but in general use most people will probably use the more common types: px, %, rem, em, vw, vh.

Viewport units are a newer addition to the list, but a helpful one. Previously, you could use vw or vh, where 1vw was equal to 1% of the viewport width and 1vh equivalent to 1% of the viewport height.

The problem with the older viewport units was that they did not take into account dynamic viewport heights for devices such as phones where window chrome collapses as you scroll down the page. 100% of the viewport height is different on page load to once you've started scrolling, and can cause issues with styling. There's now:

  • svh/svw - smallest viewport height/width.
    The smallest value of either height or width when all window chrome is shown.
  • lvh/lvw - largest viewport height/width
    The largest value of either height or width when window chrome is reduced.
  • dvh/dvw - dynamic viewport height/width
    The width or height regardless of whether the window chrome is full or reduced.

There are also min/max and logical versions of these units too, so you'll have much better control over trying to style based on viewport sizes from now on.