CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cssutils

A CSS Cascading Style Sheets library for Python implementing DOM Level 2 Style specifications

Pending
Overview
Eval results
Files

selectors.mddocs/

CSS Selectors

Parse, validate, and manipulate CSS selectors with support for CSS3 selector syntax, pseudo-classes, pseudo-elements, and specificity calculations.

Capabilities

Selector Class

Individual CSS selector with parsing, validation, and specificity calculation.

class Selector:
    """
    Individual CSS selector implementing cssutils selector interface.
    """
    
    # Properties
    selectorText: str      # Complete selector text
    specificity: tuple     # Specificity as (a, b, c, d) tuple
    
    # Methods
    @property
    def selectorText():
        """Get/set selector text"""
    
    @selectorText.setter
    def selectorText(selectorText):
        """
        Set selector text with parsing and validation.
        
        Parameters:
        - selectorText (str): CSS selector text
        """
    
    @property
    def specificity():
        """
        Get selector specificity as (a, b, c, d) tuple.
        
        Returns:
        tuple: Specificity where:
        - a: inline styles (always 0 for selectors)  
        - b: IDs
        - c: classes, attributes, pseudo-classes
        - d: elements, pseudo-elements
        """
    
    def __str__():
        """String representation of selector"""
    
    def __repr__():
        """Debug representation of selector"""

SelectorList Class

Collection of CSS selectors (comma-separated selector group).

class SelectorList:
    """
    List of CSS selectors implementing cssutils SelectorList interface.
    """
    
    # Properties
    selectorText: str  # Complete selector list text (comma-separated)
    length: int        # Number of selectors in list
    
    # Access Methods
    def item(index):
        """
        Get selector at specified index.
        
        Parameters:
        - index (int): Selector index (0-based)
        
        Returns:
        Selector: Selector at index, or None if out of bounds
        """
    
    def __getitem__(index):
        """Get selector by index using bracket notation"""
    
    def __len__():
        """Get number of selectors"""
    
    def __iter__():
        """Iterator over selectors"""
    
    # Modification Methods
    def appendSelector(selector):
        """
        Add selector to end of list.
        
        Parameters:
        - selector (str/Selector): Selector to add
        """
    
    def insertSelector(selector, index):
        """
        Insert selector at specified index.
        
        Parameters:
        - selector (str/Selector): Selector to insert
        - index (int): Position to insert
        """
    
    def removeSelector(selector):
        """
        Remove selector from list.
        
        Parameters:
        - selector (str/Selector): Selector to remove
        """
    
    # Properties
    @property
    def selectorText():
        """Get/set complete selector list text"""
    
    @selectorText.setter
    def selectorText(selectorText):
        """
        Set selector list text with parsing.
        
        Parameters:
        - selectorText (str): Comma-separated selector list
        """

Usage Examples

Basic Selector Operations

import cssutils
from cssutils.css import Selector, SelectorList

# Parse individual selector
selector = Selector()
selector.selectorText = 'div.container > p:first-child'
print(f"Selector: {selector.selectorText}")
print(f"Specificity: {selector.specificity}")

# Parse selector list
selector_list = SelectorList()
selector_list.selectorText = 'h1, h2, h3.important'
print(f"Number of selectors: {len(selector_list)}")

# Access individual selectors
for i, sel in enumerate(selector_list):
    print(f"Selector {i}: {sel.selectorText} (specificity: {sel.specificity})")

Working with CSS Rules and Selectors

import cssutils

# Parse CSS with various selectors
css = """
body { margin: 0; }
#header { background: blue; }
.nav li a:hover { color: red; }
div > p:first-child { font-weight: bold; }
h1, h2, h3 { font-family: Arial; }
"""

sheet = cssutils.parseString(css)

# Examine selectors in style rules
for rule in sheet:
    if rule.type == rule.STYLE_RULE:
        print(f"Rule: {rule.selectorText}")
        
        # Access selector list
        selector_list = rule.selectorList
        print(f"  Number of selectors: {len(selector_list)}")
        
        # Access individual selectors
        for selector in selector_list:
            print(f"    Selector: {selector.selectorText}")
            print(f"    Specificity: {selector.specificity}")

Specificity Calculations

import cssutils
from cssutils.css import Selector

# Test different selector specificities
selectors = [
    '*',                    # (0,0,0,1) - universal
    'div',                  # (0,0,0,1) - element
    'div p',                # (0,0,0,2) - elements
    '.class',               # (0,0,1,0) - class
    'div.class',            # (0,0,1,1) - element + class
    '#id',                  # (0,1,0,0) - ID
    '#id.class',            # (0,1,1,0) - ID + class
    'div#id.class',         # (0,1,1,1) - element + ID + class
    'div > p.highlight',    # (0,0,1,2) - elements + class
    'a:hover',              # (0,0,1,1) - element + pseudo-class
    'a::before',            # (0,0,0,2) - element + pseudo-element
    '[type="text"]',        # (0,0,1,0) - attribute
    'div[class~="nav"]',    # (0,0,1,1) - element + attribute
]

for sel_text in selectors:
    selector = Selector()
    selector.selectorText = sel_text
    print(f"{sel_text:20} -> {selector.specificity}")

Modifying Selectors

import cssutils

# Parse stylesheet
css = """
.old-class { color: red; }
div.container { margin: 20px; }
"""

sheet = cssutils.parseString(css)

# Modify selectors
for rule in sheet:
    if rule.type == rule.STYLE_RULE:
        old_selector = rule.selectorText
        
        # Replace class name
        if '.old-class' in rule.selectorText:
            rule.selectorText = rule.selectorText.replace('.old-class', '.new-class')
            print(f"Changed: {old_selector} -> {rule.selectorText}")
        
        # Add additional selector
        elif rule.selectorText == 'div.container':
            rule.selectorText = 'div.container, section.container'
            print(f"Extended: {old_selector} -> {rule.selectorText}")

print(sheet.cssText)

Complex Selector Parsing

import cssutils
from cssutils.css import SelectorList

# Complex selectors with various CSS3 features
complex_selectors = [
    'input[type="email"]:valid',
    'article > section:nth-child(2n+1)',
    'nav ul li:not(.active)',
    'div.content ~ aside',
    'h2 + p::first-line',
    'table tbody tr:nth-last-child(-n+3)',
    '.sidebar a:matches([href^="http"],[href^="mailto"])',
]

for sel_text in complex_selectors:
    try:
        selector_list = SelectorList()
        selector_list.selectorText = sel_text
        
        print(f"Parsed: {sel_text}")
        for selector in selector_list:
            print(f"  Specificity: {selector.specificity}")
    except Exception as e:
        print(f"Error parsing '{sel_text}': {e}")

Selector List Manipulation

import cssutils
from cssutils.css import SelectorList, Selector

# Create and manipulate selector list
selector_list = SelectorList()

# Add selectors
selector_list.appendSelector('h1')
selector_list.appendSelector('.title')
selector_list.appendSelector('#main-title')

print(f"Selector list: {selector_list.selectorText}")
print(f"Count: {len(selector_list)}")

# Insert selector
selector_list.insertSelector('h2', 1)
print(f"After insert: {selector_list.selectorText}")

# Remove selector
selector_list.removeSelector('.title')
print(f"After remove: {selector_list.selectorText}")

# Set entire list at once
selector_list.selectorText = 'article h1, article h2, article h3'
print(f"New list: {selector_list.selectorText}")

# Access specific selectors
for i, selector in enumerate(selector_list):
    print(f"Selector {i}: {selector.selectorText} (specificity: {selector.specificity})")

Pseudo-class and Pseudo-element Handling

import cssutils

# CSS with various pseudo-classes and pseudo-elements
css = """
a:link { color: blue; }
a:visited { color: purple; }
a:hover, a:focus { color: red; }
input:required { border: 1px solid red; }
li:nth-child(odd) { background: #f0f0f0; }
p::first-letter { font-size: 2em; }
p::before { content: "→ "; }
::selection { background: yellow; }
"""

sheet = cssutils.parseString(css)

# Analyze pseudo-classes and pseudo-elements
for rule in sheet:
    if rule.type == rule.STYLE_RULE:
        selector_text = rule.selectorText
        print(f"Selector: {selector_text}")
        
        for selector in rule.selectorList:
            specificity = selector.specificity
            print(f"  Specificity: {specificity}")
            
            # Identify pseudo-classes vs pseudo-elements
            if '::' in selector_text:
                print("    Contains pseudo-elements")
            elif ':' in selector_text:
                print("    Contains pseudo-classes")

Install with Tessl CLI

npx tessl i tessl/pypi-cssutils

docs

css-rules.md

index.md

parsing.md

selectors.md

serialization.md

style-declarations.md

stylesheets.md

utilities.md

tile.json