A CSS Cascading Style Sheets library for Python implementing DOM Level 2 Style specifications
—
Complete implementation of CSS rule types including style rules, @-rules, and nested structures. All rules implement DOM Level 2 CSS interfaces with proper inheritance and containment.
Base class for all CSS rules providing common properties and methods.
class CSSRule:
"""
Base class for all CSS rules implementing DOM Level 2 CSSRule interface.
"""
# Rule Type Constants
UNKNOWN_RULE = 0
STYLE_RULE = 1
CHARSET_RULE = 2
IMPORT_RULE = 3
MEDIA_RULE = 4
FONT_FACE_RULE = 5
PAGE_RULE = 6
NAMESPACE_RULE = 10
MARGIN_RULE = 1006 # cssutils extension
COMMENT = 1001 # cssutils extension
VARIABLES_RULE = 1008 # cssutils extension
# Properties
type: int # Rule type constant
cssText: str # Complete CSS text of rule
parentRule: 'CSSRule' # Parent rule (for nested rules)
parentStyleSheet: 'CSSStyleSheet' # Containing stylesheetStandard CSS style rule with selector and property declarations.
class CSSStyleRule:
"""
CSS style rule (selector { declarations }) implementing DOM Level 2 CSSStyleRule.
"""
# Properties
selectorText: str # Selector text
style: 'CSSStyleDeclaration' # Property declarations
# Methods
@property
def selectorText():
"""Get/set selector text"""
@selectorText.setter
def selectorText(selectorText):
"""Set selector text with parsing and validation"""@charset rule specifying character encoding.
class CSSCharsetRule:
"""
@charset rule implementing DOM Level 2 CSSCharsetRule.
"""
# Properties
encoding: str # Character encoding name
# Methods
@property
def encoding():
"""Get/set character encoding"""
@encoding.setter
def encoding(encoding):
"""Set character encoding with validation"""@import rule for importing external stylesheets.
class CSSImportRule:
"""
@import rule implementing DOM Level 2 CSSImportRule.
"""
# Properties
href: str # URL of imported stylesheet
media: 'MediaList' # Media query list
styleSheet: 'CSSStyleSheet' # Imported stylesheet (if loaded)
hrefFound: bool # Whether href was successfully resolved
# Methods
@property
def href():
"""Get/set import URL"""
@href.setter
def href(href):
"""Set import URL"""@media rule with nested rules for specific media conditions.
class CSSMediaRule:
"""
@media rule implementing DOM Level 2 CSSMediaRule.
"""
# Properties
media: 'MediaList' # Media query list
cssRules: 'CSSRuleList' # Nested rules
# Rule Management
def insertRule(rule, index):
"""
Insert rule at specified index.
Parameters:
- rule (str/CSSRule): Rule to insert
- index (int): Position to insert
Returns:
int: Index where rule was inserted
"""
def deleteRule(index):
"""Delete rule at specified index"""
def add(rule):
"""Add rule to end of media rule"""@page rule for paged media styling.
class CSSPageRule:
"""
@page rule implementing DOM Level 2 CSSPageRule.
"""
# Properties
selectorText: str # Page selector (:left, :right, :first, etc.)
style: 'CSSStyleDeclaration' # Page box properties
# Methods
@property
def selectorText():
"""Get/set page selector"""
@selectorText.setter
def selectorText(selectorText):
"""Set page selector with validation"""Margin rules within @page rules (e.g., @top-left, @bottom-center).
class MarginRule:
"""
Margin rule for @page contexts (cssutils extension).
"""
# Properties
margin: str # Margin area name (@top-left, etc.)
style: 'CSSStyleDeclaration' # Margin box properties
# Methods
@property
def margin():
"""Get/set margin area name"""
@margin.setter
def margin(margin):
"""Set margin area with validation"""@font-face rule for custom font definitions.
class CSSFontFaceRule:
"""
@font-face rule implementing DOM Level 2 CSSFontFaceRule.
"""
# Properties
style: 'CSSStyleDeclaration' # Font descriptors (src, font-family, etc.)@namespace rule for XML namespace declarations.
class CSSNamespaceRule:
"""
@namespace rule implementing CSSOM CSSNamespaceRule.
"""
# Properties
namespaceURI: str # Namespace URI
prefix: str # Namespace prefix (may be None for default namespace)
# Methods
@property
def namespaceURI():
"""Get/set namespace URI"""
@namespaceURI.setter
def namespaceURI(namespaceURI):
"""Set namespace URI with validation"""
@property
def prefix():
"""Get/set namespace prefix"""
@prefix.setter
def prefix(prefix):
"""Set namespace prefix"""CSS Variables rule (experimental, cssutils extension).
class CSSVariablesRule:
"""
CSS Variables rule (cssutils extension for CSS Variables draft).
"""
# Properties
media: 'MediaList' # Media query list
variables: 'CSSVariablesDeclaration' # Variable declarationsUnknown @-rule for handling unrecognized at-rules.
class CSSUnknownRule:
"""
Unknown @-rule for unrecognized at-rules.
"""
# Properties
cssText: str # Complete text of unknown ruleCSS comment (cssutils extension).
class CSSComment:
"""
CSS comment (cssutils extension).
"""
# Properties
cssText: str # Comment text including /* */ delimitersimport cssutils
from cssutils.css import CSSStyleRule
# Parse style rules
css = """
body { margin: 0; padding: 0; }
h1 { color: blue; font-size: 24px; }
.highlight { background: yellow; }
"""
sheet = cssutils.parseString(css)
# Access style rules
for rule in sheet:
if rule.type == rule.STYLE_RULE:
print(f"Selector: {rule.selectorText}")
print(f"Declarations: {rule.style.cssText}")
# Modify selector
if rule.selectorText == 'h1':
rule.selectorText = 'h1, h2'
# Modify properties
rule.style.setProperty('line-height', '1.5')
# Create new style rule
rule = CSSStyleRule()
rule.selectorText = 'p.intro'
rule.style.cssText = 'font-weight: bold; color: #333;'
sheet.add(rule)import cssutils
from cssutils.css import CSSMediaRule, CSSStyleRule
# Parse media rules
css = """
@media screen and (max-width: 768px) {
body { font-size: 14px; }
.sidebar { display: none; }
}
"""
sheet = cssutils.parseString(css)
# Access media rule
media_rule = sheet.cssRules[0]
print(f"Media: {media_rule.media.mediaText}")
# Add rule to media rule
new_rule = CSSStyleRule()
new_rule.selectorText = '.mobile-only'
new_rule.style.display = 'block'
media_rule.add(new_rule)
# Create new media rule
media_rule = CSSMediaRule()
media_rule.media.mediaText = 'print'
style_rule = CSSStyleRule()
style_rule.selectorText = 'body'
style_rule.style.fontSize = '12pt'
media_rule.add(style_rule)
sheet.add(media_rule)import cssutils
# Parse import rules
css = """
@import url("base.css");
@import "layout.css" screen;
@import "print.css" print;
"""
sheet = cssutils.parseString(css)
# Access import rules
for rule in sheet:
if rule.type == rule.IMPORT_RULE:
print(f"Import: {rule.href}")
print(f"Media: {rule.media.mediaText}")
if rule.styleSheet:
print(f"Loaded: {len(rule.styleSheet.cssRules)} rules")import cssutils
from cssutils.css import CSSPageRule, MarginRule
# Parse page rules
css = """
@page {
margin: 1in;
size: letter;
}
@page :first {
margin-top: 2in;
}
@page {
@top-left {
content: "Document Title";
}
@bottom-center {
content: counter(page);
}
}
"""
sheet = cssutils.parseString(css)
# Access page rules
for rule in sheet:
if rule.type == rule.PAGE_RULE:
print(f"Page selector: {rule.selectorText}")
print(f"Properties: {rule.style.cssText}")
# Access margin rules
for margin_rule in rule.cssRules:
if isinstance(margin_rule, MarginRule):
print(f"Margin {margin_rule.margin}: {margin_rule.style.cssText}")import cssutils
# Parse font-face rules
css = """
@font-face {
font-family: 'MyFont';
src: url('myfont.woff2') format('woff2'),
url('myfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
"""
sheet = cssutils.parseString(css)
# Access font-face rule
font_rule = sheet.cssRules[0]
print(f"Font family: {font_rule.style.getPropertyValue('font-family')}")
print(f"Sources: {font_rule.style.getPropertyValue('src')}")import cssutils
# Parse namespace rules
css = """
@namespace "http://www.w3.org/1999/xhtml";
@namespace svg "http://www.w3.org/2000/svg";
div { color: blue; }
svg|rect { fill: red; }
"""
sheet = cssutils.parseString(css)
# Access namespace rules
for rule in sheet:
if rule.type == rule.NAMESPACE_RULE:
print(f"Prefix: {rule.prefix}")
print(f"URI: {rule.namespaceURI}")
# Access stylesheet namespaces
for prefix, uri in sheet.namespaces.items():
print(f"Namespace {prefix}: {uri}")import cssutils
css = """
@charset "utf-8";
@import "base.css";
@media screen { body { margin: 0; } }
@page { margin: 1in; }
@font-face { font-family: 'Custom'; src: url('custom.woff'); }
/* Comment */
body { color: black; }
"""
sheet = cssutils.parseString(css)
# Handle all rule types
for rule in sheet:
if rule.type == rule.CHARSET_RULE:
print(f"Charset: {rule.encoding}")
elif rule.type == rule.IMPORT_RULE:
print(f"Import: {rule.href}")
elif rule.type == rule.MEDIA_RULE:
print(f"Media: {rule.media.mediaText} ({len(rule.cssRules)} nested rules)")
elif rule.type == rule.PAGE_RULE:
print(f"Page: {rule.selectorText}")
elif rule.type == rule.FONT_FACE_RULE:
print("Font-face rule")
elif rule.type == rule.STYLE_RULE:
print(f"Style: {rule.selectorText}")
elif rule.type == rule.COMMENT:
print(f"Comment: {rule.cssText}")
else:
print(f"Unknown rule type: {rule.type}")Install with Tessl CLI
npx tessl i tessl/pypi-cssutils