DEV Community

Javier Eguiluz
Javier Eguiluz

Posted on

Is Your CSS Logical?

Take a look at this CSS snippet. What's wrong with it?

p {
    border-top: 2px solid red;
    margin-left: 2rem;
    width: 80ch;
}
Enter fullscreen mode Exit fullscreen mode

Depending on your website audience, there are either zero or three errors. Before explaining which errors, let's set some context.

A Matter of Perspective

When you step onto a boat, you won't hear terms like "left" or "right". That's because the left/right sides of a boat depend on the observer's perspective. Instead, they use "port" and "starboard", unambigous terms that always refer to the same sides of the boat, regardless of your position or the speaker's:

The names of the main ship parts
Image created by Pearson Scott Foresman and released into the public domain. Source

The same principle applies to anatomical terms of location, which allow doctors and veterinarians to describe the location of body parts unambiguously, regardless of the relative position of the patient or doctor.

CSS Internationalization

If your web applications are used globally, you must design them to adapt to various linguistic needs. For example, languages like English and Spanish are written from left-to-right (LTR); Arabic and Hebrew are written from right-to-left (RTL); Mongolian and traditional Japanese are written from top to bottom.

So, when you use a CSS declaration like this:

p {
    margin-left: 2rem;
}
Enter fullscreen mode Exit fullscreen mode

Do you mean that (1) you want to add space to the physical left of the paragraph, or (2) you want to add some space before the content starts? For a fully internationalized UI, the correct answer is always (2).

The Logical Solution

You could create separate stylesheets for LTR and RTL languages and load them conditionally. There are even tools like the webpack-rtl plugin that can generate automatically a RTL stylesheet based on the original LTR stylesheet.

However, the best solution would be to apply CSS styles conditionally like this:

p {
    if writing is left-to-right:
        margin-left: 2rem;
    elseif writing is right-to-left:
        margin-right: 2rem;
    elseif writing is top-to-bottom:
        margin-top: 2rem;
    endif
}
Enter fullscreen mode Exit fullscreen mode

You can do this in CSS but with a much simpler syntax:

p {
    margin-inline-start: 2rem;
}
Enter fullscreen mode Exit fullscreen mode

This margin-inline-start property is a logical CSS property which dynamically adjusts based on the user's writing direction. Logical properties work similarly to the port/starboard analogy; they describe layout in a way that is unambiguous across different writing systems.

Logical properties define layout directions using these two terms:

  • inline: parallel to the flow of text within a line.
  • block: perpendicular to the flow of text within a line.

This illustration shows the logical positions compared to the physical locations for all the writing modes supported by CSS:

CSS logical properties and writing modes

Using logical properties, the initial example shown at the beginning of this aticle can be rewritten like this:

p {
    border-block-start: 2px solid red;
    margin-inline-start: 2rem;
    inline-size: 80ch;
}
Enter fullscreen mode Exit fullscreen mode

Updating an existing CSS stylesheet to use logical properties might seem daunting at first. However, most of the work involves simply replacing left with inline-start, right with inline-end, top with block-start, and bottom with block-end. Some properties require different renaming; for example, border-bottom-left-radius becomes border-end-start-radius, height becomes block-size, etc.

The effort is well worth it, as this is a future-proof solution that ensures your website is accessible to everyone. For instance, the EasyAdmin project, which I'm involved in, has already updated its stylesheets to use logical properties.

Logical Properties Reference

Here's a reference table of all the logical properties to help you update your own projects:

Physical Property Logical Property
border-bottom border-block-end
border-bottom-color border-block-end-color
border-bottom-left-radius border-end-start-radius
border-bottom-right-radius border-end-end-radius
border-bottom-style border-block-end-style
border-bottom-width border-block-end-width
border-left border-inline-start
border-left-color border-inline-start-color
border-left-style border-inline-start-style
border-left-width border-inline-start-width
border-right border-inline-end
border-right-color border-inline-end-color
border-right-style border-inline-end-style
border-right-width border-inline-end-width
border-top border-block-start
border-top-color border-block-start-color
border-top-left-radius border-start-start-radius
border-top-right-radius border-start-end-radius
border-top-style border-block-start-style
border-top-width border-block-start-width
bottom inset-block-end
container-intrinsic-height contain-intrinsic-block-size
container-intrinsic-width contain-intrinsic-inline-size
height block-size
left inset-inline-start
margin-bottom margin-block-end
margin-left margin-inline-start
margin-right margin-inline-end
margin-top margin-block-start
max-height max-block-size
max-width max-inline-size
min-height min-block-size
min-width min-inline-size
overscroll-behavior-x overscroll-behavior-inline
overscroll-behavior-y overscroll-behavior-block
overflow-x overflow-inline
overflow-y overflow-block
padding-bottom padding-block-end
padding-left padding-inline-start
padding-right padding-inline-end
padding-top padding-block-start
right inset-inline-end
top inset-block-start
width inline-size

Learn More


✨ If you enjoyed this or my other articles and want to support my work, consider sponsoring me on GitHub 🙌


Top comments (1)

Collapse
 
vigneshiyergithub profile image
vigneshiyergithub

Learnt a new perspective, thanks for sharing!