sabberworm/php-css-parser
A PHP library that parses CSS files into a manipulable data structure, allowing programmatic editing of rules and declarations before outputting optimized CSS. Supports custom charsets, strict parsing and optional multi-byte functions. Install via Composer.
font-*, cursor, IE filter), halving/normalizing absolute sizes, rewriting theme colors, re-rendering pretty or compact.Selector carries a specificity slot that is not populated, and there is no @media evaluation or cascade resolution — so critical-CSS extraction, unused-CSS elimination, and "computed style" features must not be scoped onto this package in planning.Adopt when:
Look elsewhere when:
@layer, @container, nesting, custom-property-aware transforms) — validate coverage against your real corpus first, not against the README examples.mb_* functions as a speed lever while warning about correctness, which tells you parsing throughput is a real constraint.Adoption gate before committing:
render() against input. Output is normalized (e.g., #rrggbb becomes rgb(...), URLs get quoted) — round-trip is not byte-identical. Get stakeholder sign-off on this early; it is the most common surprise.@import, url(javascript:), and legacy expression() are structural, not policy. If the feature is "customers upload CSS," budget the whitelist layer as its own work item.To executives: A small, free, MIT-licensed PHP library that lets our backend treat CSS as structured data instead of text. It unlocks styling features we currently can't ship — per-tenant style scoping, brand token rewrites, legacy rule cleanup, and per-channel CSS output — with no new infrastructure, no Node service, and no parser to maintain ourselves. Cost is measured in days of engineering plus one Composer dependency; the risk is bounded because every transform stays behind our own interface and can be swapped out.
To engineering: Treat it as the AST layer, never the policy layer. The seam is Parser → Document → CSSList / RuleSet / Rule / Value → render(OutputFormat); whitelisting, sanitization, and any cascade logic stay in our code, because the package deliberately stops at structure. Expect normalized output rather than byte-identical round-trips, pin the version, run strict parsing in tests to surface malformed input, and keep each transform a pure, separately tested function so a future migration to a PostCSS-based pipeline is a swap, not a rewrite.
How can I help you explore Laravel packages today?