{"id":586,"library":"tinycss2","title":"Tinycss2","description":"tinycss2 is a low-level CSS parser and generator written in Python. It can parse CSS strings, return objects representing tokens and blocks, and generate CSS strings from these objects. Based on the CSS Syntax Level 3 specification, it handles the grammar of CSS but does not know specific rules, properties, or values. It is actively maintained with regular releases.","status":"active","version":"1.5.1","language":"python","source_language":"en","source_url":"https://github.com/Kozea/tinycss2/","tags":["css","parsing","frontend","web"],"install":[{"cmd":"pip install tinycss2","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Character encoding aliases for legacy web content.","package":"webencodings","optional":false}],"imports":[{"note":"Primary function for parsing full CSS stylesheets.","symbol":"parse_stylesheet","correct":"import tinycss2\nrules = tinycss2.parse_stylesheet('body { color: red; }')"},{"note":"While often not directly imported, AST node classes reside in the `tinycss2.ast` module for inspection and manipulation of parsed output.","symbol":"ast nodes (e.g., QualifiedRule, IdentToken)","correct":"from tinycss2.ast import QualifiedRule, IdentToken"}],"quickstart":{"code":"import tinycss2\n\ncss_input = '#my-id div { width: 50%; height: 100px }'\nrules = tinycss2.parse_stylesheet(css_input)\n\n# The parsed output is a list of nodes\nfor rule in rules:\n    if rule.type == 'qualified-rule':\n        print(f\"Qualified Rule: {rule.prelude[0].value} {rule.prelude[2].value}\") # Example: 'my-id', 'div'\n        for declaration in tinycss2.parse_declaration_list(rule.content):\n            if declaration.type == 'declaration':\n                print(f\"  Declaration: {declaration.name}: {declaration.value[0].value}{declaration.value[0].unit}\")\n\n# To serialize back to CSS (approximate)\nserialized_css = ''.join(node.serialize() for node in rules)\nprint(f\"\\nSerialized CSS: {serialized_css}\")","lang":"python","description":"Parses a CSS string into an Abstract Syntax Tree (AST) of tokens and blocks, then iterates through the parsed rules and declarations."},"warnings":[{"fix":"Use `tinycss2.parse_blocks_contents` instead for parsing declaration lists.","message":"The `tinycss2.parse_declaration_list` function was deprecated in v1.3.0.","severity":"deprecated","affected_versions":">=1.3.0"},{"fix":"Ensure your project uses Python 3.10 or a more recent compatible version.","message":"Python 3.6 support was dropped in v1.2.0, and Python 3.5 support in v1.1.0. The library currently requires Python 3.10 or newer.","severity":"breaking","affected_versions":">=1.2.0"},{"fix":"Users are expected to build their own higher-level logic on top of tinycss2's parsed output if they need to interpret CSS rules beyond their grammatical structure.","message":"tinycss2 is a low-level CSS parser. It understands CSS syntax (tokens, blocks, qualified rules, at-rules) but does not interpret the semantics of specific CSS properties, values, or selectors. It does not provide high-level representations of browser-rendered styles.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If upgrading from very old versions and expecting comments/whitespace to be omitted, pass `skip_comments=True` and `skip_whitespace=True` to parsing functions like `parse_stylesheet` or `parse_declaration_list`.","message":"In tinycss2 v0.5, the default behavior for parsing functions changed to preserve CSS comments and top-level whitespace in the output AST. Previously, these were skipped by default.","severity":"breaking","affected_versions":">=0.5"}],"env_vars":null,"last_verified":"2026-05-12T16:21:25.847Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the tinycss2 package using pip: `pip install tinycss2`","cause":"The tinycss2 library is not installed in your current Python environment.","error":"ModuleNotFoundError: No module named 'tinycss2'"},{"fix":"Ensure the input to the parsing function is a `str` (for `parse_stylesheet`) or `bytes` (for `parse_stylesheet_bytes`) object. For example, `css_string = '.selector { color: red; }'`.","cause":"Parsing functions like `tinycss2.parse_stylesheet()` expect a string or bytes object as input, but received an incompatible type.","error":"TypeError: argument must be a string or bytes, not <class 'int'>"},{"fix":"Iterate over the returned list to access attributes of individual tokens: `for token in tinycss2.parse_stylesheet(css_string): print(token.type)`","cause":"The `tinycss2.parse_stylesheet()` function returns a list of tokens, not a single token object, so you must iterate over the list to access individual token attributes like `type` or `value`.","error":"AttributeError: 'list' object has no attribute 'type'"},{"fix":"Use the correct import and function name: `from tinycss2 import parse_stylesheet`","cause":"The function name `parse_stylesheet_string` does not exist in the `tinycss2` module; the correct function for parsing a CSS string is `parse_stylesheet`.","error":"ImportError: cannot import name 'parse_stylesheet_string' from 'tinycss2'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":"1.5.1","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"18.1M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"18.1M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"20.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"20.0M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.7,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"11.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"11.9M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"11.6M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"11.5M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.4,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"17.6M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"17.6M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.8,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}