What is @csstools/postcss-cascade-layers?
@csstools/postcss-cascade-layers is a PostCSS plugin that enables the use of CSS Cascade Layers, a feature that allows developers to manage the priority of different stylesheets and style rules in a more organized and predictable manner.
What are @csstools/postcss-cascade-layers's main functionalities?
Defining Cascade Layers
This feature allows you to define and organize your CSS into different layers, which can help manage the specificity and priority of your styles.
/* Define layers */
@layer reset, base, theme, components, utilities;
/* Add styles to layers */
@layer reset {
/* Reset styles */
}
@layer base {
/* Base styles */
}
@layer theme {
/* Theme styles */
}
@layer components {
/* Component styles */
}
@layer utilities {
/* Utility styles */
}
Using Layers in Stylesheets
This feature demonstrates how to use the defined layers in your stylesheets to apply different styles to various elements, ensuring that the styles are applied in the correct order of priority.
/* Define layers */
@layer reset, base, theme, components, utilities;
/* Add styles to layers */
@layer base {
body {
font-family: Arial, sans-serif;
}
}
@layer theme {
body {
background-color: #f0f0f0;
}
}
@layer components {
.button {
padding: 10px 20px;
border: none;
}
}
@layer utilities {
.text-center {
text-align: center;
}
}
Other packages similar to @csstools/postcss-cascade-layers
postcss-preset-env
postcss-preset-env allows you to use future CSS features today by converting modern CSS into something most browsers can understand. It includes features like custom properties, nesting, and media queries, but it does not specifically focus on cascade layers like @csstools/postcss-cascade-layers.
postcss-import
postcss-import allows you to inline @import rules content with PostCSS. While it helps in managing CSS imports and dependencies, it does not provide the cascade layer functionality that @csstools/postcss-cascade-layers offers.
postcss-nested
postcss-nested unwraps nested rules like how Sass does. It helps in writing nested CSS rules but does not offer the cascade layer management that @csstools/postcss-cascade-layers provides.
PostCSS Cascade Layers
PostCSS Cascade Layers lets you use @layer
following the Cascade Layers Specification. For more information on layers, checkout A Complete Guide to CSS Cascade Layers by Miriam Suzanne.
target {
color: purple;
}
@layer {
target {
color: green;
}
}
/* becomes */
target:not(#\#) {
color: purple;
}
target {
color: green;
}
How it works
PostCSS Cascade Layers creates "layers" of specificity.
It applies extra specificity on all your styles based on :
- the most specific selector found
- the order in which layers are defined
@layer A, B;
@layer B {
.a-less-specific-selector {
}
}
@layer A {
#something #very-specific {
}
}
@layer C {
.a-less-specific-selector {
}
}
most specific selector :
#something #very-specific
[2, 0, 0]
2 + 1
-> 3
to ensure there is no overlap
the order in which layers are defined :
layer | previous adjustment | specificity adjustment | selector |
---|
A | 0 | 0 + 0 = 0 | N/A |
B | 0 | 0 + 3 = 3 | :not(#/#):not(#/#):not(#/#) |
C | 3 | 3 + 3 = 6 | :not(#/#):not(#/#):not(#/#):not(#/#):not(#/#):not(#/#) |
This approach lets more important (later) layers always override less important (earlier) layers.
And layers have enough room internally so that each selector works and overrides as expected.
More layers with more specificity will cause longer :not(...)
selectors to be generated.
⚠️ For this to work the plugin needs to analyze your entire stylesheet at once.
If you have different assets that are unaware of each other it will not work correctly as the analysis will be incorrect.
Usage
Add PostCSS Cascade Layers to your project:
npm install postcss @csstools/postcss-cascade-layers --save-dev
Use it as a PostCSS plugin:
const postcss = require('postcss');
const postcssCascadeLayers = require('@csstools/postcss-cascade-layers');
postcss([
postcssCascadeLayers()
]).process(YOUR_CSS );
PostCSS Cascade Layers runs in all Node environments, with special
instructions for:
Options
onRevertLayerKeyword
The onRevertLayerKeyword
option enables warnings if revert-layer
is used.
Transforming revert-layer
for older browsers is not possible in this plugin.
Defaults to warn
postcssCascadeLayers({ onRevertLayerKeyword: 'warn' })
/* [postcss-cascade-layers]: handling "revert-layer" is unsupported by this plugin and will cause style differences between browser versions. */
@layer {
.foo {
color: revert-layer;
}
}
onConditionalRulesChangingLayerOrder
The onConditionalRulesChangingLayerOrder
option enables warnings if layers are declared in multiple different orders in conditional rules.
Transforming these layers correctly for older browsers is not possible in this plugin.
Defaults to warn
postcssCascadeLayers({ onConditionalRulesChangingLayerOrder: 'warn' })
/* [postcss-cascade-layers]: handling different layer orders in conditional rules is unsupported by this plugin and will cause style differences between browser versions. */
@media (min-width: 10px) {
@layer B {
.foo {
color: red;
}
}
}
@layer A {
.foo {
color: pink;
}
}
@layer B {
.foo {
color: red;
}
}
onImportLayerRule
The @import
at-rule can also be used with cascade layers, specifically to create a new layer like so:
@import 'theme.css' layer(utilities);
If your CSS uses @import
with layers, you will also need the postcss-import plugin. This plugin alone will not handle the @import
at-rule.
This plugin will warn you when it detects that postcss-import did not transform@import
at-rules.
postcssCascadeLayers({ onImportLayerRule: 'warn' })
Contributors
The contributors to this plugin were Olu Niyi-Awosusi and Sana Javed from Oddbird and Romain Menke.