CSS Logical Properties and Values

Avatar of Ollie Williams
Ollie Williams on (Updated on )

Now that cross-browser support is at a tipping point, it’s a good time to take a look at logical properties and values. If you’re creating a website in multiple languages, logical properties and values are incredibly useful. Even if you’re not, there are still some convenient new shorthands it’s worth knowing about.

For example, I’ve lost count of the amount of times I’ve written this to center something:

.thing {
  margin-left: auto;
  margin-right: auto;
}

We could make it a one-liner with something like margin: 0 auto; but then the top and bottom margins get thrown into the mix. Instead, we can select just the left and right margin with the margin-inline logical property.

Start thinking of things as “inline” or “block”

That last demo is pretty neat, right? The margin-inline property sets both margin-left and margin-right. Similarly, the margin-block property sets both margin-top and margin-bottom. And we’re not only talking margins. Logical properties has similar shorthands to set border and padding. So if you have a visual design that calls for borders only on the sides, you can just use border-inline instead of fussing with each physical direction on its own.

Showing border-left and border-right with matching values combined together as border-inline as a single declaration, and another example showing padding-top and padding-bottoms et to 32 pixels combined to padding-block set to 32 pixels.
Rather than thinking in physical terms, like left and right, we can think of an “inline” direction and a “block” direction.

So, as we move ahead, we now know that we’re dealing with inline and block directions instead of physical directions. Inline handles the left and right directions, while block manages top and bottom.

That is, until things get swapped around when the writing-mode changes.

Pay attention to direction and writing mode

What we’ve seen so far are examples of CSS logical properties. These are versions of CSS properties were used to like margin and padding, but written in a new way that forgoes physical directions (i.e. left, right, top, and bottom).

CSS was developed with the English language in mind and English is written and read from left-to-right. That’s not the case for all languages though. Arabic, for example, is read from right-to-left. That’s why HTML has a dir attribute.

<html dir="rtl">

CSS has an equivalent property (although it’s recommended to use the HTML attribute just in case the CSS fails to load):

.foreign-language { direction: rtl; }
Two cards, one in english and one in arabic, Both cards have a subtitle in gray above a main heading in a larger black font. The english goes from left to right and indicates the direction with an arrow below the card. The arabic direction is reverse of the english.
Credit: Ahmad Shadeed

Chinese, Japanese, Korean and Mongolian can be written either horizontally from left-to-right, or vertically from top to bottom. The majority of websites in these languages are written horizontally, the same as with English.

Comparatively, vertical writing is more common on Japanese websites. Some sites use a mixture of both vertical and horizontal text.

baroku.co.jp

When written vertically, Chinese, Japanese and Korean are written with the top-right as a starting point, whereas Mongolian reads from left to right. This is exactly why we have the writing-mode property in CSS, which includes the following values:

  • horizontal-tb: This is the default value, setting the the direction left-to-right for languages like English or French, and right-to-left languages like Arabic. The tb stands for “top-to-bottom.”
  • vertical-rl: This changes the direction to right-to-left in a vertical orientation for languages like Chinese, Japanese and Korean.
  • vertical-lr: This is used for vertical left-to-right languages, like Mongolian.

CSS logical properties offer a way to write CSS that is contextual. When using logical properties, spacing and layout are dependent on both the writing-mode and direction (whether set by either CSS or HTML). It therefore becomes possible to reuse CSS styles across different languages. BBC News, for example, rebuild their website in over a dozen languages. That’s a better experience than leaving users to rely on autotranslate. It also means they can better cater specific content to different parts of the world. The visual styling though, remains much the same across regions.

Screenshot of the BBC website. The header is red with the BBC logo aligned to the right of the screen. The navigation is also in red and aligned to the right. There is a featured article with right-aligned text and a large image to the right of it. Below that are four more article cards in a single row, each with an image above a title and date and aligned right.
bbc.com/arabic

Let’s look at the example below to see the shortcomings of physical properties. Using the physical margin-left property (shown in red), everything looks good in English. If you were to reuse the CSS but change the writing mode to rtl (shown at the bottom) there’s no space between the text and the icon and there’s excess white space on the left of the text. We can avoid this by using a logical property instead.

Two buttons, both with an envelope icon and a label. The left-to-right version of the button on top shows the spacing between the icon and the label. The right-to-left version shows the spacing to the left of both the label and icon.

What makes logical properties and values so useful is that they will automatically cater to the context of the language. In a left-to-right language like English, margin-inline-start will set the left-side margin. For a right-to-left language like Arabic, Urdu, or Hebrew, it will set the right-hand margin — which solves the layout problem in the above example. That’s right-to-left taken care of. If you have vertical text, margin-inline-start will cater to that context to, adding the margin at the top, which is where you would start reading from in any vertical language (that’s why it’s called margin-inline-start — just think about which direction you start reading from). The direction of inline changes based on the element’s writing-mode. When a vertical writing-mode is set, it handles the vertical direction top and bottom. See how things can get switched around?

An example of the writing direction in Mongolian. (Credit: W3C)

A complete list of logical properties and values

There are dozens of CSS properties that have a logical alternative syntax. Adrian Roselli has a handy visualization where you can toggle between the physical CSS properties that we’re all used to and their logical property equivalents. It’s a nice way to visualize logical properties and the physical properties they map to when the direction is ltr and the writing-mode is horizontal-tb.

Let’s break all of those down even further and map each and every physical CSS property to its logical companion, side-by-side. The tables shown throughout this article show traditional physical CSS in the left column and their logical equivalents (using a left-to-right horizontal mapping) in the right column. Remember though, the whole point of logical properties is that they change based on context!

Sizing

In a horizontal writing mode, inline-size sets the width of an element, while block-size sets the height. In a vertical writing mode, the opposite is true: inline-size sets the height and block-size sets the width.

Physical propertyLogical property
widthinline-size
max-widthmax-inline-size
min-widthmin-inline-size
heightblock-size
max-heightmax-block-size
min-heightmin-block-size

Logical properties for sizing have good cross-browser support.

Borders

Everything here has solid cross-browser support among modern browsers.

Physical propertyLogical property
border-topborder-block-start
border-bottomborder-block-end
border-leftborder-inline-start
border-rightborder-inline-end

Here’s an example of using border-inline-start shown with English, Arabic, and Chinese.

Here’s an example that sets border-block-start dotted and border-block-end dashed:

There are also logical properties for setting the border color, width, and style individually:

Physical propertyLogical property
border-top-colorborder-block-start-color
border-top-widthborder-block-start-width
border-top-styleborder-block-start-style

So, again, it’s about thinking in terms of “inline” and “block” instead of physical directions, like left and top. We also have shorthand logical properties for borders:

Physical propertyLogical property
border-top and border-bottomborder-block
border-left and border-rightborder-inline

Margin

Here are all the individual logical margin properties:

Physical propertyLogical property
margin-topmargin-block-start
margin-bottommargin-block-end
margin-leftmargin-inline-start
margin-rightmargin-inline-end

These logical properties has comprehensive modern cross-browser support, including Samsung Internet, and has been supported in Safari since 12.2.

And, remember, we have the shorthands as well:

Physical propertyLogical property
margin-top and margin-bottommargin-block
margin-left and margin-rightmargin-inline

Padding

Padding is super similar to margin. Replace margin with padding and we’ve got the same list of properties.

Physical propertyLogical property
padding-toppadding-block-start
padding-bottompadding-block-end
padding-leftpadding-inline-start
padding-rightpadding-inline-end
padding-top and padding-bottompadding-block
padding-left and padding-rightpadding-inline

Just like margins, logical properties for padding have good cross-browser support.

Positioning

Need to offset an element’s position in a certain direction? We can declare those logically, too.

Physical propertyLogical property
topinset-block-start
bottominset-block-end
leftinset-inline-start
rightinset-inline-end
top and bottominset-block
left and rightinset-inline

In a horizontal writing mode (either left-to-right, or right-to-left) inset-block-start is equivalent to setting top, and inset-block-end is equivalent to setting bottom. In a horizontal writing mode, with a left-to-right direction, inset-inline-start is equivalent to left, while inset-inline-end is equivalent to right, and vice-versa for right-to-left languages.

Conversely, for a vertical writing mode, inset-inline-start is equivalent to top while inset-inline-end is equivalent to bottom. If writing-mode is set to vertical-rl, inset-block-start is equivalent to right and inset-block-end is equivalent to left. If the writing-mode is set to vertical-lr, the opposite is the case and so inset-block-start is equivalent to left.

Logical propertyWriting modeEquivalent to:
inset-block-startHorizontal LTRtop
inset-block-startHorizontal RTLtop
inset-block-startVertical LTRleft
inset-block-startVertical RTLright

Here’s an example of how the same CSS code for absolute positioning looks in each of the four different writing directions:

Logical properties for positioning are supported in all modern browsers, but only recently landed in Safari.

There’s also a new shorthand for setting all four offsets in one line of code. Here’s an example using inset as a shorthand for setting top, bottom, left, and right in one fell swoop to create a full-page overlay:

I’ve heard inset incorrectly referred to as a logical property. But, a quick look in DevTools shows that it is actually a shorthand for physical values, not logical properties:

What it’s actually doing is defining physical offsets (i.e. left, right, top and bottom) rather than logical ones (i.e. inline, block, start and end). Obviously if you want to set the same value for all four sides, as in the example above, it doesn’t matter.

inset: 10px 20px 5px 8px; /* shorthand for physical properties not logical properties  */

Text alignment

Logical values for text alignment enjoy great browser support and have for many years. When working in English, text-align: start is the same as text-align: left, while text-align: end is the same as text-align: right. If you set the dir attribute to rtl, they switch and text-align: start aligns text to the right.

Physical valueWriting modeEquivalent to:
startLTRleft
startRTLright
endLTRright
endRTLleft

Border radius

So far everything we’ve looked at has decent browser support. However, there are some other logical properties where support is still a work in progress, and border radius is one of them. In other words, we can set a different border-radius value for different corners of an element using logical properties, but browser support isn’t great.

Physical propertyLogical property
border-top-left-radiusborder-start-start-radius
border-top-right-radiusborder-start-end-radius
border-bottom-left-radiusborder-end-start-radius
border-bottom-right-radiusborder-end-end-radius

It’s worth noting that the spec doesn’t include shorthand properties, like border-start-radius and border-end-radius. But, like I said, we’re still in early days here, so that might be a space to watch.

Floats

Flow-relative values for logical floats have terrible browser support at the time I’m writing this. Only Firefox supports inline-start and inline-end as float values.

Physical valueLogical value
float: leftfloat: inline-start
float: rightfloat: inline-end
clear: leftclear: inline-start
clear: rightclear: inline-end

Other logical properties

There are proposed logical properties for overflow and resize, but they currently have horrendous browser support.

PhysicalLogical
resize: verticalresize: block
resize: horizontalresize: inline
overflow-yoverflow-block
overflow-xoverflow-inline

Digging deeper

We explored what it means for a property to be considered “logical” and then mapped out all of the new logical properties and values to their physical counterparts. That’s great! But if you want to go even deeper into CSS Logical Properties and Values, there are a number of resources worth checking out.

  • “RTL Styling 101” (Ahmad Shadeed): A great resource if you’re dealing with Arabic or other right-to-left languages. Ahmad covers everything, from logical properties to considerations when working with specific layout techniques, like flexbox and grid.
  • text-combine-upright (CSS-Tricks): If you’re dealing with vertical text, did you know that this property can rotate text and squeeze multiple characters into the space of a single character? It’s a nice touch of refinement in specific situations where some characters need to go together but still flow with a vertical writing mode.

If you want to view some nice real-world examples of vertical typography from across the web, take a look at the Web Awards for Horizontal and Vertical Writings. There’s a lot of great stuff in there.

Wrapping up

Do you need to rush and swap all of the physical properties out of your codebase? Nope. But it also doesn’t hurt to start using logical properties and values in your work. As we’ve seen, browser support is pretty much there. And even if you’re working on a site that’s just in English, there’s no reason to not use them.