A CSS Cascading Style Sheets library for Python implementing DOM Level 2 Style specifications
—
Convert CSS objects back to formatted CSS text with extensive customization options for output formatting, indentation, and style preferences.
Main serialization class with configurable formatting preferences.
class CSSSerializer:
"""
CSS serialization with comprehensive formatting control.
Constructor:
CSSSerializer(prefs=None)
Parameters:
- prefs (Preferences): Formatting preferences object (uses defaults if None)
"""
# Properties
prefs: 'Preferences' # Formatting preferences
# Main Serialization Methods
def do_CSSStyleSheet(stylesheet):
"""
Serialize complete CSS stylesheet.
Parameters:
- stylesheet (CSSStyleSheet): Stylesheet to serialize
Returns:
str: Formatted CSS text
"""
def do_CSSStyleRule(rule):
"""
Serialize CSS style rule.
Parameters:
- rule (CSSStyleRule): Style rule to serialize
Returns:
str: Formatted CSS rule text
"""
def do_CSSMediaRule(rule):
"""
Serialize @media rule with nested rules.
Parameters:
- rule (CSSMediaRule): Media rule to serialize
Returns:
str: Formatted @media rule text
"""
def do_CSSImportRule(rule):
"""
Serialize @import rule.
Parameters:
- rule (CSSImportRule): Import rule to serialize
Returns:
str: Formatted @import rule text
"""
def do_CSSPageRule(rule):
"""
Serialize @page rule.
Parameters:
- rule (CSSPageRule): Page rule to serialize
Returns:
str: Formatted @page rule text
"""
def do_CSSFontFaceRule(rule):
"""
Serialize @font-face rule.
Parameters:
- rule (CSSFontFaceRule): Font-face rule to serialize
Returns:
str: Formatted @font-face rule text
"""
def do_CSSNamespaceRule(rule):
"""
Serialize @namespace rule.
Parameters:
- rule (CSSNamespaceRule): Namespace rule to serialize
Returns:
str: Formatted @namespace rule text
"""
def do_CSSCharsetRule(rule):
"""
Serialize @charset rule.
Parameters:
- rule (CSSCharsetRule): Charset rule to serialize
Returns:
str: Formatted @charset rule text
"""
def do_css_CSSStyleDeclaration(style, separator=None, omit=True):
"""
Serialize CSS style declarations.
Parameters:
- style (CSSStyleDeclaration): Style declarations to serialize
- separator (str): Property separator (default: uses preferences)
- omit (bool): Whether to omit last semicolon
Returns:
str: Formatted declarations text
"""
def do_CSSComment(comment):
"""
Serialize CSS comment.
Parameters:
- comment (CSSComment): Comment to serialize
Returns:
str: Formatted comment text
"""Serialization formatting preferences controlling output appearance.
class Preferences:
"""
Serialization formatting preferences for controlling CSS output appearance.
"""
# Basic Formatting
indent: str # Indentation string (default: ' ' - 4 spaces)
lineSeparator: str # Line ending character (default: '\\n')
omitLastSemicolon: bool # Omit semicolon after last property (default: True)
# Rule Formatting
keepEmptyRules: bool # Include empty rules in output (default: False)
keepComments: bool # Include CSS comments in output (default: True)
keepAllProperties: bool # Preserve all properties including duplicates (default: False)
# Property Formatting
defaultPropertyName: bool # Use normalized property names (default: True)
defaultAtKeyword: bool # Use default @keyword form (default: True)
# Value Formatting
minimizeColorHash: bool # Minimize color hashes #FFFFFF → #FFF (default: True)
# Advanced Options
lineNumbers: bool # Add line numbers to output (default: False)
validOnly: bool # Only output valid CSS (default: False)
# Methods
def __init__(**kwargs):
"""
Initialize preferences with custom values.
Parameters:
- **kwargs: Any preference property and its value
"""
def copy():
"""
Create copy of preferences.
Returns:
Preferences: Copy of current preferences
"""Global functions for setting and getting the default serializer.
def setSerializer(serializer):
"""
Set the global serializer used by all cssutils classes.
Parameters:
- serializer (CSSSerializer): Serializer instance to use globally
"""
def getSerializer():
"""
Get the current global serializer.
Returns:
CSSSerializer: Current global serializer instance
"""import cssutils
from cssutils.serialize import CSSSerializer
# Parse CSS
css = """
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
h1 {
color: #333;
font-size: 24px;
}
"""
sheet = cssutils.parseString(css)
# Use default serialization
print("Default serialization:")
print(sheet.cssText)
# Use custom serializer
serializer = CSSSerializer()
print("\nCustom serialization:")
print(serializer.do_CSSStyleSheet(sheet))import cssutils
from cssutils.serialize import CSSSerializer, Preferences
# Create custom preferences
prefs = Preferences(
indent=' ', # 2-space indent
lineSeparator='\n', # Unix line endings
omitLastSemicolon=False, # Keep all semicolons
keepEmptyRules=True, # Keep empty rules
minimizeColorHash=False, # Don't minimize colors
)
# Create serializer with preferences
serializer = CSSSerializer(prefs=prefs)
# Parse and serialize with custom formatting
css = """
body{margin:0;padding:0;color:#ffffff}
h1{color:red;}
.empty{}
"""
sheet = cssutils.parseString(css)
formatted = serializer.do_CSSStyleSheet(sheet)
print(formatted)import cssutils
from cssutils.serialize import CSSSerializer, Preferences
css = """
.navigation {
background-color: #333333;
border: 1px solid #666666;
margin: 0;
padding: 10px 20px;
}
"""
sheet = cssutils.parseString(css)
# Expanded format (default)
expanded_prefs = Preferences(
indent=' ',
omitLastSemicolon=True,
minimizeColorHash=False
)
expanded_serializer = CSSSerializer(prefs=expanded_prefs)
print("Expanded format:")
print(expanded_serializer.do_CSSStyleSheet(sheet))
# Compact format
compact_prefs = Preferences(
indent='',
lineSeparator='',
omitLastSemicolon=True,
minimizeColorHash=True
)
compact_serializer = CSSSerializer(prefs=compact_prefs)
print("\nCompact format:")
print(compact_serializer.do_CSSStyleSheet(sheet))import cssutils
from cssutils.serialize import CSSSerializer
css = """
@import url("base.css") screen;
@media print {
body { font-size: 12pt; }
}
h1 { color: blue; }
"""
sheet = cssutils.parseString(css)
serializer = CSSSerializer()
# Serialize individual rules
for i, rule in enumerate(sheet.cssRules):
print(f"Rule {i} ({rule.type}):")
if rule.type == rule.IMPORT_RULE:
print(serializer.do_CSSImportRule(rule))
elif rule.type == rule.MEDIA_RULE:
print(serializer.do_CSSMediaRule(rule))
elif rule.type == rule.STYLE_RULE:
print(serializer.do_CSSStyleRule(rule))
print()import cssutils
from cssutils.serialize import CSSSerializer
# Create style declaration
style = cssutils.css.CSSStyleDeclaration()
style.setProperty('color', 'red')
style.setProperty('margin', '10px 20px')
style.setProperty('font-weight', 'bold', 'important')
serializer = CSSSerializer()
# Different serialization options
print("Normal:")
print(serializer.do_css_CSSStyleDeclaration(style))
print("\nWith custom separator:")
print(serializer.do_css_CSSStyleDeclaration(style, separator='; '))
print("\nWithout omitting last semicolon:")
print(serializer.do_css_CSSStyleDeclaration(style, omit=False))import cssutils
from cssutils.serialize import CSSSerializer, Preferences
# Create custom global serializer
custom_prefs = Preferences(
indent=' ',
minimizeColorHash=True,
keepComments=False
)
custom_serializer = CSSSerializer(prefs=custom_prefs)
# Set as global serializer
cssutils.setSerializer(custom_serializer)
# All cssutils objects now use custom serializer
css = """
/* This comment will be removed */
body {
color: #ffffff; /* This becomes #fff */
margin: 0;
}
"""
sheet = cssutils.parseString(css)
print("With custom global serializer:")
print(sheet.cssText)
# Reset to default
cssutils.setSerializer(cssutils.CSSSerializer())import cssutils
from cssutils.serialize import CSSSerializer
# CSS with various constructs
css = """
@charset "utf-8";
@namespace svg "http://www.w3.org/2000/svg";
@import "base.css";
@media screen and (max-width: 768px) {
body { font-size: 14px; }
}
@page :first {
margin-top: 2in;
}
@font-face {
font-family: 'Custom';
src: url('custom.woff');
}
/* Main styles */
body {
margin: 0;
color: #333;
}
svg|rect {
fill: blue;
}
"""
sheet = cssutils.parseString(css)
serializer = CSSSerializer()
print("Complete stylesheet serialization:")
print(serializer.do_CSSStyleSheet(sheet))import cssutils
from cssutils.serialize import CSSSerializer, Preferences
# Enable line numbers for debugging
debug_prefs = Preferences(
lineNumbers=True,
keepComments=True
)
debug_serializer = CSSSerializer(prefs=debug_prefs)
css = """
body {
margin: 0;
padding: 0;
}
h1 {
color: blue;
}
"""
sheet = cssutils.parseString(css)
print("With line numbers:")
print(debug_serializer.do_CSSStyleSheet(sheet))import cssutils
from cssutils.serialize import CSSSerializer, Preferences
# CSS with duplicate properties (for browser compatibility)
css = """
.box {
background: red; /* Fallback */
background: linear-gradient(to bottom, red, blue);
border-radius: 5px; /* Standard */
-webkit-border-radius: 5px; /* Webkit prefix */
-moz-border-radius: 5px; /* Mozilla prefix */
}
"""
sheet = cssutils.parseString(css)
# Default behavior (removes duplicates)
default_serializer = CSSSerializer()
print("Default (removes duplicates):")
print(default_serializer.do_CSSStyleSheet(sheet))
# Keep all properties
preserve_prefs = Preferences(keepAllProperties=True)
preserve_serializer = CSSSerializer(prefs=preserve_prefs)
print("\nKeeping all properties:")
print(preserve_serializer.do_CSSStyleSheet(sheet))Install with Tessl CLI
npx tessl i tessl/pypi-cssutils