0
# postcss-normalize-charset
1
2
postcss-normalize-charset is a PostCSS plugin that normalizes CSS @charset declarations by ensuring only a single charset rule exists and is positioned at the top of the document. It prevents issues that can occur when concatenating CSS files with multiple or misplaced charset declarations, and can automatically add UTF-8 charset declarations when non-ASCII characters are detected.
3
4
## Package Information
5
6
- **Package Name**: postcss-normalize-charset
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install postcss-normalize-charset`
10
11
## Core Imports
12
13
```javascript
14
const postcssNormalizeCharset = require("postcss-normalize-charset");
15
```
16
17
Note: This package uses CommonJS exports only. For ES modules, use dynamic import:
18
19
```javascript
20
const postcssNormalizeCharset = await import("postcss-normalize-charset");
21
// Use postcssNormalizeCharset.default
22
```
23
24
## Basic Usage
25
26
```javascript
27
const postcss = require("postcss");
28
const postcssNormalizeCharset = require("postcss-normalize-charset");
29
30
// Basic usage with default options
31
const result = await postcss([postcssNormalizeCharset()])
32
.process('a{content:"©"}', { from: undefined });
33
34
console.log(result.css);
35
// Output: @charset "utf-8";\na{content:"©"}
36
37
// Usage with options
38
const result2 = await postcss([postcssNormalizeCharset({ add: false })])
39
.process('a{content:"©"}', { from: undefined });
40
41
console.log(result2.css);
42
// Output: a{content:"©"} (no charset added)
43
```
44
45
## Capabilities
46
47
### Plugin Creator Function
48
49
The main export creates a PostCSS plugin instance with optional configuration.
50
51
```javascript { .api }
52
/**
53
* Creates a PostCSS plugin that normalizes CSS @charset declarations
54
* @param {Options} opts - Configuration options for the plugin
55
* @returns {Plugin} PostCSS plugin instance
56
*/
57
function postcssNormalizeCharset(opts?: Options): Plugin;
58
59
/**
60
* PostCSS plugin marker - indicates this function is a PostCSS plugin
61
* This property is used by PostCSS to identify the function as a plugin
62
*/
63
postcssNormalizeCharset.postcss = true;
64
```
65
66
**Parameters:**
67
- `opts` (optional): Configuration options object
68
69
**Returns:** PostCSS plugin instance that can be passed to PostCSS
70
71
**Plugin Behavior:**
72
1. Scans the CSS for existing @charset rules and removes them
73
2. Detects non-ASCII characters in the CSS content
74
3. If non-ASCII characters are found and no charset was present, adds `@charset "utf-8"` (unless `add: false`)
75
4. If a charset rule existed, preserves the first one found and positions it at the top
76
5. Ensures only one charset declaration exists in the final CSS
77
78
### Configuration Options
79
80
The plugin accepts an optional configuration object with the following properties:
81
82
- `add` (boolean, optional): Controls whether the plugin automatically adds `@charset "utf-8"` when non-ASCII characters are detected in CSS that doesn't already have a charset declaration. Defaults to `true`.
83
84
## Usage Examples
85
86
### Automatic Charset Addition
87
88
```javascript
89
const postcss = require("postcss");
90
const postcssNormalizeCharset = require("postcss-normalize-charset");
91
92
// CSS with non-ASCII characters but no charset
93
const css = 'a{content:"©"}';
94
95
const result = await postcss([postcssNormalizeCharset()])
96
.process(css, { from: undefined });
97
98
console.log(result.css);
99
// Output: @charset "utf-8";\na{content:"©"}
100
```
101
102
### Preventing Automatic Addition
103
104
```javascript
105
const postcss = require("postcss");
106
const postcssNormalizeCharset = require("postcss-normalize-charset");
107
108
// CSS with non-ASCII characters, but prevent charset addition
109
const css = 'a{content:"©"}';
110
111
const result = await postcss([postcssNormalizeCharset({ add: false })])
112
.process(css, { from: undefined });
113
114
console.log(result.css);
115
// Output: a{content:"©"} (no charset added)
116
```
117
118
### Normalizing Multiple Charset Rules
119
120
```javascript
121
const postcss = require("postcss");
122
const postcssNormalizeCharset = require("postcss-normalize-charset");
123
124
// CSS with multiple charset declarations
125
const css = 'a{content:"©"}@charset "utf-8";@charset "windows-1251";';
126
127
const result = await postcss([postcssNormalizeCharset()])
128
.process(css, { from: undefined });
129
130
console.log(result.css);
131
// Output: @charset "utf-8";\na{content:"©"}
132
```
133
134
### Moving Charset to Top
135
136
```javascript
137
const postcss = require("postcss");
138
const postcssNormalizeCharset = require("postcss-normalize-charset");
139
140
// CSS with charset rule in wrong position
141
const css = 'b{жизнь:калька}@charset "windows-1251";a{content:"©"}';
142
143
const result = await postcss([postcssNormalizeCharset()])
144
.process(css, { from: undefined });
145
146
console.log(result.css);
147
// Output: @charset "windows-1251";b{жизнь:калька}a{content:"©"}
148
```
149
150
### Removing Unnecessary Charset Rules
151
152
```javascript
153
const postcss = require("postcss");
154
const postcssNormalizeCharset = require("postcss-normalize-charset");
155
156
// CSS with charset but no non-ASCII characters
157
const css = 'a{content:"c"}@charset "utf-8";@charset "windows-1251";';
158
159
const result = await postcss([postcssNormalizeCharset()])
160
.process(css, { from: undefined });
161
162
console.log(result.css);
163
// Output: a{content:"c"} (charset rules removed since no non-ASCII chars)
164
```
165
166
## Types
167
168
```javascript { .api }
169
/**
170
* Configuration options for postcss-normalize-charset
171
*/
172
interface Options {
173
/**
174
* Whether to automatically add @charset "utf-8" when non-ASCII characters are detected
175
* @default true
176
*/
177
add?: boolean;
178
}
179
180
/**
181
* PostCSS plugin instance interface
182
*/
183
interface Plugin {
184
/** The name identifier for this PostCSS plugin */
185
postcssPlugin: string;
186
/** Hook that runs once after all other processing is complete */
187
OnceExit(css: Root, helpers: { AtRule: AtRuleConstructor }): void;
188
}
189
190
/**
191
* PostCSS CSS root node representing the entire stylesheet
192
*/
193
interface Root {
194
/** Walk through all nodes in the CSS tree */
195
walk(callback: (node: Node) => void): void;
196
/** Add a node to the beginning of the root */
197
prepend(node: Node): void;
198
/** The first child node */
199
first?: Node;
200
/** The parent node (null for root) */
201
parent: null;
202
}
203
204
/**
205
* Base PostCSS node interface
206
*/
207
interface Node {
208
/** The type of node (e.g., 'atrule', 'rule', 'decl') */
209
type: string;
210
/** The parent node containing this node */
211
parent?: Node;
212
/** Convert the node to a CSS string */
213
toString(): string;
214
/** Remove this node from its parent */
215
remove(): void;
216
/** Source location information */
217
source?: {
218
input: { css: string };
219
start: { column: number; line: number };
220
end: { column: number; line: number };
221
};
222
}
223
224
/**
225
* PostCSS at-rule node (like @charset, @media, etc.)
226
*/
227
interface AtRule extends Node {
228
/** The at-rule name (without @) */
229
name: string;
230
/** The at-rule parameters */
231
params: string;
232
}
233
234
/**
235
* PostCSS AtRule constructor for creating @charset rules
236
*/
237
interface AtRuleConstructor {
238
new(props: { name: string; params: string; source?: any }): AtRule;
239
}
240
```