#tokenize #css-parser #css #nested

azul-simplecss

A very simple CSS 2.1 tokenizer with CSS nesting support

4 releases

0.2.0 Feb 14, 2026
0.1.2 Nov 29, 2025
0.1.1 Jul 7, 2019
0.1.0 Jul 7, 2019

#196 in Web programming

Download history 1552/week @ 2025-12-28 1737/week @ 2026-01-04 1892/week @ 2026-01-11 2013/week @ 2026-01-18 1688/week @ 2026-01-25 1399/week @ 2026-02-01 1361/week @ 2026-02-08 1971/week @ 2026-02-15 1636/week @ 2026-02-22 2406/week @ 2026-03-01 2548/week @ 2026-03-08 2794/week @ 2026-03-15 3417/week @ 2026-03-22 3428/week @ 2026-03-29 4491/week @ 2026-04-05 4676/week @ 2026-04-12

16,298 downloads per month
Used in 10 crates (2 directly)

MPL-2.0 license

40KB
744 lines

azul-simplecss

Fork of https://github.com/RazrFalcon/simplecss (because lack of maintainer). Added @rules, CSS nesting support for nested selectors and @-rules, and better parsing on top of original parser.


A very simple streaming parser/tokenizer for CSS 2.1 data format without heap allocations.

Since it's very simple we will start with limitations:

Limitations

  • The ident token must be ASCII only.

    CSS like #аттр { имя:значение } will lead to a parsing error.

  • Property values are not parsed.

    In CSS like * { width: 5px } you will get width property with 5px values as a string.

  • Attribute selector rule is not parsed.

    [foo~="warning"] will be parsed as Token::AttributeSelector("foo~=\"warning\"").

  • There are no data validation.

    • Pseudo-class tokens can contain any text, language pseudo-class can contain any text or even none.
    • Declarations can contain any kind of names and values.
  • All comments will be ignored.

    They didn't have it's own Token item.

  • CDO/CDC comments are not supported.

  • Parser is case sensitive. All keywords should be lowercase.

  • Unicode escape, like \26, is not supported.

  • No spec-defined error handling.

    If something will go wrong you will get an error. Parser will not recover an invalid input. Details.

Where to use

simplecss can be useful for parsing a very simple or predefined CSS.

It's tiny, dependency free and pretty fast.

Examples

Simple

* { color : red }
| | |           ||
| | |           |+- Token::EndOfStream
| | |           +- Token::BlockEnd
| | +- Token::Declaration("color", "red")
| +- Token::BlockStart
+- Token::UniversalSelector

Complex

div#x:first-letter em[id] + .hh1 { color : red }
|  | |            || |    | |    | |           ||
|  | |            || |    | |    | |           |+- Token::EndOfStream
|  | |            || |    | |    | |           +- Token::BlockEnd
|  | |            || |    | |    | +- Token::Declaration("color", "red")
|  | |            || |    | |    +- Token::BlockStart
|  | |            || |    | +- Token::ClassSelector("hh1")
|  | |            || |    +- Token::Combinator(Combinator::Plus)
|  | |            || +- Token::AttributeSelector("id")
|  | |            |+- Token::TypeSelector("em")
|  | |            +- Token::Combinator(Combinator::Space)
|  | +- Token::PseudoClass("first-letter")
|  +- Token::IdSelector("x")
+- Token::TypeSelector("div")

No runtime deps