What is postcss-logical?
The postcss-logical npm package is a PostCSS plugin that allows developers to use logical, rather than physical, property mappings in their CSS. This is particularly useful for writing styles that adapt to different writing modes, such as left-to-right (LTR) and right-to-left (RTL) languages. It transforms logical properties and values into their equivalent directional syntax.
What are postcss-logical's main functionalities?
Logical Properties Conversion
Converts logical properties like 'margin-inline-start' to 'margin-left' or 'margin-right' depending on the direction of the text. This is useful for supporting both LTR and RTL layouts with the same CSS.
/* Input CSS */
:root {
margin-inline-start: 10px;
}
/* Output CSS */
:root {
margin-left: 10px; /* in LTR */
margin-right: 10px; /* in RTL */
}
Logical Values Conversion
Handles logical values such as 'border-inline' which are transformed into 'border-left' or 'border-right'. This feature simplifies the development of cross-directional styles.
/* Input CSS */
:root {
border-inline: 1px solid black;
}
/* Output CSS */
:root {
border-left: 1px solid black; /* in LTR */
border-right: 1px solid black; /* in RTL */
}
Other packages similar to postcss-logical
postcss-dir-pseudo-class
This package also facilitates writing directional CSS by providing a way to define styles for different directions using :dir() pseudo-class. It is similar to postcss-logical but focuses more on pseudo-classes rather than property conversions.
rtlcss
RTL CSS is a framework for transforming LTR CSS to RTL. It's more comprehensive than postcss-logical as it includes a wider range of transformations and configurations, making it suitable for complex RTL adaptations.
PostCSS Logical Properties and Values 
npm install postcss-logical --save-dev
PostCSS Logical Properties and Values lets you use logical, rather than physical, direction and dimension mappings in CSS, following the CSS Logical Properties and Values specification.
.element {
block-size: 100px;
max-inline-size: 400px;
inline-size: 200px;
padding-block: 10px 20px;
margin-inline: auto;
border-block-width: 2px;
border-block-style: solid;
}
.element {
height: 100px;
max-width: 400px;
width: 200px;
padding-top: 10px;
padding-bottom: 20px;
margin-left: auto;
margin-right: auto;
border-top-width: 2px;
border-bottom-width: 2px;
border-top-style: solid;
border-bottom-style: solid;
}
Usage
Add PostCSS Logical Properties and Values to your project:
npm install postcss postcss-logical --save-dev
Use it as a PostCSS plugin:
const postcss = require('postcss');
const postcssLogical = require('postcss-logical');
postcss([
postcssLogical()
]).process(YOUR_CSS );
Options
blockDirection
and inlineDirection
The blockDirection
and inlineDirection
options allow you to specify the direction of the block and inline axes. The default values are top-to-bottom
and left-to-right
respectively, which would match any latin language.
You should tweak these values so that they are specific to your language and writing mode.
postcssLogical({
blockDirection: 'right-to-left',
inlineDirection: 'top-to-bottom'
})
.element {
block-size: 100px;
max-inline-size: 400px;
inline-size: 200px;
padding-block: 10px 20px;
margin-inline: auto;
border-block-width: 2px;
border-block-style: solid;
}
.element {
width: 100px;
max-height: 400px;
height: 200px;
padding-right: 10px;
padding-left: 20px;
margin-top: auto;
margin-bottom: auto;
border-right-width: 2px;
border-left-width: 2px;
border-right-style: solid;
border-left-style: solid;
}
Each direction must be one of the following:
top-to-bottom
bottom-to-top
left-to-right
right-to-left
You can't mix two vertical directions or two horizontal directions so for example top-to-bottom
and right-to-left
are valid, but top-to-bottom
and bottom-to-top
are not.
Please do note that text-align
won't be transformed if inlineDirection
becomes vertical.
ignoreCustomProperties
The ignoreCustomProperties
option allows you to ignore any properties containing var()
.
postcss-logical
assumes that all custom properties are single value (e.g. --foo: 10px;
) and will assign these to physical properties as fallbacks for logical properties.
This will produce broken declarations when your custom properties contain multiple values instead (e.g. --foo: 1px 2px;
).
:root {
--inset-a: 10px;
}
.foo {
inset: var(--inset-a);
}
:root {
--inset-b: 1px 2px 3px 4px;
}
.bar {
inset: var(--inset-b);
}
:root {
--inset-a: 10px;
}
.foo {
top: var(--inset-a);
right: var(--inset-a);
bottom: var(--inset-a);
left: var(--inset-a);
}
:root {
--inset-b: 1px 2px 3px 4px;
}
.bar {
top: var(--inset-b);
right: var(--inset-b);
bottom: var(--inset-b);
left: var(--inset-b);
}
With ignoreCustomProperties
set to true
:
:root {
--inset-a: 10px;
}
.foo {
inset: var(--inset-a);
}
:root {
--inset-b: 1px 2px 3px 4px;
}
.bar {
inset: var(--inset-b);
}
:root {
--inset-a: 10px;
}
.foo {
inset: var(--inset-a);
}
:root {
--inset-b: 1px 2px 3px 4px;
}
.bar {
inset: var(--inset-b);
}