A CSS parser, transformer, and minifier written in Rust with Node.js bindings
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Browser compatibility targeting system for controlling CSS transformation, vendor prefixing, and syntax lowering based on specific browser versions and feature support.
Convert browserslist query results into Lightning CSS targets for seamless integration with existing browser compatibility workflows.
/**
* Converts a browserslist result into targets that can be passed to lightningcss
* @param browserslist - Array of browser version strings from browserslist
* @returns Targets object for use in transformation options
*/
function browserslistToTargets(browserslist: string[]): Targets;Usage Examples:
import { browserslistToTargets, transform } from "lightningcss";
import browserslist from "browserslist";
// Use browserslist query
const browsers = browserslist('last 2 versions, not dead');
const targets = browserslistToTargets(browsers);
console.log(targets);
// Output: { chrome: 5898240, firefox: 5832704, safari: 1114112, ... }
// Use with transformation
const result = transform({
filename: "modern.css",
code: new TextEncoder().encode(`
.container {
display: grid;
gap: 1rem;
color: lab(50% 20 -30);
}
`),
targets,
minify: true
});
// Manual browserslist with specific queries
const modernTargets = browserslistToTargets(browserslist([
'Chrome >= 90',
'Firefox >= 88',
'Safari >= 14',
'Edge >= 90'
]));Directly specify browser versions for precise control over transformation behavior.
interface Targets {
/** Android browser version (version * 65536) */
android?: number;
/** Chrome browser version (version * 65536) */
chrome?: number;
/** Microsoft Edge version (version * 65536) */
edge?: number;
/** Firefox browser version (version * 65536) */
firefox?: number;
/** Internet Explorer version (version * 65536) */
ie?: number;
/** iOS Safari version (version * 65536) */
ios_saf?: number;
/** Opera browser version (version * 65536) */
opera?: number;
/** Safari browser version (version * 65536) */
safari?: number;
/** Samsung Internet version (version * 65536) */
samsung?: number;
}Usage Examples:
import { transform } from "lightningcss";
// Target modern browsers only
const modernTargets: Targets = {
chrome: 90 << 16, // Chrome 90 (90 * 65536)
firefox: 88 << 16, // Firefox 88
safari: 14 << 16, // Safari 14
edge: 90 << 16 // Edge 90
};
// Target older browsers requiring more polyfills
const legacyTargets: Targets = {
chrome: 60 << 16, // Chrome 60
firefox: 55 << 16, // Firefox 55
safari: 11 << 16, // Safari 11
edge: 79 << 16, // Edge 79
ie: 11 << 16 // Internet Explorer 11
};
// Mobile-focused targeting
const mobileTargets: Targets = {
android: 81 << 16, // Android WebView 81
ios_saf: 13 << 16, // iOS Safari 13
samsung: 12 << 16 // Samsung Internet 12
};
const result = transform({
filename: "responsive.css",
code: new TextEncoder().encode(`
.hero {
background: linear-gradient(45deg, #ff0000, #00ff00);
display: flex;
gap: clamp(1rem, 2vw, 2rem);
border-radius: max(1rem, 2vw);
}
`),
targets: legacyTargets,
minify: true
});Control which CSS features are compiled or preserved regardless of browser support.
// Feature flags used in TransformOptions
interface TransformOptions<C extends CustomAtRules> {
/** Features that should always be compiled, even when supported by targets. */
include?: number;
/** Features that should never be compiled, even when unsupported by targets. */
exclude?: number;
}
// Features enum (imported from lightningcss)
const Features = {
Nesting: 1,
NotSelectorList: 2,
DirSelector: 4,
LangSelectorList: 8,
IsSelector: 16,
TextDecorationThicknessPercent: 32,
MediaIntervalSyntax: 64,
MediaRangeSyntax: 128,
CustomMediaQueries: 256,
ClampFunction: 512,
ColorFunction: 1024,
OklabColors: 2048,
LabColors: 4096,
P3Colors: 8192,
HexAlphaColors: 16384,
SpaceSeparatedColorNotation: 32768,
FontFamilySystemUi: 65536,
DoublePositionGradients: 131072,
VendorPrefixes: 262144,
LogicalProperties: 524288,
LightDark: 1048576,
Selectors: 31,
MediaQueries: 448,
Colors: 1113088,
}Usage Examples:
import { transform, Features } from "lightningcss";
// Always compile nesting even if browsers support it
const alwaysCompileNesting = transform({
filename: "nested.css",
code: new TextEncoder().encode(`
.card {
background: white;
&:hover {
background: gray;
.title {
color: blue;
}
}
}
`),
targets: { chrome: 112 << 16 }, // Chrome 112 supports nesting
include: Features.Nesting, // But compile it anyway
minify: true
});
// Never compile color functions, preserve modern syntax
const preserveModernColors = transform({
filename: "colors.css",
code: new TextEncoder().encode(`
.modern {
color: lab(50% 20 -30);
background: oklch(60% 0.15 180);
border-color: color(display-p3 1 0 0);
}
`),
targets: { chrome: 70 << 16 }, // Old Chrome doesn't support these
exclude: Features.ColorFunction | Features.OklabColors | Features.P3Colors,
minify: true
});
// Compile multiple features
const compileModernFeatures = transform({
filename: "modern.css",
code: new TextEncoder().encode(`
.component {
background: lab(50% 20 -30);
margin-inline: 1rem;
&:hover {
color: oklch(60% 0.15 180);
}
@media (width > 768px) {
gap: clamp(1rem, 2vw, 2rem);
}
}
`),
targets: { firefox: 80 << 16, safari: 13 << 16 },
include: Features.Nesting | Features.LogicalProperties | Features.MediaRangeSyntax,
minify: true
});Real-world examples of how different targets affect CSS transformation output.
Modern Browser Targeting:
const modernCSS = `
.grid {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
color: lab(50% 20 -30);
}
.card {
container-type: inline-size;
&:hover {
transform: scale(1.05);
}
}
@container (width > 300px) {
.card-content { font-size: 1.2rem; }
}
`;
const modernResult = transform({
filename: "modern.css",
code: new TextEncoder().encode(modernCSS),
targets: {
chrome: 105 << 16,
firefox: 100 << 16,
safari: 16 << 16
},
minify: true
});
// Minimal transformation - most features are preservedLegacy Browser Targeting:
const legacyResult = transform({
filename: "legacy.css",
code: new TextEncoder().encode(modernCSS),
targets: {
chrome: 60 << 16,
firefox: 55 << 16,
safari: 11 << 16,
ie: 11 << 16
},
minify: true
});
// Extensive transformation - nesting flattened, modern colors converted, etc.Progressive Enhancement Pattern:
// Generate multiple CSS files for different browser tiers
const baseCss = `
.hero {
background: linear-gradient(45deg, #ff0000, #00ff00);
padding: clamp(1rem, 2vw, 3rem);
&:hover {
transform: scale(1.02);
}
}
`;
// Base styles for all browsers
const baseResult = transform({
filename: "base.css",
code: new TextEncoder().encode(baseCss),
targets: { ie: 11 << 16, chrome: 30 << 16 },
minify: true
});
// Enhanced styles for modern browsers
const enhancedResult = transform({
filename: "enhanced.css",
code: new TextEncoder().encode(baseCss + `
.hero-enhanced {
background: conic-gradient(from 45deg, #ff0000, #00ff00, #0000ff);
backdrop-filter: blur(10px);
color: lab(50% 20 -30);
}
`),
targets: { chrome: 90 << 16, firefox: 88 << 16 },
minify: true
});