package cascade

  1. Overview
  2. Docs
CSS generation and manipulation library for OCaml

Install

dune-project
 Dependency

Authors

Maintainers

Sources

cascade-1.0.0.tbz
sha256=c11bbdc7ab0eee8c03cd162e3e7fd1cb20de62beb13342b3b150a89264ee0056
sha512=43fd97a55c3b1dc4db5c87aa1a5a047d902e902ab2064af3a7c5bf945ebc333f8cd90ecca8013c17be5b950498eace8e0094ee4319eba408285e2bec8d7cdf7b

doc/CHANGES.html

1.0.0

First public release. Cascade was extracted from the tw (Tailwind CSS v4 in OCaml) project as a standalone CSS command-line tool and library, then stabilised over several internal milestones.

Library

  • Typed CSS AST: selectors, declarations, values, statements, and stylesheets are sealed ADTs. Invalid constructions are caught at compile time.
  • Single warning-aware parse entry point:

    • Css.of_string runs CSS Syntax Level 3 recovery and returns (parse, Error.t) result, where parse = { stylesheet; warnings }.
    • ~strict:true promotes the first warning to Error _.
    • Css.of_string_exn returns the recovered stylesheet directly and raises Error.Parse_error on Error.
  • Pretty-printer with separate pretty and minified contexts (Css.to_string ?minify), with several typed printers exposed (pp_color, pp_length, ...).
  • Structural transforms (fold, map, sort, flatten_nesting, inline_imports) and structural CSS diff utilities via the cascade.diff sub-library.
  • Optimizer with deduplication, rule merging, selector combining, and shorthand/longhand coverage including all reset folding. Rule merging is order-independent: rules are scheduled through a conflict DAG so cascade-safe reorderings converge on the same output regardless of source order.
  • Minification optimises estimated compressed (gzip) transfer size by default: a global factoring that shrinks raw bytes but would grow the compressed output is not applied. Pass ~objective:\Raw(CLI--objective=raw`) to optimise raw bytes instead, for output that ships uncompressed.
  • Spec coverage:

    • Selectors Level 4 -- including :has(), :is(), :where(), :not(), nesting &, and full attribute syntax.
    • Values & Units Level 4 -- calc(), clamp(), min(), max(), minmax(), the modern length units, durations, angles.
    • Color Level 4 -- 15 colour spaces including oklch(), oklab(), lch(), hwb(), color-mix(), plus the 148 named colours.
    • Conditional Rules Level 3-5 -- @media, @supports, @container (including typed style()/scroll-state() queries with range operators), @when / @else.
    • Cascade Level 5 -- @layer declarations and blocks, CSS-wide keywords, and all reset semantics in the optimizer.
    • Custom Properties Level 1 -- var() parsing/printing, typed fallbacks, theme/default substitution, @property registration.
    • Fonts Level 4 (@font-face descriptors), Animations Level 1 (@keyframes, @starting-style).
  • Over 400 typed properties cover box model, flexbox, grid (including grid-template-areas validation), logical properties, typography (font-variant-*, text-emphasis-*, text-decoration-skip-*, initial-letter*), borders and border-image, backgrounds and gradients, transforms (translate, scale, rotate, transform), transitions, animations (animation-range*, scroll-driven timelines), filters, masks, scroll snap, anchor positioning (position-anchor, position-area, position-try-fallbacks), view transitions, and the common vendor-prefixed properties.
  • Custom-property workflows: typed <syntax> parsing for @property, registered-property substitution against an explicit Css.Context.t, and round-trip-stable var() serialisation with literal fallbacks.

CLI tools

  • cascade -- pretty-print and minify CSS files. It accepts stdin via - or a missing file argument, and writes output to stdout.
  • cascade --minify applies the standard safe transforms, including deduplication, rule merging, selector grouping, empty-rule elimination, and nested-rule flattening, optimising estimated gzip transfer size by default (--objective=raw optimises raw bytes instead).
  • cascade --inline-imports resolves local @import rules relative to the input file, and cascade --inline-vars substitutes static custom-property references. --keep-vars=NAMES preserves selected custom properties.
  • cascade diff provides structural CSS diffing between two files with auto, tree, string, and canonical modes; respects NO_COLOR, CASCADE_COLOR, and --color, and colours only when stdout is a tty. Identical files exit 0 and differing files exit 1, so the command slots into CI checks and git hooks. The canonical mode projects both sheets to a normal form first, so equivalent factorings -- different rule grouping, cascade-safe rule and declaration order -- compare identical rather than as spurious changes.
  • The CLI is installable as a binary through the Homebrew tap samoht/tap/cascade, with opam installation still available for OCaml users.

Notes

  • cascade parses already-decoded UTF-8 strings. The CSS Syntax Level 3 byte-stream decoding step (BOM handling, @charset byte sniffing, HTTP/environment charset fallback) is the caller's responsibility.
  • CSS nesting round-trips through the parser and printer, and the minifier flattens nested rules when safe.
  • @import rules are preserved by default. Use --inline-imports for explicit closed-world filesystem inlining.
  • No source-map support.