Million Miles Technologies

A Complete Guide to CSS Logical Properties, with Cheat Sheet — SitePoint


In this article, we’ll dive into CSS logical properties. We’ll look at what they are, how they work, and what they’re useful for. We’ll also provide a handy cheat sheet so you can easily compare CSS logical properties with their physical equivalents.

Even if you choose not to use logical properties yourself, it’s a good idea to get familiar with them, as they’re starting to appear in the code of more and more websites and online demos.

For example, you might come across this:

p {
  margin-block-start: 1em;
}

Unless you’re familiar with CSS logical properties, that probably won’t mean much to you. If you read on, you’ll soon be a logical property ninja!

Download our handy logical properties PDF cheat sheet.

What Are Logical Properties?

Logical properties offer a new way to declare properties like width and height, padding, margin, border, border radius, position, float, text alignment, and overflow. Traditionally, these properties have been declared in relation to the physical dimensions of a computer screen — left, right, top and bottom. Logical properties instead are based on the direction of text.

Some languages run from left to right, such as English. Others run from right to left, like Arabic. Others sometimes run from top to bottom, such as Japanese. Many websites have multiple versions in different languages, such as the BBC’s news site in English, Arabic and Chinese, or Al Jazeera’s site in English, Arabic and Chinese.

Having styles linked to the direction of text offers a number of advantages, as they can adapt to changes in text direction and thus apply across all versions of a site.

Understanding text direction

To better grasp the purpose of logical properties, we really need to understand a few things about text direction.

We can specify the direction of text in both HTML and CSS.

HTML has the dir attribute, which specifies whether text runs from left to right across the page (dir="ltr"), right to left (dir="rtl"), or whether the browser should make up its own mind based on the language being used (dir="auto"). The dir attribute can be applied to the whole document (the norm if the whole document uses the same language) or to an individual element.

Instead of using the dir attribute in HTML, we can use the direction property in CSS. To specify left-to-right text, use direction: ltr, and for right-to-left text, use direction: rtl.

It doesn’t really matter whether we set text direction in HTML or CSS, although it’s often recommended that we use the dir attribute in HTML, as that ensures text will run in the correct direction even if something goes wrong with our style sheet.

We can also use CSS to specify that text runs from top to bottom. For vertical text that runs from left to right, we use writing-mode: vertical-lr, and for vertical text that runs from right to left, we use writing-mode: vertical-rl. (There’s no dir option for vertical text.)

In this article, we’ll look at a series of demos that compare the effects of physical and logical CSS properties. These demos will illustrate the direction of text using a paragraph consisting of emojis — a sort of universal language!

In the Pen below, we have four boxes containing our emoji sentence. The first is set to dir="ltr" (the browser default), the second to dir="rtl", the third to writing-mode: vertical-lr, and the fourth to writing-mode: vertical-rl.

In this demo, you can see how the text-direction settings affect the order of the characters in the paragraph.

Aside: see how the rows line up nicely in the demo above? That’s thanks to the new subgrid value in CSS Grid. We covered how to line up rows with subgrid in our recent quick tip.

Understanding block and inline in CSS

As CSS grows and develops, the focus is less on things that go left, right, up and down on a screen, and more on the flow of content. You may be familiar with the main and cross axes in Flexbox, for example, which vary depending on the direction in which text flows, as does the direction of Grid content.

The CSS block and inline properties are determined by the direction of text. In the image below, block and inline direction varies depending on the direction of the text.

Block and inline directions are shown to vary depending on the direction of the text

For a paragraph that runs left to right, like this one, the inline direction is left/right, and the block direction is up/down.

Logical properties are set in terms of block and inline dimensions, which automatically swap around as text direction changes. This makes them much more adaptable than physical properties.

Inline start and end are determined by where text starts and ends, as are start and end in the block direction.

inline and block directions with their start and end points

Are logical properties only for multilingual sites?

Logical properties are useful for all websites. There are plenty of situations where monolingual websites might benefit from using logical properties.

For example, you might find yourself changing the text direction of an element while using media or container queries. Imagine a heading with a left red border. On small screens, the heading might be horizontal, above the following paragraphs. On wide screens, you might set the heading to display vertically. The image below shows what would happen if you used border-left: 5px solid red on the heading.

On larger screens, the red border appears along the left of the vertical heading

Once the heading displays vertically, that left border stays on the left, when we most likely want it at the start of the text. Using logical properties, we can instead specify that the red border appears at the inline start of the heading (border-inline-start), no matter what direction it’s pointing in, producing the result pictured below.

Now on small and large screens, the red border appears at the inline start of the text, whether it’s horizontal or vertical

(You can check out a live demo of this on CodePen.)

This shows how, with logical properties, our layout is more adaptable to change without having to add extra CSS for different scenarios.

In addition to this, we’ll also see that logical properties offer a number of useful shorthands that help make CSS coding more efficient for everyone — whether working with multiple languages or not.

Size (Width and Height Dimensions)

Instead of width and height, which are based on the physical screen, logical properties use inline-size and block-size. To decide which to use to set width and height, we have to know what direction the text will go in.

In the demo below, the paragraphs in the first row have been given a block-size of 80px. In each case, the 80px is set on the block direction, whichever that may be.

Compare this with the second row of paragraphs, which are each set to height: 80px. In each case, the height is set in relation to the screen.

Other size properties include:

  • max-inline-size
  • min-inline-size
  • max-block-size
  • min-block-size

See the cheat sheet for all size options and how to use them with each text direction, along with browser support information.

Margin

Using logical properties, margin is set with variations of margin-inline and margin-block.

For left-to-right languages, margin-inline-start: 40px will apply a margin at the start of the text (on the left of the screen). When applied to a right-to-left language, that margin will appear on the right of the screen. For vertical text, the margin will appear at the top, as shown in the demo below.

Compare the effect of margin-inline-start applied to each paragraph in the first row with the margin-left: 40px applied to each paragraph in the second row in the demo below.

Other margin properties include:

  • margin-inline-end
  • margin-block-start
  • margin-block-end
  • margin-inline
  • margin-block

Note that margin-inline can be used as shorthand for margin-left and margin-right, which comes in very handy in a lot of situations — such as margin-inline: auto.

See the cheat sheet for all margin options and browser support information.

Padding

Using logical properties, padding is set with variations of padding-inline and padding-block.

For left-to-right languages, padding-block-start: 40px will apply padding at the top of the text (on the top of the screen). When applied to a right-to-left language, that padding will also appear on the top of the screen. For vertical text, the padding will appear on the left or right, depending on its horizontal direction.

Compare the effect of padding-block-start in the first row with the padding-top: 40px applied to each paragraph in the second row in the demo below.

Other padding properties include:

  • padding-inline-start
  • padding-inline-end
  • padding-block-end
  • padding-inline
  • padding-block

Note that padding-inline can be used as shorthand for padding-left and padding-right.

See the cheat sheet for all padding options, in each text direction, along with browser support details.

Inset (Positioned Elements)

Have you come across the very handy inset property? It’s used for positioning elements (such as when you’re using position: absolute). For example, inset: 0 is shorthand for top: 0; right: 0; bottom: 0; left: 0;.

Let’s try this out in our emoji demo. The containing divs are set to position: relative and the paragraphs are set to position: absolute. The paragraphs in the first row are set to inset-block-end: 30px, while those in the second row are set physically to bottom: 30px.

Other properties for inset include:

  • inset-block-start
  • inset-block
  • inset-inline-start
  • inset-inline-end
  • inset-inline

Note the convenient shorthand inset-block and inset-inline, which can be used in just two directions. (inset-block: 20px is equivalent to inset: 20px auto. See a simple demo here.)

View the full list of inset properties and how they work with text direction in the cheat sheet.

Borders

We can set a border all around an element with the border shorthand, such as border: 5px solid red. But if we just want to style particular sides of an element, we’re suddenly dealing with border-top, border-bottom, border-left and border-right, for which there are logical equivalents.

Borders are a little more involved, because they involve three values — width (the thickness of the border), style (solid, dotted, and so on), and color.

Let’s see what happens when we apply border-inline-start: 5px solid red to our paragraphs, and compare that with border-left: 5px solid red;.

Other logical properties for border include:

  • border-inline-end
  • border-block-start
  • border-block-end
  • border-inline
  • border-block

Notice that border-inline is a nice shorthand for border:left and border-right in left-to-right flow, and border-block for border-top and border-bottom.

We can drill down further into border logical properties to target just a single value. For width we have these:

  • border-block-start-width
  • border-block-end-width
  • border-block-width
  • border-inline-start-width
  • border-inline-end-width
  • border-inline-width

For style we have these:

  • border-block-start-style
  • border-block-end-style
  • border-block-style
  • border-inline-start-style
  • border-inline-end-style
  • border-inline-style

For color we have these:

  • border-block-start-color
  • border-block-end-color
  • border-block-color
  • border-inline-start-color
  • border-inline-end-color
  • border-inline-color

Check out the cheat sheet for all the combinations and permutations of these properties as they apply to each text direction.

Border Radius

We can set a border radius to all corners of an element with the border-radius property. If we’re targeting individual corners with physical properties, we first consider whether it’s at the top or bottom of the element, and then whether it’s on the left or right of the element. So the top left corner is specified with border-top-left-radius.

When setting border radius with logical properties, instead of top/bottom-left/right, we need to think about block[start/end]-inline[start-end].

That is, to choose the right property for a particular corner, you have to ask yourself whether it’s at the start or end of the element’s block direction and whether it’s at the start or end of the element’s inline direction, giving four possible options in the middle:

-start-start-
-end-start-
-start-end-
-end-end-

In the first row of the following demo, we’re setting a border radius of 20px at the start of the block and inline text directions with border-start-start-radius. Compare that with border-top-left-radius in the second row.

There aren’t any special shorthands here, so if you want to round two corners, you have to do something like this:

border-start-start-radius: 20px;
border-end-start-radius: 20px;

Oh well! (See a demo of that here.)

See the cheat sheet for all border radius options and browser support information. It took longer for border radius logical properties to be supported by browsers, but support is now good in modern browsers.

Floating and Clearing

Logical properties for float and clear offer new options for how to float and clear an element. Before logical properties, the only options were float: left and float: right, clear: left, and clear: right. Where text was vertical, there was no option to float in the same direction as the text.

With logical properties, floating and clearing can now be done specifically in relation to the inline flow of text, thanks to inline-start and inline-end.

In the demo below, a span element is floated with the logical value inline-start, compared with the physical value left in the second row.

The inline-start and inline-end values also apply to the clear property. (Here’s a CodePen demo of that.)

There’s no need for a logical alternative for clear: both, because it already clears in both inline directions — which is quite logical!

Text Alignment

We already have text alignment values like left, right, center, and justify. Two logical values have now also been added: start and end. They can be used to align text along the inline axis, no matter what direction it runs in.

In the demo below, the paragraphs in the first row have been set to text-align: end. As you can see, the emojis are all pushed to the far end of the inline axis.

The cheat sheet shows how to apply start and end values to work with the various text directions.

Resizing

The resize property allows for resizing certain elements in specified directions, and now there are inline and block options.

The demo below shows the difference between resize: inline and resize: horizontal. (There’s a tiny resize handle at the bottom right corner of each box that you can drag.)

(In the demo above, the resizing for the right-to-left box is a bit wild because dir="rtl" isn’t being applied to the whole document but just to the containing div.)

Overflow

The physical properties of overflow-x and overflow-y now have logical complements of overflow-inline and overflow-block.

Note that there’s very little support for these new properties at the time of writing (April 2024).

The overscroll-behavior property is a new one that refines how overflowing elements scroll. We won’t delve into it here, but you can read more on MDN.

Suffice it to say that there are logical versions of these properties as well as physical. For example, overscroll-behavior-x for left-to-right languages can be replaced by overscroll-behavior-inline, and so on. (See the cheat sheet for a full list of examples.)

Browser Support

Browser support for CSS logical properties advanced rapidly in the early 2020s, and logical properties are now strongly supported across the major browsers.

Logical properties carry the same weight as their physical counterparts, so if you’re worried about the experience in older browsers, you could declare two values, like so:

blockquote {
  border-left: 5px solid red;
  border-inline-start: 5px solid red;
}

Older browsers will use the first declaration, while newer ones will use the second.

However, it would be tedious to duplicate code like this throughout a style sheet, so if you really are worried about older browsers, perhaps go easy on logical properties for now.

Caniuse has an overview of logical property support, and each section in the cheat sheet also has links to support for specific properties.

Conclusion

In this article, we’ve covered almost every logical property that’s currently available. (You can also check out logical properties for caption-side and for size containment if you want to go further.)

If nothing else, it’s worth understanding what logical properties are and how to use them, even if you choose not to use them for now. At least you’ll understand the new CSS logical property code that’s appearing all over the Web now.

Logical properties do offer benefits, even if you’re not working on multilingual sites. The various shorthands like margin-inline are very useful and are nice tools to have in your kit.

If you’ve read right through this article, you should be able to recognize logical properties wherever they appear. (Look out for those block and inline keywords!) Hopefully you’re also confident enough to use them occasionally in your CSS — unless you’ve been inspired to go full ninja!

Don’t forget to download our handy logical properties PDF cheat sheet.

Related blogs