Normalize unicode-range descriptors, and can convert to wildcard ranges.
npx @tessl/cli install tessl/npm-postcss-normalize-unicode@7.0.0PostCSS 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.
npm install postcss-normalize-unicodeconst postcssNormalizeUnicode = require("postcss-normalize-unicode");For ES modules:
import postcssNormalizeUnicode from "postcss-normalize-unicode";const postcss = require("postcss");
const postcssNormalizeUnicode = require("postcss-normalize-unicode");
// Basic usage without options
const result = await postcss([
postcssNormalizeUnicode()
]).process(css, { from: undefined });
// With browserslist override
const result = await postcss([
postcssNormalizeUnicode({
overrideBrowserslist: ['defaults', 'not ie <=11']
})
]).process(css, { from: undefined });Input CSS:
@font-face {
font-family: test;
unicode-range: u+2b00-2bff;
}Output CSS:
@font-face {
font-family: test;
unicode-range: u+2b??;
}The plugin operates by:
unicode-range declarations in CSS during the OnceExit phaseu+2b00-2bff into start/end boundsCreates a PostCSS plugin instance for normalizing unicode-range descriptors.
/**
* Creates a PostCSS plugin for normalizing unicode-range descriptors
* @param {Options} opts - Plugin configuration options
* @returns {import('postcss').Plugin} PostCSS plugin instance
*/
function postcssNormalizeUnicode(opts?: Options): import('postcss').Plugin;The plugin automatically processes all unicode-range declarations and:
u+2b00-2bff to u+2b?? when possibleu+1e00-1eff to u+1e?? when possibleu+2125-2128)Automatically detects and handles browser-specific requirements:
interface Options {
/** Override browserslist configuration for browser targeting */
overrideBrowserslist?: string | string[];
/** Custom usage statistics for browserslist */
stats?: object;
/** Custom path for browserslist config resolution */
path?: string;
/** Environment name for browserslist config */
env?: string;
}overrideBrowsersliststring | string[]['defaults', 'not ie <=11'] or 'IE 9'statsobjectpathstringenvstringconst postcss = require("postcss");
const postcssNormalizeUnicode = require("postcss-normalize-unicode");
const processor = postcss([postcssNormalizeUnicode()]);
const css = `
@font-face {
font-family: 'MyFont';
unicode-range: u+2b00-2bff, u+1e00-1eff;
}
`;
const result = await processor.process(css, { from: undefined });
console.log(result.css);
// Output: unicode-range: u+2b??, u+1e??;// Force legacy browser compatibility
const processor = postcss([
postcssNormalizeUnicode({
overrideBrowserslist: 'IE 9'
})
]);
const result = await processor.process(css, { from: undefined });
// Output will use uppercase 'U+2b??' instead of 'u+2b??'// Use specific browserslist environment
const processor = postcss([
postcssNormalizeUnicode({
env: 'legacy'
})
]);const postcss = require("postcss");
const postcssNormalizeUnicode = require("postcss-normalize-unicode");
const css = `
@font-face {
font-family: 'Icons';
unicode-range: u+2000-2fff, u+2120-212f, u+0-7f;
}
`;
const result = await postcss([postcssNormalizeUnicode()])
.process(css, { from: undefined });
console.log(result.css);
// Output:
// @font-face {
// font-family: 'Icons';
// unicode-range: u+2???, u+212?, u+0-7f;
// }
//
// Transformations applied:
// u+2000-2fff → u+2??? (4-digit range to 3 wildcards)
// u+2120-212f → u+212? (4-digit range to 1 wildcard)
// u+0-7f → remains unchanged (cannot be optimized)The plugin automatically detects browser requirements using browserslist configuration and applies the appropriate prefix casing.
The plugin exposes a PostCSS compatibility marker to indicate it's a valid PostCSS plugin:
// PostCSS plugin compatibility marker
postcssNormalizeUnicode.postcss = true;The plugin handles various edge cases gracefully:
var(), env(), and other CSS functions unchangedunicode-range declarations, ignores other properties