CSS logical properties provide a powerful way to create layouts that automatically adapt to different writing modes and text directions. If you're building websites that need to support multiple languages, especially those with right-to-left (RTL) writing systems like Arabic or Hebrew, logical properties will revolutionize your workflow.
The Problem with Physical Properties
Traditionally, CSS has relied on physical properties that are tied to specific directions:
margin-left
,margin-right
padding-top
,padding-bottom
border-left
,border-right
text-align: left
,text-align: right
These properties work fine for left-to-right (LTR) languages like English, but they become problematic when building sites that need to support RTL languages. Developers often end up maintaining separate stylesheets or using complex mixins to handle the direction switching.
Enter Logical Properties
CSS logical properties replace these physical directions with logical ones that automatically adapt based on the text direction and writing mode:
- Instead of left/right, we use start/end
- Instead of top/bottom, we use block-start/block-end
This means your layouts will automatically flip when the text direction changes, without requiring separate stylesheets or complex overrides.
Block vs. Inline
To understand logical properties, you need to grasp two key concepts:
- Block dimension: The dimension perpendicular to the flow of text (usually vertical in English)
- Inline dimension: The dimension parallel to the flow of text (usually horizontal in English)
In an LTR language like English:
- inline-start = left
- inline-end = right
- block-start = top
- block-end = bottom
In an RTL language like Arabic:
- inline-start = right
- inline-end = left
- block-start = top
- block-end = bottom
Practical Examples
Margins and Padding
Instead of:
.element {
margin-left: 1rem;
padding-right: 2rem;
}
Use:
.element {
margin-inline-start: 1rem;
padding-inline-end: 2rem;
}
Borders
Instead of:
.element {
border-left: 1px solid #333;
border-top-right-radius: 4px;
}
Use:
.element {
border-inline-start: 1px solid #333;
border-start-end-radius: 4px;
}
Text Alignment
Instead of:
.element {
text-align: left;
}
Use:
.element {
text-align: start;
}
Positioning
Instead of:
.element {
left: 0;
right: auto;
}
Use:
.element {
inset-inline-start: 0;
inset-inline-end: auto;
}
Shorthand Properties
CSS logical properties also include helpful shorthand properties:
.element {
/* Apply to all sides */
margin-block: 1rem; /* top and bottom */
margin-inline: 2rem; /* left and right in LTR */
/* Apply to individual sides */
margin-block-start: 1rem; /* top in horizontal writing mode */
margin-block-end: 2rem; /* bottom in horizontal writing mode */
margin-inline-start: 1rem; /* left in LTR, right in RTL */
margin-inline-end: 2rem; /* right in LTR, left in RTL */
}
Handling Width and Height
For width and height, we use inline-size and block-size:
.element {
/* Instead of width: 200px; */
inline-size: 200px;
/* Instead of height: 100px; */
block-size: 100px;
/* Instead of min-width and max-width */
min-inline-size: 100px;
max-inline-size: 300px;
}
Setting Up the Document Direction
To enable RTL support, you need to set the direction on your HTML element:
<html dir="rtl" lang="ar">
<!-- RTL content here -->
</html>
Or dynamically with CSS:
html[dir="rtl"] {
direction: rtl;
}
Real-World Use Case: Building a Card Component
Let's build a simple card component that works in both LTR and RTL contexts:
.card {
display: flex;
flex-direction: row;
border-radius: 8px;
overflow: hidden;
}
.card__image {
inline-size: 120px;
block-size: auto;
}
.card__content {
padding-block: 1rem;
padding-inline: 1.5rem;
border-inline-start: 4px solid #3498db;
}
.card__title {
margin-block-end: 0.5rem;
text-align: start;
}
.card__button {
margin-inline-start: auto;
padding-inline: 1rem;
}
This card will automatically adapt to RTL languages without any additional code.
Handling Float and Clear
For floating elements, use logical values:
.element {
/* Instead of float: left; */
float: inline-start;
/* Instead of clear: right; */
clear: inline-end;
}
Logical Properties in Grid and Flexbox
When working with Grid and Flexbox, you can use logical properties for alignment:
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
justify-content: start; /* Instead of left */
align-content: flex-start; /* This remains the same */
}
.flex-container {
display: flex;
justify-content: flex-start; /* This remains the same */
align-items: flex-start; /* This remains the same */
}
Browser Support
Logical properties have excellent browser support:
- Chrome 89+
- Firefox 68+
- Safari 15+
- Edge 89+
For older browsers, you can use a combination of logical properties with physical fallbacks:
.element {
/* Fallback for older browsers */
margin-left: 1rem;
/* Modern browsers will use this */
margin-inline-start: 1rem;
}
Conclusion
CSS logical properties are a game-changer for international websites. By embracing them, you can:
- Write cleaner, more maintainable CSS
- Support multiple writing modes and directions with a single codebase
- Create truly internationalized layouts that respect the user's language
As the web becomes increasingly global, logical properties are becoming an essential part of a modern CSS developer's toolkit. Start incorporating them into your projects today to build more adaptable and inclusive web experiences.