Advanced CSS minification with modern features and 100% backward compatibility.
CSSminify2 provides powerful CSS compression using an enhanced YUI compressor engine with extensive modern CSS support. This native Ruby implementation eliminates Java dependencies while delivering state-of-the-art compression performance.
- π₯ Up to 63% compression ratios - Best-in-class performance
- π‘οΈ 100% backward compatibility - Existing code works unchanged
- β‘ Modern CSS support - Grid, Flexbox, Custom Properties, and more
- π― Advanced optimizations - Selector merging, shorthand optimization, variable inlining
- π§ Configurable features - Enable only the optimizations you need
- π Detailed statistics - Performance metrics and compression insights
- π Robust error handling - Graceful fallbacks for malformed CSS
- π¦ Zero dependencies - Pure Ruby implementation
Install CSSminify2 from RubyGems:
gem install cssminify2Or include it in your project's Gemfile:
gem 'cssminify2'require 'cssminify2'
# Simple compression - works exactly as before
CSSminify2.compress('/* comment */ .test { display: block; }')
# => ".test{display:block}"
# From file
CSSminify2.compress(File.read('styles.css'))
# With line length control
CSSminify2.compress(css_string, 200)
# Instance method
compressor = CSSminify2.new
compressor.compress(css_string)require 'cssminify2'
# Enhanced compression with modern features
result = CSSminify2.compress_enhanced(css, {
merge_duplicate_selectors: true,
optimize_shorthand_properties: true,
compress_css_variables: true,
advanced_color_optimization: true
})
# Get detailed statistics
stats = CSSminify2.compress_with_stats(css, {
merge_duplicate_selectors: true,
optimize_shorthand_properties: true
})
puts "Compressed: #{stats[:compressed_css]}"
puts "Original size: #{stats[:statistics][:original_size]}"
puts "Compressed size: #{stats[:statistics][:compressed_size]}"
puts "Compression ratio: #{stats[:statistics][:compression_ratio]}%"
puts "Selectors merged: #{stats[:statistics][:selectors_merged]}"All enhanced features are opt-in to maintain backward compatibility:
options = {
merge_duplicate_selectors: true, # Merge .btn{color:red} .btn{background:blue}
optimize_shorthand_properties: true, # margin:10px 10px 10px 10px β margin:10px
compress_css_variables: true, # Remove unused, inline single-use variables
advanced_color_optimization: true, # #FF0000 β red (with IE filter protection)
strict_error_handling: false, # Enable strict validation (default: false)
linebreakpos: 5000 # Maximum line length
}
result = CSSminify2.compress_enhanced(css, options)# Conservative (default) - all enhancements disabled
config = CSSminify2Enhanced::Configuration.conservative
# Aggressive - all optimizations enabled
config = CSSminify2Enhanced::Configuration.aggressive
# Modern - aggressive + statistics and modern features
config = CSSminify2Enhanced::Configuration.modern
compressor = CSSminify2Enhanced::Compressor.new(config)
result = compressor.compress(css)/* Input */
.btn { color: red; }
.btn { background: blue; }
.btn { color: green; } /* Overrides previous color */
/* Output */
.btn { color: green; background: blue; }/* Input */
.element {
margin: 10px 10px 10px 10px;
padding: 0.0px 0rem 0vh;
flex: 1 1 auto;
background: none repeat scroll 0 0 #FF0000;
}
/* Output */
.element {
margin: 10px;
padding: 0;
flex: 1;
background: red;
}/* Input */
:root {
--primary-color: #FF0000;
--unused-variable: #00FF00;
--single-use-margin: 10px;
--frequently-used-very-long-padding-value: 8rem;
}
.element {
color: var(--primary-color);
margin: var(--single-use-margin);
padding: var(--frequently-used-very-long-padding-value);
}
/* Output */
:root {
--primary-color: red;
--v1: 8rem;
}
.element {
color: var(--primary-color);
margin: 10px; /* Inlined single-use variable */
padding: var(--v1); /* Long name shortened */
}
/* --unused-variable removed *//* Input */
.container {
display: grid;
grid-gap: 20px 20px;
flex: 1 1 auto;
justify-content: flex-start;
align-items: center;
justify-items: center;
transform: translate(0, 0) rotate(0deg) scale(1, 1);
}
/* Output */
.container {
display: grid;
gap: 20px;
flex: 1;
justify-content: start;
place-items: center;
transform: translate(0) scale(1);
}| CSS Type | Original Size | Basic Compression | Enhanced Compression | Improvement |
|---|---|---|---|---|
| Bootstrap 5 | 275KB | 210KB (23.6%) | 165KB (40.0%) | +21.4% |
| Modern App CSS | 156KB | 122KB (21.8%) | 89KB (42.9%) | +27.0% |
| CSS Grid Layout | 45KB | 38KB (15.6%) | 28KB (37.8%) | +26.3% |
| CSS Variables Heavy | 67KB | 58KB (13.4%) | 29KB (56.7%) | +50.0% |
- Basic compression: ~2ms for 100KB CSS
- Enhanced compression: ~5ms for 100KB CSS
- Memory usage: <10MB for 1MB CSS files
CSSminify2 includes robust error handling for production use:
# Non-strict mode (default) - always succeeds with fallbacks
result = CSSminify2.compress_enhanced(malformed_css, {
strict_error_handling: false # default
})
# Strict mode - validates CSS and throws detailed errors
begin
result = CSSminify2.compress_enhanced(css, {
strict_error_handling: true
})
rescue CSSminify2Enhanced::MalformedCSSError => e
puts "CSS validation failed: #{e.message}"
puts "Errors found: #{e.css_errors}"
rescue CSSminify2Enhanced::EnhancedCompressionError => e
puts "Compression failed: #{e.message}"
puts "Original error: #{e.original_error}"
end- Enhanced optimization fails β Fall back to basic compression
- Basic compression fails β Fall back to safe whitespace compression
- All compression fails β Return original CSS with warning
Replace YUI compressor with CSSminify2:
# config/application.rb
config.assets.css_compressor = CSSminify2.new
# Or with enhanced features
config.assets.css_compressor = CSSminify2Enhanced::Compressor.new(
CSSminify2Enhanced::Configuration.aggressive
)require 'cssminify2'
require 'sprockets'
Sprockets.register_compressor 'text/css', :cssminify2, CSSminify2Use via Ruby bridge or consider the JavaScript port for Node.js environments.
#!/usr/bin/env ruby
require 'cssminify2'
Dir.glob('src/**/*.css').each do |file|
css = File.read(file)
stats = CSSminify2.compress_with_stats(css, {
merge_duplicate_selectors: true,
optimize_shorthand_properties: true,
compress_css_variables: true
})
output_file = file.sub('src/', 'dist/').sub('.css', '.min.css')
File.write(output_file, stats[:compressed_css])
puts "#{file}: #{stats[:statistics][:compression_ratio].round(1)}% compression"
endRun the comprehensive test suite:
# Run all tests
bundle exec rspec
# Run with Docker for clean environment
docker build -t cssminify-test .
docker run --rm cssminify-test rspec- β 95.8% YUI compressor compatibility (23/24 tests passing)
- β 100% backward compatibility maintained
- β 77 comprehensive test cases covering all features
- β Error handling test suite for robustness
- β Performance regression tests
No changes required - v2.x is 100% backward compatible:
# This code continues to work unchanged
CSSminify2.compress(css_string)
CSSminify2.compress(css_string, line_length)
compressor = CSSminify2.new
compressor.compress(css_string)Gradually adopt new features:
# Phase 1: Start with safe optimizations
result = CSSminify2.compress_enhanced(css, {
optimize_shorthand_properties: true
})
# Phase 2: Add selector merging
result = CSSminify2.compress_enhanced(css, {
optimize_shorthand_properties: true,
merge_duplicate_selectors: true
})
# Phase 3: Full optimization
result = CSSminify2.compress_enhanced(css, {
merge_duplicate_selectors: true,
optimize_shorthand_properties: true,
compress_css_variables: true,
advanced_color_optimization: true
})Problem: Enhanced features not working
# Solution: Ensure you're using the enhanced API
result = CSSminify2.compress_enhanced(css, options) # β
Correct
result = CSSminify2.compress(css, options) # β Won't use enhancementsProblem: CSS breaks after compression
# Solution: Enable strict mode to catch issues
result = CSSminify2.compress_enhanced(css, {
strict_error_handling: true
})Problem: Unexpected compression results
# Solution: Check statistics for details
stats = CSSminify2.compress_with_stats(css, options)
puts "Fallback used: #{stats[:statistics][:fallback_used]}"
puts "Optimizations applied: #{stats[:statistics]}"Enable warnings for detailed debugging:
# This will show warnings for any optimization failures
$VERBOSE = true
result = CSSminify2.compress_enhanced(css, options)- π₯ Advanced Compression: Up to 63% compression ratios (vs 22% in v1.x)
- π― Modern CSS Support: CSS Grid, Flexbox, Custom Properties, etc.
- π§ Configurable Optimizations: Enable only what you need
- π Detailed Statistics: Performance insights and metrics
- π Robust Error Handling: Production-ready reliability
CSSminify2.compress_enhanced(css, options)- Advanced compressionCSSminify2.compress_with_stats(css, options)- Compression with metrics- Configuration system with presets
- Individual optimization controls
- β calc() spacing preservation - No more broken calc() functions
- β Flex property protection - Flex shorthand values preserved correctly
- β Pseudo-selector spacing - Complex selectors maintain proper spacing
- β IE filter compatibility - Color optimization won't break IE filters
- β YUI compressor color optimization - Full color keyword support
We welcome contributions! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes with tests
- Run the test suite (
bundle exec rspec) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
git clone https://github.com/digitalsparky/cssminify.git
cd cssminify
bundle install
bundle exec rspec # Run testsRuby Versions:
- β Ruby 2.6+
- β Ruby 3.0+
- β JRuby 9.3+
- β TruffleRuby 22.0+
Frameworks:
- β Rails 5.0+
- β Sinatra
- β Sprockets 3.0+
- β Jekyll
- β Any Rack-based application
Basic CSS compression with YUI compressor compatibility.
Parameters:
css(String|IO): CSS content to compressline_length(Integer): Maximum output line length
Returns: (String) Compressed CSS
Instance method equivalent of class method.
Advanced CSS compression with configurable optimizations.
Parameters:
css(String|IO): CSS content to compressoptions(Hash): Configuration options
Options:
merge_duplicate_selectors(Boolean): Merge duplicate selectorsoptimize_shorthand_properties(Boolean): Optimize margin, padding, etc.compress_css_variables(Boolean): Optimize CSS custom propertiesadvanced_color_optimization(Boolean): Enhanced color compressionstrict_error_handling(Boolean): Enable strict CSS validationlinebreakpos(Integer): Maximum line length
Enhanced compression with detailed statistics.
Returns: (Hash)
compressed_css(String): Compressed CSS outputstatistics(Hash): Compression metrics and details
CSSminify2Enhanced::Configuration
.conservative- All features disabled (default).aggressive- All optimizations enabled.modern- Aggressive + additional modern features
CSSminify2Enhanced::Compressor
#initialize(config)- Create compressor with configuration#compress(css, line_length)- Compress with instance configuration#statistics- Access compression statistics
CSSminify2Enhanced::EnhancedCompressionError
- Raised when enhanced compression fails in strict mode
#original_error- Access underlying error
CSSminify2Enhanced::MalformedCSSError
- Raised when CSS validation fails in strict mode
#css_errors- Array of specific validation errors
Copyright (c) 2012 Matthias Siegel ([email protected])
Copyright (c) 2016 Matt Spurrier ([email protected])
See LICENSE for details.
See original YUI compressor license for details.
β If CSSminify2 helped you achieve better CSS compression, please give us a star!
π Found a bug? Have a feature request? Open an issue
π¬ Questions? Check our discussions or create a new one.