What it is

FnCSS is a CSS parser and style computation engine for Elixir. It tokenizes and parses stylesheets, matches selectors against a document, runs the cascade, and produces computed values for each element. It can also serialize a stylesheet back to CSS text.

In the Fn* document pipeline it is the styling stage: FnHTML (on top of FnXML) produces the document, FnCSS computes each element's style, and FnLayout turns the styled tree into positioned boxes and draw commands.

Example

# Parse a stylesheet
{:ok, stylesheet} = FnCSS.parse("""
  .card {
    background: white;
    padding: 1rem;
  }
  .card:hover {
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  }
""")

# Serialize back to CSS, optionally minified
css_text = FnCSS.serialize(stylesheet)
css_min = FnCSS.serialize(stylesheet, minify: true)

# Parse individual values into tagged tuples
{:ok, length} = FnCSS.Values.parse("2.5rem")
# => {:ok, {:length, 2.5, :rem}}

{:ok, calc} = FnCSS.Values.parse("calc(100% - 20px)")
# => {:ok, {:calc, {:sub, {:percentage, 100}, {:length, 20, :px}}}}

FnCSS.compute_styles/2 takes a parsed document and a list of stylesheets and returns the computed style of every element. Values come back as plain data such as {:rgb, 255, 0, 0, 1.0} or {:length, 24, :px}.

What it covers

FnCSS works from these W3C specifications:

A CSSOM-style API reads and sets property values and edits inline style attributes.

Architecture

The stages are separate modules, each usable on its own: a tokenizer producing a stream of tokens, a parser producing a stylesheet AST, a selector matcher, the cascade, computed-style resolution backed by the values parser, and a serializer that turns any AST back into text. Selector parsing and matching are exposed directly (FnCSS.parse_selector/1, FnCSS.matches?/2, FnCSS.select/2), so the library can also be used to query documents.

Conformance

FnCSS passes its own internal conformance suite of 113 hand-written cases covering the tokenizer, parser, selectors and values. This is not a measurement against the W3C web-platform-tests; that comparison has not been done yet. The visual results reported by FnLayout exercise FnCSS indirectly, since every reftest goes through its cascade.

Status

FnCSS is at version 0.2 and under active development. It is not published to Hex, and builds against sibling checkouts of FnHTML and FnXML as path dependencies. MIT licensed.