0
# PostCSS Nesting
1
2
PostCSS Nesting is a PostCSS plugin that enables CSS nesting functionality, allowing developers to nest style rules inside each other following the CSS Nesting specification. It transforms nested CSS into standard CSS that browsers can understand, providing Sass-like nesting capabilities while adhering to web standards.
3
4
## Package Information
5
6
- **Package Name**: postcss-nesting
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install postcss-nesting --save-dev`
10
- **Peer Dependencies**: `postcss ^8.4` (install separately: `npm install postcss --save-dev`)
11
12
## Core Imports
13
14
```typescript
15
import postcssNesting from "postcss-nesting";
16
```
17
18
For CommonJS:
19
20
```javascript
21
const postcssNesting = require("postcss-nesting");
22
```
23
24
## Basic Usage
25
26
```typescript
27
import postcss from "postcss";
28
import postcssNesting from "postcss-nesting";
29
30
// Basic usage with default 2024-02 edition
31
const processor = postcss([
32
postcssNesting()
33
]);
34
35
const result = await processor.process(css, { from: "input.css", to: "output.css" });
36
37
// With options (2021 edition supports options)
38
const processorWithOptions = postcss([
39
postcssNesting({
40
edition: '2021',
41
noIsPseudoSelector: true,
42
silenceAtNestWarning: true
43
})
44
]);
45
46
// Note: 2024-02 edition ignores options except 'edition'
47
const processor2024 = postcss([
48
postcssNesting({
49
edition: '2024-02'
50
// Other options are ignored in 2024-02 edition
51
})
52
]);
53
```
54
55
Example CSS transformation:
56
57
```css
58
/* Input */
59
.foo {
60
color: red;
61
62
&:hover {
63
color: green;
64
}
65
66
> .bar {
67
color: blue;
68
}
69
70
@media (prefers-color-scheme: dark) {
71
color: cyan;
72
}
73
}
74
75
/* Output (2024-02 edition) */
76
.foo {
77
color: red;
78
}
79
.foo:hover {
80
color: green;
81
}
82
.foo > .bar {
83
color: blue;
84
}
85
@media (prefers-color-scheme: dark) {
86
.foo {
87
color: cyan;
88
}
89
}
90
```
91
92
## Capabilities
93
94
### Plugin Creator Function
95
96
Creates a postcss-nesting plugin instance with specified options.
97
98
```typescript { .api }
99
/**
100
* Creates a postcss-nesting plugin instance
101
* @param opts - Plugin configuration options
102
* @returns PostCSS plugin instance
103
*/
104
function postcssNesting(opts?: pluginOptions): PostCSSPlugin;
105
106
// Returns a PostCSS plugin object with the following structure:
107
// {
108
// postcssPlugin: 'postcss-nesting',
109
// Rule(rule, { result }) { /* processing logic */ },
110
// AtRule?: { nest(rule) { /* @nest handling */ } }
111
// }
112
```
113
114
The plugin function has a `postcss` property set to `true` to indicate PostCSS compatibility:
115
116
```typescript { .api }
117
postcssNesting.postcss = true;
118
```
119
120
### Plugin Options
121
122
Configuration options for the postcss-nesting plugin.
123
124
```typescript { .api }
125
interface pluginOptions {
126
/** The implementation edition for CSS Nesting, defaults to '2024-02' */
127
edition?: '2021' | '2024-02';
128
/** Avoid the :is() pseudo class (2021 edition only) */
129
noIsPseudoSelector?: boolean;
130
/** Silence the @nest warning (2021 edition only) */
131
silenceAtNestWarning?: boolean;
132
}
133
```
134
135
### Edition-Specific Options
136
137
Options available for the 2021 edition:
138
139
```typescript { .api }
140
interface pluginOptions2021 {
141
/** Avoid the :is() pseudo class as much as possible, default: false */
142
noIsPseudoSelector?: boolean;
143
/** Silence the @nest warning */
144
silenceAtNestWarning?: boolean;
145
}
146
```
147
148
Options for the 2024-02 edition:
149
150
```typescript { .api }
151
interface pluginOptions2024_02 {
152
/** @deprecated This option was removed. You must migrate your CSS to the latest specification to continue using this plugin. */
153
noIsPseudoSelector?: boolean;
154
}
155
```
156
157
## CSS Nesting Editions
158
159
The plugin supports two specification editions with different behaviors:
160
161
### 2024-02 Edition (Default)
162
163
The current specification implementation:
164
165
- Uses `:is()` pseudo-class in generated CSS (required for correct specificity)
166
- At-rules are not combined with the `and` keyword
167
- `@nest` syntax is removed and will throw an error
168
- Declarations and nested rules are not reordered
169
- Options are ignored (except `edition` for switching between editions)
170
171
```typescript
172
postcssNesting({
173
edition: '2024-02' // default
174
})
175
176
// In 2024-02 edition, the plugin creator ignores options
177
postcssNesting() // equivalent to above
178
```
179
180
### 2021 Edition (Legacy)
181
182
Legacy specification implementation for backward compatibility:
183
184
- Optional `:is()` pseudo-class usage (can be disabled with `noIsPseudoSelector`)
185
- Supports `@nest` syntax with optional warning suppression
186
- Reorders declarations and nested rules
187
188
```typescript
189
postcssNesting({
190
edition: '2021',
191
noIsPseudoSelector: true, // avoid :is() when possible
192
silenceAtNestWarning: true // suppress @nest warnings
193
})
194
```
195
196
## Advanced Usage Examples
197
198
### Specificity Control (2021 Edition)
199
200
```typescript
201
// Without noIsPseudoSelector (maintains specification compliance)
202
postcssNesting({ edition: '2021' })
203
204
// CSS Input:
205
// #alpha, .beta {
206
// &:hover { order: 1; }
207
// }
208
// Output: :is(#alpha,.beta):hover { order: 1; }
209
210
// With noIsPseudoSelector (non-standard specificity)
211
postcssNesting({
212
edition: '2021',
213
noIsPseudoSelector: true
214
})
215
216
// Same Input
217
// Output: #alpha:hover, .beta:hover { order: 1; }
218
```
219
220
### Error Handling
221
222
The plugin throws errors for invalid configurations:
223
224
```typescript
225
// Invalid edition throws error
226
try {
227
postcssNesting({ edition: 'invalid' });
228
} catch (error) {
229
console.log(error.message); // "Invalid edition: invalid"
230
}
231
232
// @nest usage in 2024-02 edition throws error
233
// CSS: @nest .foo & { color: red; }
234
// Error: "`@nest` was removed from the CSS Nesting specification and will be removed from PostCSS Nesting in the next major version."
235
```
236
237
## Type Definitions
238
239
Complete TypeScript type definitions are provided:
240
241
```typescript { .api }
242
import type { PluginCreator } from 'postcss';
243
244
// Main plugin creator function
245
declare const creator: PluginCreator<pluginOptions>;
246
// Plugin creator has postcss property set to true
247
creator.postcss = true;
248
249
export default creator;
250
251
export declare type pluginOptions = {
252
edition?: '2021' | '2024-02';
253
} & pluginOptions2021 & pluginOptions2024_02;
254
255
export declare type pluginOptions2021 = {
256
noIsPseudoSelector?: boolean;
257
silenceAtNestWarning?: boolean;
258
};
259
260
export declare type pluginOptions2024_02 = {
261
/** @deprecated */
262
noIsPseudoSelector?: boolean;
263
};
264
```
265
266
## Integration Examples
267
268
### With PostCSS CLI
269
270
```bash
271
postcss input.css -o output.css -u postcss-nesting
272
```
273
274
### With Webpack
275
276
```javascript
277
module.exports = {
278
module: {
279
rules: [
280
{
281
test: /\.css$/,
282
use: [
283
'style-loader',
284
'css-loader',
285
{
286
loader: 'postcss-loader',
287
options: {
288
postcssOptions: {
289
plugins: [
290
require('postcss-nesting')({
291
edition: '2024-02'
292
})
293
]
294
}
295
}
296
}
297
]
298
}
299
]
300
}
301
};
302
```
303
304
### With Next.js
305
306
```javascript
307
// next.config.js
308
module.exports = {
309
webpack: (config) => {
310
config.module.rules.push({
311
test: /\.css$/,
312
use: [
313
'style-loader',
314
'css-loader',
315
{
316
loader: 'postcss-loader',
317
options: {
318
postcssOptions: {
319
plugins: [
320
require('postcss-nesting')()
321
]
322
}
323
}
324
}
325
]
326
});
327
return config;
328
}
329
};
330
```