A Python port of YUI CSS Compressor for minifying CSS stylesheets
npx @tessl/cli install tessl/pypi-csscompressor@0.9.0A Python port of YUI CSS Compressor that provides comprehensive CSS minification and compression capabilities. CSS Compressor removes unnecessary whitespace, comments, and redundant code while optimizing colors, properties, and syntax to produce smaller CSS files with identical functionality.
pip install csscompressorfrom csscompressor import compress, compress_partitionedModule import:
import csscompressor
# Use: csscompressor.compress()from csscompressor import compress
# Basic CSS compression
css_input = '''
body {
background-color: #ffffff;
color: rgba(0, 0, 0, 1);
margin: 0px 0px 0px 0px;
}
.header {
font-size: 1.0em;
padding: 10px;
}
'''
compressed = compress(css_input)
print(compressed)
# Output: body{background-color:#fff;color:#000;margin:0}.header{font-size:1em;padding:10px}
# Compress with line length limit for source control
compressed_wrapped = compress(css_input, max_linelen=80)
# Preserve important comments
css_with_comments = '''
/*! Important copyright notice */
/* Regular comment that will be removed */
body { color: red; }
'''
compressed_with_preserved = compress(css_with_comments, preserve_exclamation_comments=True)CSS Compressor can be used directly from the command line:
# Compress a single file to stdout
python -m csscompressor styles.css
# Compress multiple files (concatenated with double newlines) with line breaks
python -m csscompressor file1.css file2.css --line-break 80
# Output to a specific file
python -m csscompressor input.css -o compressed.css
# Get help
python -m csscompressor --helpCommand line arguments:
input: One or more CSS files to compress (files are concatenated with \n\n before compression)--line-break <column>: Insert line break after specified column number-o, --output <file>: Write output to file instead of stdoutNote: The command line interface always uses preserve_exclamation_comments=True and processes multiple input files by concatenating them with double newlines before compression.
Compresses CSS stylesheets into a single optimized string with extensive minification features.
def compress(css, max_linelen=0, preserve_exclamation_comments=True):
"""Compress given CSS stylesheet.
Parameters:
- css : str
An str with CSS rules.
- max_linelen : int = 0
Some source control tools don't like it when files containing lines longer
than, say 8000 characters, are checked in. This option is used in
that case to split long lines after a specific column.
- preserve_exclamation_comments : boolean = True
Some stylesheets contain /*! ... */ comment block which used for copyright
notices or else. By default compress dont remove them like other comment
blocks. It will lead to bigger file size. but once you decide to remove
them just set this parameter to False.
Returns a ``str`` object with compressed CSS.
Raises:
ValueError: For malformed CSS (unbalanced braces, malformed url() or calc() expressions)
"""Compresses CSS into multiple strings to work around Internet Explorer's 4096 rule limit per stylesheet file.
def compress_partitioned(css,
max_linelen=0,
max_rules_per_file=4000,
preserve_exclamation_comments=True):
"""Compress given CSS stylesheet into a set of files.
Parameters:
- css : str
CSS rules to compress
- max_linelen : int = 0
Has the same meaning as for "compress()" function.
- max_rules_per_file : int = 4000
Internet Explorers <= 9 have an artificial max number of rules per CSS
file (4096; http://blogs.msdn.com/b/ieinternals/archive/2011/05/14/10164546.aspx)
When ``max_rules_per_file`` is a positive number, the function *always* returns
a list of ``str`` objects, each limited to contain less than the passed number
of rules.
- preserve_exclamation_comments : boolean = True
Has the same meaning as for "compress()" function.
Always returns a ``list`` of ``str`` objects with compressed CSS.
Raises:
ValueError: For malformed CSS (unbalanced braces)
AssertionError: If max_rules_per_file is not positive
"""CSS Compressor performs numerous optimizations to reduce file size:
rgb(51,102,153) to #336699#AABBCC to #ABC when possible#f00 to red for common colors)hsl() and hsla()0px, 0em, 0% to just 00.5 to .5, -0.5 to -.5)margin: 0 0 0 0 to margin: 0)background-position and transform-origin valuescalc() expressions with proper whitespaceurl() data URIs and file paths correctlyprogid:DXImageTransform.Microsoft filters-o-device-pixel-ratio for OperaThe compressor validates CSS syntax and raises errors for malformed input:
ValueError Conditions:
url() expressions without proper closingcalc() expressions without proper structureAssertionError Conditions:
max_rules_per_file parameter is not positive (≤ 0) in compress_partitioned()Common error scenarios:
# Unbalanced braces - missing closing brace
compress("body { color: red") # Raises ValueError: malformed css
# Malformed url() without closing parenthesis
compress("body { background: url('image.png' }") # Raises ValueError: malformed css
# Invalid calc() expression structure
compress("div { width: calc(10px- }") # Raises ValueError: malformed css
# Invalid max_rules_per_file parameter
compress_partitioned("body{}", max_rules_per_file=0) # Raises AssertionError
# Unbalanced braces in partitioned compression
compress_partitioned("body { color: red") # Raises ValueError: malformed CSS: non-balanced curly-bracesError Sources:
_preserve_call_tokens(): Malformed url() or calc() expressionscompress_partitioned(): Invalid max_rules_per_file parameter assertioncompress_partitioned(): Unbalanced curly braces during partitioning# Long lines can cause issues with some source control tools
css = "body { /* very long CSS rule */ }"
compressed = compress(css, max_linelen=120)# Process multiple CSS files for production
css_files = ['base.css', 'components.css', 'theme.css']
all_css = []
for file_path in css_files:
with open(file_path, 'r') as f:
all_css.append(f.read())
# Combine and compress all CSS
combined_css = '\n\n'.join(all_css)
compressed = compress(combined_css, preserve_exclamation_comments=True)
# Write to production file
with open('dist/styles.min.css', 'w') as f:
f.write(compressed)# Split CSS for IE compatibility (4096 rule limit)
large_css = open('large-stylesheet.css').read()
css_parts = compress_partitioned(large_css, max_rules_per_file=4000)
# Write multiple files for IE
for i, css_part in enumerate(css_parts):
with open(f'styles-{i+1}.min.css', 'w') as f:
f.write(css_part)The package version can be accessed programmatically:
import csscompressor
print(csscompressor.__version__) # Returns '0.9.4'Note: The __version__ constant in the source code shows '0.9.4' while setup.py may show different version numbers due to development versioning practices. The source code __version__ is the authoritative version identifier.