or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-postcss-value-parser

Transforms CSS declaration values and at-rule parameters into abstract syntax trees with traversal API

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/postcss-value-parser@4.2.x

To install, run

npx @tessl/cli install tessl/npm-postcss-value-parser@4.2.0

0

# 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

```