Mantine PostCSS preset
postcss-preset-mantine
provides several CSS functions and mixins to help you write styles.It is not required to use it, but highly recommended. All demos that feature stylesassume that you have this preset installed.
postcss-preset-mantine
includes the following PostCSS plugins:
- postcss-nested
- postcss-mixins with Mantine specific mixins
- Custom plugin with
em
/rem
functions
Installation
Installpostcss-preset-mantine
as a dev dependency:
yarn add --dev postcss-preset-mantine
npm install --save-dev postcss-preset-mantine
Usage
Note that setting up PostCSS may be different depending on your build tool/framework, checkadedicated framework guide to learn more.Addpostcss-preset-mantine
to yourpostcss.config.cjs
file (usually it is located in the root of your project):
module.exports = { plugins: { 'postcss-preset-mantine': {}, },};
All done! You can now use all the features of the preset.
rem/em functions
rem
andem
functions can be used to convert pixels to rem/em units.16px = 1rem
and16px = 1em
,em
values are supposed to be used in media queries,rem
everywhere else. You can learn more about units conversions inthis guide.
.demo { font-size: rem(16px); @media (min-width: em(320px)) { font-size: rem(32px); }}
Will be transformed to:
.demo { font-size: calc(1rem * var(--mantine-scale)); @media (min-width: 20em) { font-size: calc(2rem * var(--mantine-scale)); }}
Auto convert px to rem
autoRem
option can be used to automatically convert all pixel values to rem unitsin.css
files:
module.exports = { plugins: { 'postcss-preset-mantine': { autoRem: true, }, },};
This option works similar torem
function. The following code:
.demo { font-size: 16px; @media (min-width: 320px) { font-size: 32px; }}
Will be transformed to:
.demo { font-size: calc(1rem * var(--mantine-scale)); @media (min-width: 320px) { font-size: calc(2rem * var(--mantine-scale)); }}
Note thatautoRem
converts only CSS properties, values in@media
queries arenot converted automatically – you still need to useem
function to convert them.
autoRem
option does not convert values in the following cases:
- Values in
calc()
,var()
,clamp()
andurl()
functions - Values in
content
property - Values that contain
rgb()
,rgba()
,hsl()
,hsla()
colors
If you want to convert above values to rem units, userem
function manually.
dark and light mixins
dark
andlight
mixins can be used to create styles that will be applied only in dark or light color scheme.
.demo { @mixin light { color: red; } @mixin dark { color: blue; }}
Will be transformed to:
[data-mantine-color-scheme='light'] .demo { color: red;}[data-mantine-color-scheme='dark'] .demo { color: blue;}
Note that usually you do not need to use bothlight
anddark
mixins at the same time.It is easier to define styles for light color scheme and then usedark
mixin to override them in dark color scheme.
.demo { // Value for light color scheme color: red; @mixin dark { // Value for dark color scheme color: blue; }}
To define values for light/dark color scheme on the:root
/html
element, uselight-root
anddark-root
mixins instead:
:root { @mixin light-root { --color: red; } @mixin dark-root { --color: blue; }}
smaller-than and larger-than mixins
smaller-than
andlarger-than
mixins can be used to create styles that will be applied only when the screen is smaller or larger than specified breakpoint.
.demo { @mixin smaller-than 320px { color: red; } @mixin larger-than 320px { color: blue; }}
Will be transformed to:
// Breakpoint values are converted to em units// In smaller-than mixin 0.1px is subtracted from breakpoint value// to avoid intersection with larger-than mixin@media (max-width: 19.99375em) { .demo { color: red; }}@media (min-width: 20em) { .demo { color: blue; }}
You can also usesmaller-than
andlarger-than
mixins withmantine breakpoints:
.demo { @mixin smaller-than $mantine-breakpoint-sm { color: red; } @mixin larger-than $mantine-breakpoint-sm { color: blue; }}
light-dark function
light-dark
function is an alternative tolight
anddark
mixins. It accepts two arguments:first argument is rule that will be applied in light color scheme, second argument is rule that will be applied in dark color scheme.
.demo { color: light-dark(red, blue);}
Will be transformed to:
.demo { color: red;}[data-mantine-color-scheme='dark'] .demo { color: blue;}
Note thatlight-dark
function does not work on:root
/html
element. Uselight-root
anddark-root
mixins instead:
// ❌ Does not work:root { --color: light-dark(red, blue);}// ✅ Works:root { @mixin light-root { --color: red; } @mixin dark-root { --color: blue; }}
alpha function
alpha
function can be used to add alpha channel to color. Note that it usescolor-mix which is not supported in some older browsers.
.demo { color: alpha(var(--mantine-color-red-4), 0.5); border: 1px solid alpha(#ffc, 0.2);}
Will be transformed to:
.demo { color: color-mix( in srgb, var(--mantine-color-red-4), transparent 50% ); border: 1px solid color-mix(in srgb, #ffc, transparent 80%);}
lighten and darken functions
lighten
anddarken
functions work similar toalpha
function, but instead of adding alpha channel they add white or black color to the color withcolor-mix.
.demo { color: lighten(var(--mantine-color-red-4), 0.5); border: 1px solid darken(#ffc, 0.2);}
Will be transformed to:
.demo { color: color-mix(in srgb, var(--mantine-color-red-4), white 50%); border: 1px solid color-mix(in srgb, #ffc, black 20%);}
hover mixin
hover
mixin can be used to create styles that will be applied on hover.
.demo { @mixin hover { color: orange; }}
Will be transformed to:
@media (hover: hover) { .demo:hover { color: orange; }}@media (hover: none) { .demo:active { color: orange; }}
rtl/ltr mixins
rtl
mixin can be used to create styles that will be applied whendir="rtl"
is set on parent element (usually<html />
).
.demo { margin-left: 1rem; @mixin rtl { margin-left: 0; margin-right: 1rem; }}
Will be transformed to:
.demo { margin-left: 1rem;}[dir='rtl'] .demo { margin-left: 0; margin-right: 1rem;}
ltr
mixin works the same way, but fordir="ltr"
:
.demo { margin-left: 1rem; @mixin ltr { margin-left: 0; margin-right: 1rem; }}
Will be transformed to:
.demo { margin-left: 1rem;}[dir='ltr'] .demo { margin-left: 0; margin-right: 1rem;}
not-rtl/not-ltr mixins
not-rtl
/not-ltr
mixins can be used to create styles that will be applied when the direction is set to the opposite value or not set at all.For example,not-rtl
styles will be applied whendir="ltr"
or whendir
is not set at all.
.demo { @mixin not-rtl { margin-right: 1rem; }}
Will be transformed to:
:root:not([dir='rtl']) .demo { margin-right: 1rem;}
where-* mixins
where-*
mixins are alternative tolight
,dark
,rlt
andhover
mixins.They work exactly the same, but produced CSS is less specific. These mixins areuseful when you want to easily override styles, for example, when you are buildinga library or extension.
Example of usingwhere-light
mixin:
.demo { @mixin where-light { color: red; }}
Will be transformed to:
:where([data-mantine-color-scheme='light']) .demo { color: red;}
Custom mixins
You can define custom mixins that are not included in the preset by specifying themin themixins
option. To learn about mixins syntax, followpostcss-mixins documentation.
Example of addingclearfix
andcircle
mixins:
module.exports = { plugins: { 'postcss-preset-mantine': { autoRem: true, mixins: { clearfix: { '&::after': { content: '""', display: 'table', clear: 'both', }, }, circle: (_mixin, size) => ({ borderRadius: '50%', width: size, height: size, }), }, }, // ... Other plugins },};
Then you can use these mixins in your styles:
.demo { @mixin clearfix; @mixin circle 100px;}
Disable specific features
You can disable specific features of the preset by setting them tofalse
:
module.exports = { 'postcss-preset-mantine': { features: { // Turn off `light-dark` function lightDarkFunction: false, // Turn off `postcss-nested` plugin nested: false, // Turn off `lighten`, `darken` and `alpha` functions colorMixAlpha: false, // Turn off `rem` and `em` functions remEmFunctions: false, // Turn off `postcss-mixins` plugin mixins: false, }, },};