0
# Serialization and Stringification
1
2
Convert AST nodes back into CSS strings with customizable formatting and processing through callback-based serialization system.
3
4
## Capabilities
5
6
### Serialize Function
7
8
Core serialization function that traverses AST nodes and applies callback functions to generate CSS output.
9
10
```javascript { .api }
11
/**
12
* Convert AST nodes to CSS string using callback function
13
* @param children - Array of AST node objects to serialize
14
* @param callback - Function to process each node and generate CSS
15
* @returns Serialized CSS string
16
*/
17
function serialize(children: object[], callback: function): string;
18
```
19
20
**Usage Examples:**
21
22
```javascript
23
import { compile, serialize, stringify } from 'stylis';
24
25
// Basic serialization with default stringify
26
const ast = compile('h1 { color: red; }');
27
const css = serialize(ast, stringify);
28
console.log(css); // "h1{color:red;}"
29
30
// Custom serialization callback
31
const customCss = serialize(ast, (element, index, children, callback) => {
32
if (element.type === 'rule') {
33
return `/* Rule: ${element.props.join(', ')} */\n${stringify(element, index, children, callback)}`;
34
}
35
return stringify(element, index, children, callback);
36
});
37
38
// Serialization with middleware
39
import { middleware, prefixer } from 'stylis';
40
const processed = serialize(
41
compile('div { display: flex; }'),
42
middleware([prefixer, stringify])
43
);
44
```
45
46
### Stringify Function
47
48
Default stringification middleware that converts AST nodes into standard CSS syntax.
49
50
```javascript { .api }
51
/**
52
* Default stringification middleware for AST nodes
53
* @param element - AST node to stringify
54
* @param index - Index of node in children array
55
* @param children - Array of sibling nodes
56
* @param callback - Recursive callback for child nodes
57
* @returns CSS string for the element
58
*/
59
function stringify(element: object, index: number, children: object[], callback: function): string;
60
```
61
62
**Behavior by Node Type:**
63
64
- **LAYER**: Returns empty string if no children, otherwise processes children
65
- **IMPORT/NAMESPACE/DECLARATION**: Returns `element.return` or `element.value`
66
- **COMMENT**: Returns empty string (comments are typically stripped)
67
- **KEYFRAMES**: Returns `@keyframes name { ...children... }`
68
- **RULESET**: Returns `selector { ...children... }` if selector is non-empty
69
70
## Serialization Callback Interface
71
72
Custom serialization callbacks follow this interface:
73
74
```javascript { .api }
75
/**
76
* Serialization callback function interface
77
* @param element - Current AST node being processed
78
* @param index - Index of element in parent's children array
79
* @param children - Array of sibling elements
80
* @param callback - Recursive callback to process child elements
81
* @returns CSS string output for this element
82
*/
83
interface SerializationCallback {
84
(element: object, index: number, children: object[], callback: function): string;
85
}
86
```
87
88
## Node Processing Examples
89
90
### Custom Rule Processing
91
92
```javascript
93
import { compile, serialize } from 'stylis';
94
95
const customProcessor = (element, index, children, callback) => {
96
switch (element.type) {
97
case 'rule':
98
// Add custom attributes to selectors
99
const selectors = element.props.map(selector => `${selector}[data-styled]`);
100
return `${selectors.join(',')}{${serialize(element.children, callback)}}`;
101
102
case 'decl':
103
// Add !important to all declarations
104
return `${element.props}:${element.children} !important;`;
105
106
default:
107
return serialize([element], callback);
108
}
109
};
110
111
const styled = serialize(compile('.component { color: red; }'), customProcessor);
112
```
113
114
### Minification Example
115
116
```javascript
117
const minifier = (element, index, children, callback) => {
118
if (element.type === 'comm') {
119
return ''; // Strip comments
120
}
121
122
// Use default processing but remove extra whitespace
123
const result = stringify(element, index, children, callback);
124
return result.replace(/\s+/g, ' ').trim();
125
};
126
127
const minified = serialize(compile(`
128
.component {
129
padding: 20px;
130
margin: 10px;
131
}
132
`), minifier);
133
```
134
135
### Debug Output Example
136
137
```javascript
138
const debugSerializer = (element, index, children, callback) => {
139
const indent = ' '.repeat(getDepth(element));
140
const nodeInfo = `${indent}/* ${element.type}: ${element.value} */\n`;
141
const nodeOutput = stringify(element, index, children, callback);
142
return nodeInfo + nodeOutput;
143
};
144
145
function getDepth(element) {
146
let depth = 0;
147
let current = element.parent;
148
while (current) {
149
depth++;
150
current = current.parent;
151
}
152
return depth;
153
}
154
```
155
156
## Output Formatting Control
157
158
The serialization system provides full control over CSS output formatting:
159
160
### Whitespace Control
161
- **Minified**: Remove all unnecessary whitespace
162
- **Formatted**: Add indentation and line breaks for readability
163
- **Compact**: Single line with minimal spacing
164
165
### Comment Handling
166
- **Preserve**: Keep all comments in output
167
- **Strip**: Remove all comments
168
- **Selective**: Keep only specific comment types (e.g., license headers)
169
170
### Property Formatting
171
- **Standard**: `property: value;`
172
- **Expanded**: `property : value ;` (with extra spacing)
173
- **Custom**: Apply transformation functions to property-value pairs
174
175
## Error Handling
176
177
The serialization system is designed to handle malformed AST gracefully:
178
179
- **Missing Properties**: Uses fallback values or empty strings
180
- **Invalid Nodes**: Skips invalid nodes or applies default processing
181
- **Circular References**: Detects and breaks circular references in AST
182
- **Type Mismatches**: Handles unexpected node types with default behavior
183
184
Serialization errors are typically non-fatal and result in partial CSS output rather than throwing exceptions.