or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# PostCSS Normalize Unicode

1

2

PostCSS Normalize Unicode is a PostCSS plugin that normalizes unicode-range descriptors in CSS @font-face rules. It intelligently converts ranges like `u+2b00-2bff` into more compact wildcard representations like `u+2b??` when the range covers complete hex digit positions, resulting in smaller CSS output while maintaining browser compatibility.

3

4

## Package Information

5

6

- **Package Name**: postcss-normalize-unicode

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install postcss-normalize-unicode`

10

11

## Core Imports

12

13

```javascript

14

const postcssNormalizeUnicode = require("postcss-normalize-unicode");

15

```

16

17

For ES modules:

18

19

```javascript

20

import postcssNormalizeUnicode from "postcss-normalize-unicode";

21

```

22

23

## Basic Usage

24

25

```javascript

26

const postcss = require("postcss");

27

const postcssNormalizeUnicode = require("postcss-normalize-unicode");

28

29

// Basic usage without options

30

const result = await postcss([

31

postcssNormalizeUnicode()

32

]).process(css, { from: undefined });

33

34

// With browserslist override

35

const result = await postcss([

36

postcssNormalizeUnicode({

37

overrideBrowserslist: ['defaults', 'not ie <=11']

38

})

39

]).process(css, { from: undefined });

40

```

41

42

**Input CSS:**

43

```css

44

@font-face {

45

font-family: test;

46

unicode-range: u+2b00-2bff;

47

}

48

```

49

50

**Output CSS:**

51

```css

52

@font-face {

53

font-family: test;

54

unicode-range: u+2b??;

55

}

56

```

57

58

## Architecture

59

60

The plugin operates by:

61

62

1. **Browser Detection**: Uses browserslist to determine target browsers and detect legacy IE/Edge compatibility requirements

63

2. **CSS Processing**: Walks through all `unicode-range` declarations in CSS during the `OnceExit` phase

64

3. **Value Parsing**: Uses postcss-value-parser to safely parse and transform unicode-range values

65

4. **Range Optimization**: Converts unicode ranges to wildcard patterns using the internal algorithm:

66

- Parses ranges like `u+2b00-2bff` into start/end bounds

67

- Compares hex digit positions from left to right

68

- Converts positions where start=0 and end=f to wildcard (?)

69

- Supports up to 5 wildcard characters maximum

70

- Falls back to original range if optimization isn't possible

71

5. **Legacy Support**: Automatically converts lowercase 'u' prefixes to uppercase 'U' for IE ≤11 and Edge ≤15

72

6. **Performance Optimization**: Implements caching to avoid re-processing identical values

73

74

## Capabilities

75

76

### Plugin Creator

77

78

Creates a PostCSS plugin instance for normalizing unicode-range descriptors.

79

80

```javascript { .api }

81

/**

82

* Creates a PostCSS plugin for normalizing unicode-range descriptors

83

* @param {Options} opts - Plugin configuration options

84

* @returns {import('postcss').Plugin} PostCSS plugin instance

85

*/

86

function postcssNormalizeUnicode(opts?: Options): import('postcss').Plugin;

87

```

88

89

### Unicode Range Normalization

90

91

The plugin automatically processes all `unicode-range` declarations and:

92

93

- Converts ranges like `u+2b00-2bff` to `u+2b??` when possible

94

- Converts ranges like `u+1e00-1eff` to `u+1e??` when possible

95

- Supports up to 5 wildcard characters (?) in range patterns

96

- Preserves ranges that cannot be optimized (e.g., `u+2125-2128`)

97

- Handles case normalization (converts to lowercase by default)

98

- Applies uppercase 'U' prefix for legacy browser compatibility when needed

99

100

### Browser Compatibility Handling

101

102

Automatically detects and handles browser-specific requirements:

103

104

- **Legacy browsers** (IE ≤11, Edge ≤15): Converts to uppercase 'U' prefix

105

- **Modern browsers**: Uses lowercase 'u' prefix for smaller output

106

- Uses browserslist configuration for automatic browser detection

107

108

## Configuration Options

109

110

```javascript { .api }

111

interface Options {

112

/** Override browserslist configuration for browser targeting */

113

overrideBrowserslist?: string | string[];

114

/** Custom usage statistics for browserslist */

115

stats?: object;

116

/** Custom path for browserslist config resolution */

117

path?: string;

118

/** Environment name for browserslist config */

119

env?: string;

120

}

121

```

122

123

### Configuration Properties

124

125

#### `overrideBrowserslist`

126

- **Type**: `string | string[]`

127

- **Optional**: Yes

128

- **Description**: Override the default browserslist configuration to target specific browsers

129

- **Example**: `['defaults', 'not ie <=11']` or `'IE 9'`

130

131

#### `stats`

132

- **Type**: `object`

133

- **Optional**: Yes

134

- **Description**: Custom usage statistics for browserslist browser selection

135

136

#### `path`

137

- **Type**: `string`

138

- **Optional**: Yes

139

- **Description**: Custom path for browserslist configuration file resolution

140

141

#### `env`

142

- **Type**: `string`

143

- **Optional**: Yes

144

- **Description**: Environment name to use from browserslist configuration (e.g., 'production', 'legacy')

145

146

## Usage Examples

147

148

### Basic Plugin Usage

149

150

```javascript

151

const postcss = require("postcss");

152

const postcssNormalizeUnicode = require("postcss-normalize-unicode");

153

154

const processor = postcss([postcssNormalizeUnicode()]);

155

156

const css = `

157

@font-face {

158

font-family: 'MyFont';

159

unicode-range: u+2b00-2bff, u+1e00-1eff;

160

}

161

`;

162

163

const result = await processor.process(css, { from: undefined });

164

console.log(result.css);

165

// Output: unicode-range: u+2b??, u+1e??;

166

```

167

168

### Legacy Browser Support

169

170

```javascript

171

// Force legacy browser compatibility

172

const processor = postcss([

173

postcssNormalizeUnicode({

174

overrideBrowserslist: 'IE 9'

175

})

176

]);

177

178

const result = await processor.process(css, { from: undefined });

179

// Output will use uppercase 'U+2b??' instead of 'u+2b??'

180

```

181

182

### Using Browserslist Environment

183

184

```javascript

185

// Use specific browserslist environment

186

const processor = postcss([

187

postcssNormalizeUnicode({

188

env: 'legacy'

189

})

190

]);

191

```

192

193

### Multiple Range Processing

194

195

```javascript

196

const postcss = require("postcss");

197

const postcssNormalizeUnicode = require("postcss-normalize-unicode");

198

199

const css = `

200

@font-face {

201

font-family: 'Icons';

202

unicode-range: u+2000-2fff, u+2120-212f, u+0-7f;

203

}

204

`;

205

206

const result = await postcss([postcssNormalizeUnicode()])

207

.process(css, { from: undefined });

208

209

console.log(result.css);

210

// Output:

211

// @font-face {

212

// font-family: 'Icons';

213

// unicode-range: u+2???, u+212?, u+0-7f;

214

// }

215

//

216

// Transformations applied:

217

// u+2000-2fff → u+2??? (4-digit range to 3 wildcards)

218

// u+2120-212f → u+212? (4-digit range to 1 wildcard)

219

// u+0-7f → remains unchanged (cannot be optimized)

220

```

221

222

## Browser Compatibility

223

224

- **Modern browsers**: Uses lowercase 'u' prefix (smaller output)

225

- **IE ≤11**: Requires uppercase 'U' prefix (automatically detected and applied)

226

- **Edge ≤15**: Requires uppercase 'U' prefix (automatically detected and applied)

227

- **Edge 16+**: Supports lowercase 'u' prefix

228

229

The plugin automatically detects browser requirements using browserslist configuration and applies the appropriate prefix casing.

230

231

## Plugin Properties

232

233

The plugin exposes a PostCSS compatibility marker to indicate it's a valid PostCSS plugin:

234

235

```javascript { .api }

236

// PostCSS plugin compatibility marker

237

postcssNormalizeUnicode.postcss = true;

238

```

239

240

## Error Handling

241

242

The plugin handles various edge cases gracefully:

243

244

- **Invalid ranges**: Preserves original values for ranges that don't follow expected patterns

245

- **Single values**: Passes through unicode ranges that aren't ranges (no dash)

246

- **Mismatched lengths**: Preserves ranges where start and end have different hex digit lengths

247

- **CSS variables and functions**: Passes through `var()`, `env()`, and other CSS functions unchanged

248

- **Unknown properties**: Only processes `unicode-range` declarations, ignores other properties

249

250

## Performance Features

251

252

- **Caching**: Results are cached during processing to avoid redundant transformations

253

- **Lazy evaluation**: Processing only occurs during PostCSS OnceExit phase for efficiency

254

- **Minimal parsing**: Uses postcss-value-parser for safe and efficient CSS value manipulation