Transforms CSS declaration values and at-rule parameters into abstract syntax trees with traversal API
npx @tessl/cli install tessl/npm-postcss-value-parser@4.2.00
# PostCSS Value Parser
1
2
PostCSS Value Parser transforms CSS declaration values and at-rule parameters into abstract syntax trees (AST) with a simple traversal API. It provides comprehensive CSS value parsing for build tools, PostCSS plugins, and applications requiring detailed CSS value analysis.
3
4
## Package Information
5
6
- **Package Name**: postcss-value-parser
7
- **Package Type**: npm
8
- **Language**: JavaScript with TypeScript definitions
9
- **Installation**: `npm install postcss-value-parser`
10
11
## Core Imports
12
13
```javascript
14
const valueParser = require('postcss-value-parser');
15
```
16
17
For ES modules:
18
19
```javascript
20
import valueParser from 'postcss-value-parser';
21
```
22
23
## Basic Usage
24
25
```javascript
26
const valueParser = require('postcss-value-parser');
27
28
// Parse a CSS value
29
const cssValue = 'rgba(233, 45, 66, .5) no-repeat center/contain';
30
const parsed = valueParser(cssValue);
31
32
// Walk through all nodes
33
parsed.walk(function(node) {
34
if (node.type === 'function' && node.value === 'rgba') {
35
// Transform rgba() to hex
36
const values = node.nodes.filter(n => n.type === 'word').map(n => n.value);
37
node.type = 'word';
38
node.value = '#E92D42';
39
}
40
});
41
42
// Convert back to CSS string
43
console.log(parsed.toString()); // "#E92D42 no-repeat center/contain"
44
```
45
46
## Architecture
47
48
PostCSS Value Parser is built around a tree-based parsing approach:
49
50
- **Parser**: Converts CSS values into node trees with precise source mapping
51
- **Node System**: Seven node types representing different CSS value components (word, string, function, etc.)
52
- **Tree Walker**: Recursive traversal system supporting both forward and reverse walking
53
- **Stringifier**: Converts parsed trees back to CSS with optional custom transformations
54
- **Utility Functions**: CSS dimension parsing and static utility methods
55
56
## Capabilities
57
58
### Value Parsing
59
60
Main parser function that converts CSS values into traversable node trees.
61
62
```javascript { .api }
63
/**
64
* Parse a CSS value into a series of nodes
65
* Can be called as function or constructor
66
* @param value - The CSS value string to parse
67
* @returns ParsedValue instance with nodes array and methods
68
*/
69
function valueParser(value: string): ParsedValue;
70
71
/**
72
* Constructor form of the parser
73
* @param value - The CSS value string to parse
74
* @returns ParsedValue instance
75
*/
76
new valueParser(value: string): ParsedValue;
77
78
interface ParsedValue {
79
/** Array of parsed nodes */
80
nodes: Node[];
81
/** Convert parsed nodes back to CSS string */
82
toString(): string;
83
/** Walk all parsed nodes with callback function */
84
walk(callback: WalkCallback, bubble?: boolean): this;
85
}
86
```
87
88
**Usage Examples:**
89
90
```javascript
91
// Parse background shorthand - both patterns work
92
const parsed1 = valueParser('url(bg.jpg) no-repeat 50% 75%');
93
const parsed2 = new valueParser('url(bg.jpg) no-repeat 50% 75%');
94
console.log(parsed1.nodes.length); // 7 nodes
95
96
// Parse function with parameters
97
const rgba = valueParser('rgba(255, 0, 128, 0.5)');
98
console.log(rgba.nodes[0].type); // 'function'
99
console.log(rgba.nodes[0].value); // 'rgba'
100
console.log(rgba.nodes[0].nodes.length); // 7 (4 values + 3 dividers)
101
```
102
103
### Tree Walking
104
105
Traverse the parsed node tree with visitor callbacks, supporting both depth-first and reverse traversal.
106
107
```javascript { .api }
108
/**
109
* Walk all parsed nodes, applying callback function
110
* @param callback - Visitor function called for each node
111
* @param bubble - When true, traverse inside-out instead of outside-in
112
* @returns this (chainable)
113
*/
114
walk(callback: WalkCallback, bubble?: boolean): this;
115
116
/**
117
* Static walk function for node arrays
118
* @param nodes - Array of nodes to walk
119
* @param callback - Visitor function called for each node
120
* @param bubble - When true, traverse inside-out instead of outside-in
121
*/
122
function walk(nodes: Node[], callback: WalkCallback, bubble?: boolean): void;
123
124
interface WalkCallback {
125
/**
126
* @param node - Current node being visited
127
* @param index - Index of node in parent's nodes array
128
* @param nodes - Parent's complete nodes array
129
* @returns Returning false prevents traversal of descendant nodes (only when bubble=false)
130
*/
131
(node: Node, index: number, nodes: Node[]): void | boolean;
132
}
133
```
134
135
**Usage Examples:**
136
137
```javascript
138
// Find and modify all function calls
139
parsed.walk(function(node) {
140
if (node.type === 'function') {
141
console.log(`Found function: ${node.value}`);
142
// Modify function name
143
node.value = 'new-' + node.value;
144
}
145
});
146
147
// Shallow walk (don't traverse into functions)
148
parsed.walk(function(node) {
149
console.log(node.type);
150
if (node.type === 'function') {
151
return false; // Skip function contents
152
}
153
}, false);
154
155
// Reverse traversal (inside-out)
156
parsed.walk(function(node) {
157
console.log(node.value);
158
}, true);
159
```
160
161
### String Conversion
162
163
Convert parsed node trees back to CSS strings with optional custom stringification.
164
165
```javascript { .api }
166
/**
167
* Convert parsed nodes back to CSS string
168
* @returns Reconstructed CSS value string
169
*/
170
toString(): string;
171
172
/**
173
* Static stringify function for nodes
174
* @param nodes - Node or array of nodes to stringify
175
* @param custom - Optional custom stringifier callback
176
* @returns CSS string representation
177
*/
178
function stringify(nodes: Node | Node[], custom?: CustomStringifierCallback): string;
179
180
interface CustomStringifierCallback {
181
/**
182
* @param node - Node to stringify
183
* @returns Custom string representation, or undefined to use default
184
*/
185
(node: Node): string | undefined;
186
}
187
```
188
189
**Usage Examples:**
190
191
```javascript
192
// Basic stringification
193
const cssString = parsed.toString();
194
195
// Custom stringification
196
const customCss = valueParser.stringify(parsed.nodes, function(node) {
197
if (node.type === 'function' && node.value === 'rgb') {
198
// Convert rgb() to hex
199
return '#FF0000';
200
}
201
// Return undefined to use default stringification
202
});
203
```
204
205
### CSS Dimension Parsing
206
207
Parse CSS values containing numbers and units into separate components.
208
209
```javascript { .api }
210
/**
211
* Parse CSS dimension into numeric and unit parts
212
* @param value - CSS dimension string (e.g., "2rem", "100px", "1.5em")
213
* @returns Dimension object with number and unit, or false if parsing fails
214
*/
215
function unit(value: string): Dimension | false;
216
217
interface Dimension {
218
/** Numeric part as string (preserves original precision) */
219
number: string;
220
/** Unit part as string (empty string for unitless numbers) */
221
unit: string;
222
}
223
```
224
225
**Usage Examples:**
226
227
```javascript
228
// Parse various dimensions
229
console.log(valueParser.unit('2rem')); // { number: '2', unit: 'rem' }
230
console.log(valueParser.unit('100px')); // { number: '100', unit: 'px' }
231
console.log(valueParser.unit('1.5em')); // { number: '1.5', unit: 'em' }
232
console.log(valueParser.unit('50')); // { number: '50', unit: '' }
233
console.log(valueParser.unit('auto')); // false (not a dimension)
234
235
// Use in node walking
236
parsed.walk(function(node) {
237
if (node.type === 'word') {
238
const dimension = valueParser.unit(node.value);
239
if (dimension && dimension.unit === 'px') {
240
// Convert px to rem
241
const remValue = parseFloat(dimension.number) / 16;
242
node.value = remValue + 'rem';
243
}
244
}
245
});
246
```
247
248
## Node Types
249
250
All parsed CSS values are represented as trees of typed nodes. Each node has common properties plus type-specific properties.
251
252
### Base Node Properties
253
254
```javascript { .api }
255
interface BaseNode {
256
/** Node type identifier */
257
type: string;
258
/** The node's characteristic value */
259
value: string;
260
/** Start position in original CSS string (inclusive) */
261
sourceIndex: number;
262
/** End position in original CSS string (exclusive) */
263
sourceEndIndex: number;
264
}
265
266
/** Mixin interface for nodes that can be unclosed */
267
interface ClosableNode {
268
/** True if the node was not properly closed in CSS */
269
unclosed?: true;
270
}
271
272
/** Mixin interface for nodes with adjacent whitespace */
273
interface AdjacentAwareNode {
274
/** Whitespace before the node content */
275
before: string;
276
/** Whitespace after the node content */
277
after: string;
278
}
279
```
280
281
### Word Node
282
283
Represents keywords, quantities, and hex colors.
284
285
```javascript { .api }
286
interface WordNode extends BaseNode {
287
type: 'word';
288
/** The word value (e.g., 'no-repeat', '20px', '#e6e6e6') */
289
value: string;
290
}
291
```
292
293
**Examples:** `no-repeat`, `20px`, `75%`, `1.5`, `#e6e6e6`, `auto`
294
295
### String Node
296
297
Represents quoted string values.
298
299
```javascript { .api }
300
interface StringNode extends BaseNode, ClosableNode {
301
type: 'string';
302
/** Text content without quotes */
303
value: string;
304
/** Quote character used (" or ') */
305
quote: '"' | "'";
306
}
307
```
308
309
**Examples:** `"Arial"` in `font-family: "Arial"`, `'image.png'` in `background: url('image.png')`
310
311
### Function Node
312
313
Represents CSS functions with their arguments.
314
315
```javascript { .api }
316
interface FunctionNode extends BaseNode, ClosableNode, AdjacentAwareNode {
317
type: 'function';
318
/** Function name (e.g., 'rgb', 'url', 'calc') */
319
value: string;
320
/** Child nodes representing function arguments */
321
nodes: Node[];
322
}
323
```
324
325
**Examples:** `rgba(255, 0, 0, 0.5)`, `url(image.jpg)`, `calc(100% - 20px)`
326
327
**Special Cases:**
328
- `url()` functions with unquoted arguments are parsed differently than quoted ones
329
- Media features in parentheses (e.g., `(min-width: 700px)`) are parsed as functions with empty value
330
- `calc()` functions have special handling for `/` and `*` operators
331
332
### Div Node
333
334
Represents divider characters with surrounding whitespace.
335
336
```javascript { .api }
337
interface DivNode extends BaseNode, AdjacentAwareNode {
338
type: 'div';
339
/** Divider character (',', '/', or ':') */
340
value: ',' | '/' | ':';
341
}
342
```
343
344
**Examples:** `,` in `1s, 2s, 3s`, `/` in `10px / 20px`, `:` in `(min-width: 700px)`
345
346
### Space Node
347
348
Represents whitespace used as separators.
349
350
```javascript { .api }
351
interface SpaceNode extends BaseNode {
352
type: 'space';
353
/** Whitespace characters */
354
value: string;
355
}
356
```
357
358
**Examples:** Space in `border: 1px solid black`
359
360
### Comment Node
361
362
Represents CSS comments.
363
364
```javascript { .api }
365
interface CommentNode extends BaseNode, ClosableNode {
366
type: 'comment';
367
/** Comment content without /* and */ delimiters */
368
value: string;
369
}
370
```
371
372
**Examples:** `/* comment */` becomes `{ type: 'comment', value: ' comment ' }`
373
374
### Unicode Range Node
375
376
Represents Unicode range descriptors used in @font-face rules.
377
378
```javascript { .api }
379
interface UnicodeRangeNode extends BaseNode {
380
type: 'unicode-range';
381
/** Unicode range value (e.g., 'U+0025-00FF') used in @font-face rules */
382
value: string;
383
}
384
```
385
386
**Examples:** `U+0025-00FF`, `U+4E00-9FFF`
387
388
### Node Union Type
389
390
```javascript { .api }
391
type Node =
392
| WordNode
393
| StringNode
394
| FunctionNode
395
| DivNode
396
| SpaceNode
397
| CommentNode
398
| UnicodeRangeNode;
399
```
400
401
## Static Methods
402
403
Access utility functions directly on the main parser function.
404
405
```javascript { .api }
406
/** CSS dimension parsing utility */
407
valueParser.unit: (value: string) => Dimension | false;
408
409
/** Static tree walking utility */
410
valueParser.walk: (nodes: Node[], callback: WalkCallback, bubble?: boolean) => void;
411
412
/** Static stringification utility */
413
valueParser.stringify: (nodes: Node | Node[], custom?: CustomStringifierCallback) => string;
414
```