Minify font declarations with PostCSS by optimizing font-family, font-weight, and font shorthand properties
npx @tessl/cli install tessl/npm-postcss-minify-font-values@6.1.0PostCSS Minify Font Values is a PostCSS plugin that optimizes CSS font declarations by minimizing font-family, font-weight, and font shorthand properties. It intelligently unquotes font families where safe, removes duplicates, converts font-weight keywords to numeric values, and can truncate font-family lists after generic keywords.
npm install postcss-minify-font-valuesconst minifyFontValues = require('postcss-minify-font-values');ES Module:
import minifyFontValues from 'postcss-minify-font-values';const postcss = require('postcss');
const minifyFontValues = require('postcss-minify-font-values');
// Basic usage
const css = `
h1 {
font: bold 2.2rem/.9 "Open Sans Condensed", sans-serif;
}
p {
font-family: "Helvetica Neue", Arial, sans-serif, Helvetica;
font-weight: normal;
}
`;
const result = await postcss([minifyFontValues()])
.process(css, { from: undefined });
console.log(result.css);
// Output:
// h1 {
// font: 700 2.2rem/.9 Open Sans Condensed,sans-serif
// }
//
// p {
// font-family: Helvetica Neue,Arial,sans-serif;
// font-weight: 400;
// }PostCSS Minify Font Values follows the standard PostCSS plugin architecture with several key components:
var(), env()) and skips processing to preserve dynamic valuesThe plugin operates during PostCSS's OnceExit phase, walking through all font-related declarations and applying optimizations while preserving the original CSS structure and functionality.
Creates a PostCSS plugin instance with configurable options.
/**
* Creates a PostCSS plugin for minifying font values
* @param {Options} opts - Configuration options
* @returns {Plugin} PostCSS plugin instance
*/
function pluginCreator(opts?: Options): Plugin;
interface Options {
/** Remove font families after encountering generic keywords (default: false) */
removeAfterKeyword?: boolean;
/** Remove duplicate font families (default: true) */
removeDuplicates?: boolean;
/** Remove quotes from font families or custom function for CSS variables (default: true) */
removeQuotes?: boolean | ((prop: string) => '' | 'font' | 'font-family' | 'font-weight');
}
interface Plugin {
postcssPlugin: 'postcss-minify-font-values';
prepare(): ProcessorFunctions;
}
interface ProcessorFunctions {
OnceExit(css: Root): void;
}Usage Examples:
// Default options
const plugin = minifyFontValues();
// Custom options
const plugin = minifyFontValues({
removeAfterKeyword: true,
removeDuplicates: false,
removeQuotes: false
});
// CSS variable support with custom function
const plugin = minifyFontValues({
removeQuotes: (prop) => {
if (prop === '--font-family') return 'font-family';
if (prop === '--font-weight') return 'font-weight';
return '';
}
});The plugin processes font-family declarations to optimize font family lists.
Transformations applied:
sans-serif/* Input */
h1 { font-family: "Helvetica Neue", "Arial", "Helvetica Neue", sans-serif, "Times"; }
/* Output (default options) */
h1 { font-family: Helvetica Neue,Arial,sans-serif,Times; }
/* Output (removeAfterKeyword: true) */
h1 { font-family: Helvetica Neue,Arial,sans-serif; }The plugin converts font-weight keyword values to their numeric equivalents.
Conversions:
normal → 400bold → 700/* Input */
p { font-weight: normal; }
h1 { font-weight: bold; }
/* Output */
p { font-weight: 400; }
h1 { font-weight: 700; }The plugin optimizes the CSS font shorthand property by applying font-family and font-weight optimizations while preserving other font properties.
/* Input */
h1 { font: bold 16px/1.2 "Helvetica Neue", Arial, sans-serif; }
/* Output */
h1 { font: 700 16px/1.2 Helvetica Neue,Arial,sans-serif; }When using CSS variables for font properties, pass a custom function to the removeQuotes option to identify which variables should be treated as font properties.
const plugin = minifyFontValues({
removeQuotes: (prop) => {
// Map CSS variable names to font property types
if (prop === '--primary-font') return 'font-family';
if (prop === '--heading-weight') return 'font-weight';
if (prop === '--body-font') return 'font';
return ''; // Don't process other variables
}
});/* Input */
:root {
--primary-font: "Helvetica Neue", Arial, sans-serif;
--heading-weight: bold;
--other-var: "keep quotes";
}
/* Output */
:root {
--primary-font: Helvetica Neue,Arial,sans-serif;
--heading-weight: 700;
--other-var: "keep quotes";
}removeAfterKeyword?: booleanWhen true, removes font families from the list after encountering a generic font family keyword (sans-serif, serif, fantasy, cursive, monospace, system-ui).
Default: false
Example:
// removeAfterKeyword: true
minifyFontValues({ removeAfterKeyword: true })
// Input: font-family: Arial, sans-serif, Times, serif;
// Output: font-family: Arial,sans-serif;removeDuplicates?: booleanWhen true, removes duplicate font family names from the font family list. Note that monospace is treated specially and duplicates are preserved.
Default: true
Example:
// removeDuplicates: false
minifyFontValues({ removeDuplicates: false })
// Input: font-family: Arial, Helvetica, Arial, sans-serif;
// Output: font-family: Arial,Helvetica,Arial,sans-serif;removeQuotes?: boolean | ((prop: string) => '' | 'font' | 'font-family' | 'font-weight')Controls quote removal from font family names. Can be a boolean or a function for CSS variable support.
true (default): Removes quotes when safe to do sofalse: Preserves all quotesDefault: true
Function signature for CSS variables:
type RemoveQuotesFunction = (prop: string) => '' | 'font' | 'font-family' | 'font-weight';The function receives a CSS property name and should return:
'font-family': Process as font-family property'font-weight': Process as font-weight property'font': Process as font shorthand property'': Don't process (preserve quotes)The plugin includes several safety mechanisms:
The plugin automatically skips processing when CSS variable functions (var(), env()) are detected in property values to avoid breaking dynamic values.
/* These will not be processed */
h1 { font-family: var(--main-font), sans-serif; }
p { font-weight: env(--weight-normal); }Font family names that contain special characters or start with invalid identifier patterns are properly escaped according to CSS specification.
Generic font family keywords and CSS global keywords (inherit, initial, unset) are preserved and never quoted.
The plugin uses internal caching to avoid reprocessing identical property-value combinations, improving performance when processing large stylesheets with repeated font declarations.
interface Options {
removeAfterKeyword?: boolean;
removeDuplicates?: boolean;
removeQuotes?: boolean | ((prop: string) => '' | 'font' | 'font-family' | 'font-weight');
}
interface Plugin {
postcssPlugin: 'postcss-minify-font-values';
prepare(): {
OnceExit(css: Root): void;
};
}
type RemoveQuotesFunction = (prop: string) => '' | 'font' | 'font-family' | 'font-weight';