css-if-polyfill
v0.1.5
Published
A JavaScript polyfill for CSS if() functionality with style(), media(), and supports() functions
Maintainers
Readme
CSS if() Function Polyfill v0.1
A modern JavaScript polyfill for the CSS if() function with hybrid build-time and runtime processing. Transforms CSS if() functions to native @media and @supports rules where possible, with runtime fallback for dynamic conditions.
🚀 What's New in v0.1
- 🏗️ Build-time Transformation - Convert
media()andsupports()conditions to native CSS - ⚡ Zero Runtime Cost - Native CSS rules require no JavaScript processing
- 🔄 Hybrid Processing - Automatic routing between native and runtime processing
- 🛠️ CLI Tool - Transform CSS files during build process
- 📈 Performance Optimized - Up to 95% faster for transformable conditions
- 🔧 Backwards Compatible - Existing code continues to work unchanged
Features
- ✅ Hybrid Architecture with build-time + runtime processing
- ✅ Native CSS Generation for
media()andsupports()conditions - ✅ Runtime Processing for dynamic
style()conditions - ✅ CLI Tool for build-time transformation with statistics
- ✅ Multiple conditions within a single if() function
- ✅ Shorthand property support for complex CSS values
- ✅ Automatic fallback for unsupported browsers
- ✅ Real-time processing of dynamic stylesheets
- ✅ TypeScript support with full type definitions
- ✅ Zero dependencies - Pure JavaScript implementation
- ✅ Comprehensive test suite with 95%+ coverage
- ✅ Multiple build formats (ES6, CommonJS, UMD)
Installation
npm install css-if-polyfillQuick Start
Build-time Transformation (Recommended)
# Transform CSS during build
npx css-if-polyfill input.css output.css --minify --statsRuntime Processing
import { init } from "css-if-polyfill";
// Initialize with hybrid processing
init({ useNativeTransform: true });Usage
Automatic Initialization (Recommended)
Simply import the polyfill and it will automatically initialize:
import "css-if-polyfill";Or include it via script tag:
<script src="https://cdn.jsdelivr.net/npm/css-if-polyfill/dist/index.umd.min.js"></script>Manual Initialization
import { init } from "css-if-polyfill";
// Initialize with options
const polyfill = init({
debug: true,
autoInit: true
});Processing CSS Text
import { processCSSText } from "css-if-polyfill";
const css = ".button { color: if(media(width >= 768px): blue; else: red); }";
const processed = processCSSText(css);
console.log(processed); // .button { color: red; } @media(width >= 768px) { .button { color: blue; } }CSS if() Syntax
The polyfill supports the following CSS if() syntax:
property: if(condition: value; else: value-if-false);Note: The else clause is optional. If omitted and the condition is false, an empty value will be used.
Enhanced Features
1. Multiple Conditions within Single if()
You can now use multiple conditions within a single if() function, where each condition is tested sequentially until one matches:
.element {
/* Multiple conditions tested in order */
background: if(
style(--scheme: ice): linear-gradient(#caf0f8, white, #caf0f8) ;
style(--scheme: fire): linear-gradient(#ffc971, white, #ffc971) ;
style(--scheme: earth): linear-gradient(#8fbc8f, white, #8fbc8f) ;
else: linear-gradient(#e0e0e0, white, #e0e0e0) ;
);
}2. Shorthand Property Support
Use if() functions within CSS shorthand properties:
.element {
/* Border shorthand with conditional values */
border: if(
style(--scheme: ice): 3px; style(--scheme: fire): 5px; else: 1px;
)
if(supports(border-style: dashed): dashed; else: solid)
if(
style(--scheme: ice): #0ea5e9; style(--scheme: fire): #f97316;
else: #6b7280
);
/* Font shorthand with multiple conditions */
font:
if(
media(width >= 1200px): bold; media(width >= 768px): 600;
else: normal
)
if(media(width >= 768px): 18px; else: 14px) / 1.5 system-ui,
sans-serif;
}Supported Condition Types
1. Media Queries with media()
.responsive-text {
font-size: if(
media(width >= 1200px): 24px; media(width >= 768px): 18px; else: 16px
);
}2. Feature Detection with supports()
.modern-layout {
display: if(
supports(display: subgrid): subgrid; supports(display: grid): grid;
supports(display: flex): flex; else: block
);
}3. Style Queries with style()
.theme-aware {
color: if(
style(--theme: dark): white; style(--theme: light): black;
style(--theme: blue): #1e40af; else: #374151
);
}4. Boolean Conditions
.debug-mode {
border: if(style(--true): 2px solid red; else: none);
opacity: if(style(--false): 0.5; else: 1);
}Advanced Examples
Theme-Based Styling
.card {
background: if(
style(--scheme: ice): linear-gradient(135deg, #caf0f8, white, #caf0f8) ;
style(--scheme: fire): linear-gradient(
135deg,
#ffc971,
white,
#ffc971
)
;
style(--scheme: earth): linear-gradient(
135deg,
#8fbc8f,
white,
#8fbc8f
)
; else: linear-gradient(135deg, #e0e0e0, white, #e0e0e0) ;
);
color: if(
style(--theme: dark): #e2e8f0; style(--theme: light): #2d3748;
style(--theme: blue): #1e40af; else: #374151;
);
}Progressive Enhancement
.feature-demo {
display: if(
supports(display: subgrid): subgrid; supports(display: grid): grid;
supports(display: flex): flex; else: block;
);
gap: if(supports(gap): 20px; else: 0;);
}Responsive Design with Multiple Breakpoints
.responsive-element {
padding: if(
media(width >= 1200px): 40px; media(width >= 768px): 30px;
media(width >= 480px): 20px; else: 15px;
);
font-size: if(
media(width >= 1200px): 20px; media(width >= 768px): 18px; else: 16px;
);
}Accessibility-Aware Animations
.animated-element {
transition: if(
media(prefers-reduced-motion: reduce): none; supports(transition): all
0.3s ease; else: none;
);
transform: if(
media(prefers-reduced-motion: reduce): none;
supports(transform): scale(1) ; else: none;
);
}API Reference
init(options)
Initialize the polyfill with optional configuration.
const polyfill = init({
debug: false, // Enable debug logging
autoInit: true // Automatically process existing stylesheets
});processCSSText(cssText, options)
Process CSS text containing if() functions.
const processed = processCSSText(`
.test {
color: if(
style(--theme: dark): white;
style(--theme: light): black;
else: gray;
);
}
`);hasNativeSupport()
Check if the browser has native CSS if() support.
if (hasNativeSupport()) {
console.log("Native support available!");
}Instance Methods
const polyfill = init();
// Manually refresh/reprocess all stylesheets
polyfill.refresh();
// Check if polyfill is needed
polyfill.hasNativeSupport();
// Process specific CSS text
polyfill.processCSSText(cssText);Browser Support
The polyfill works in all modern browsers that support:
- ES6 (ECMAScript 2015)
- CSS Object Model
- MutationObserver
- matchMedia API
Tested browsers:
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
Performance Considerations
- The polyfill only activates when native CSS if() support is not available
- Uses efficient CSS parsing with minimal DOM manipulation
- Caches evaluation results for better performance
- Processes stylesheets incrementally to avoid blocking
- Optimized parsing for multiple conditions and complex shorthand properties
Examples
The package includes comprehensive examples:
examples/index.html- Basic CSS if() usageexamples/advanced.html- Advanced conditional stylingexamples/enhanced.html- Multiple if-tests and shorthand propertiesexamples/multiple-conditions.html- Multiple conditions within single if()
Contributing
Please have a look at our CONTRIBUTION guidelines.
License
MIT License - see LICENSE file for details.
Credits
- Pure JavaScript implementation with custom CSS parsing
- Inspired by the CSS Working Group's conditional CSS proposals
- Thanks to all contributors and testers
Related
- CSS Conditional Rules - MDN documentation for @media and @supports
Further solutions
- postcss-if-function - PostCSS plugin for build-time transformation
- lightningcss-plugin-if-function - Lightning CSS plugin for build-time transformation
- stylelint-config-if-function - Stylelint configuration for linting CSS if() usage
