# csstree: what changed from 2 to 3 - Product: csstree (https://whatsnew.fyi/product/csstree) - Vendor: csstree - Range: changelog entries numbered after v2.3.1 up to and including v3.2.1, stable releases only - Entries below: 5 releases (newest first) - Resolved: 2 is v2.3.1 and 3 is v3.2.1, the newest stable release of each major we track - Carrying security changes: 0 · CVEs mentioned: 0 · Mentioning breaking changes: 0 · Removing or deprecating something: 1 - Page: https://whatsnew.fyi/product/csstree/compare/2...3 What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. ## What changed (57 changes, grouped by kind) ### Added #### v3.2.0 (2026-03-05) - Added `"sideEffects": false` in `package.json` - Added `list` option to the `parse()` method to specify whether the parser should produce a `List` (by default, `list: true`) or an array (`list: false`) for node's children - Added support for Functional Notation in definition syntax by wrapping function arguments into an implicit group when necessary - Added support for stacked multipliers `{A}?` and `{A,B}?` according to spec in definition syntax parsing - Added math functions support in syntax matching (e.g., `min()`, `max()`, etc.) - Added `onToken` option to the `parse()` method, which can be either an array or a function for token handling with type, start, end, and index parameters - Extended `TokenStream` with `getTokenEnd(tokenIndex)` method to return the token's end offset by index - Extended `TokenStream` with `getTokenType(tokenIndex)` method to return the token's type by index - Extended `TokenStream` with `isBlockOpenerTokenType(tokenType)` method to identify block opener tokens - Extended `TokenStream` with `isBlockCloserTokenType(tokenType)` method to identify block closer tokens - Extended `TokenStream` with `getBlockTokenPairIndex(tokenIndex)` method to return the index of the pair token for a block or `-1` if no pair exists #### v3.1.0 (2024-12-06) - Support for boolean expression multiplier in syntax definition, i.e. `` - Add `source`, `startOffset`, `startLine`, and `startColumn` parameters to `OffsetToLocation` constructor - Expose `OffsetToLocation` class in the main entry point #### v3.0.1 (2024-11-02) - Added errors array to the Lexer#validate() method result, providing details on problematic syntax - Added Lexer#cssWideKeywords dictionary to list CSS-wide keywords #### v3.0.0 (2024-09-11) - Support for the @container at-rule - Support for the @starting-style at-rule - Support for the @scope at-rule - Support for the @position-try at-rule - Support for the @layer at-rule - Support for layer, layer() and supports() in the @media at-rule - Layer and LayerList node types - TokenStream#lookupTypeNonSC() method - to generic types - Feature, FeatureRange, FeatureFunction, Condition, and GeneralEnclosure node types for query-related at-rules - Support for functions in features and features in range context - SupportsDeclaration node type to encapsulate a declaration in a @supports query - Support for the selector() feature in @supports at-rule via FeatureFunction node ### Changed #### v3.2.0 (2026-03-05) - Changed `generate()` to not auto insert whitespaces between tokens for raw values #### v3.0.1 (2024-11-02) - Bumped mdn/data to 2.12.1 - Updated the Lexer's constructor to consider config.cssWideKeywords for overriding the default list - Expanded the lexer's dump output to include the cssWideKeywords dictionary - Modified the fork() method to accept a cssWideKeywords option, allowing the addition of new keywords to the existing list #### v3.0.0 (2024-09-11) - Aligned <'font'> to CSS Fonts 4 - Aligned to CSS Color 5 - Block to not include { and } - Atrule and Rule to include { and } for a block - Ratio parsing to use nodes instead of strings for left and right parts, allow any number for both parts, support functions in both parts, and permit omitting the right part - MediaFeature node type transitioned to Feature node type with kind: "media" in @media at-rule - MediaQuery node structure to include modifier, mediaType, and condition properties - parseWithFallback() to rollback tokenIndex before calling a fallback ### Fixed #### v3.2.0 (2026-03-05) - Fixed `fork()` to extend `node` definitions instead of overriding them #### v3.1.0 (2024-12-06) - Fix `Raw` node value consumption by ignoring stop tokens inside blocks - Fix `TokenStream#balance` computation to handle unmatched brackets correctly - Fix syntax definition parser to allow a token to be followed by a multiplier - Fix location for `Layer` node #### v3.0.1 (2024-11-02) - Reverted changes to Block to include { and }, and Atrule and Rule to exclude { and } for a block - Fixed syntaxes for , and <'stroke-opacity'> #### v3.0.0 (2024-09-11) - Initialization when Object.prototype is extended or polluted - fork() method to consider the generic option when creating a Lexer instance - Crash on parse error when custom line or offset is specified via options - speak syntax patch - :lang() to accept a list of or per spec - Lexer matching for syntaxes referred to as <'property'> when the syntax has a top-level #-multiplier - Parsing of syntax definition to allow whitespaces in range multiplier ### Removed #### v3.0.1 (2024-11-02) - Removed second parameter (assign) for the callback in the fork() method _One release carries no categorized changes yet: v3.2.1._ ## Release notes ### v3.2.1 — 3.2.1 - Date: 2026-03-05 - Version: v3.2.1 - Original notes: https://github.com/csstree/csstree/releases/tag/v3.2.1 - Permalink: https://whatsnew.fyi/product/csstree/releases/v3.2.1 - Fixed parsing of nested function in a group in definition syntax (#358) ### v3.2.0 — 3.2.0 - Date: 2026-03-05 - Version: v3.2.0 - Original notes: https://github.com/csstree/csstree/releases/tag/v3.2.0 - Permalink: https://whatsnew.fyi/product/csstree/releases/v3.2.0 - **added** — Added `"sideEffects": false` in `package.json` - **added** — Added `list` option to the `parse()` method to specify whether the parser should produce a `List` (by default, `list: true`) or an array (`list: false`) for node's children - **added** — Added support for Functional Notation in definition syntax by wrapping function arguments into an implicit group when necessary - **added** — Added support for stacked multipliers `{A}?` and `{A,B}?` according to spec in definition syntax parsing - **added** — Added math functions support in syntax matching (e.g., `min()`, `max()`, etc.) - **added** — Added `onToken` option to the `parse()` method, which can be either an array or a function for token handling with type, start, end, and index parameters - **added** — Extended `TokenStream` with `getTokenEnd(tokenIndex)` method to return the token's end offset by index - **added** — Extended `TokenStream` with `getTokenType(tokenIndex)` method to return the token's type by index - **added** — Extended `TokenStream` with `isBlockOpenerTokenType(tokenType)` method to identify block opener tokens - **added** — Extended `TokenStream` with `isBlockCloserTokenType(tokenType)` method to identify block closer tokens - **added** — Extended `TokenStream` with `getBlockTokenPairIndex(tokenIndex)` method to return the index of the pair token for a block or `-1` if no pair exists - **changed** — Changed `generate()` to not auto insert whitespaces between tokens for raw values - **fixed** — Fixed `fork()` to extend `node` definitions instead of overriding them - Added `"sideEffects": false` in `package.json` - Added `list` option to the `parse()` method to specify whether the parser should produce a `List` (by default, `list: true`) or an array (`list: false`) for node's children (e.g., `SelectorList`, `Block`, etc.) - Added support for [Functional Notation](https://www.w3.org/TR/css-values-4/#component-functions) in definition syntax (for now by wrapping function arguments into an implicit group when necessary, see #292) - Added support for stacked multipliers `{A}?` and `{A,B}?` according to spec in definition syntax parsing (#346) - Added math functions support in syntax matching (e.g., `min()`, `max()`, etc.) (#344) - Added `onToken` option to the `parse()` method, which can be either an array or a function: - When the value is an array, it is populated with objects `{ type, start, end }` (token type, and its start and end offsets). - When the value is a function, it accepts `type`, `start`, `end`, and `index` parameters, and is invoked with a token API as `this`, enabling advanced token handling (see [onToken](docs/parsing.md#ontoken)). For example, the following demonstrates checking if all block tokens have matching pairs: ```js parse(css, { onToken(type, start, end, index) { if (this.isBlockOpenerTokenType(type)) { if (this.getBlockPairTokenIndex(index) === -1) { console.warn('No closing pair for', this.getTokenValue(index), this.getRangeLocation(start, end)); } } else if (this.isBlockCloserTokenType(type)) { if (this.getBlockPairTokenIndex(index) === -1) { console.warn('No opening pair for', this.getTokenValue(index), this.getRangeLocation(start, end)); } } } }); ``` - Extended `TokenStream` with the following methods: - `getTokenEnd(tokenIndex)` – returns the token's end offset by index, complementing `getTokenStart(tokenIndex)` - `getTokenType(tokenIndex)` – returns the token's type by index - `isBlockOpenerTokenType(tokenType)` – returns `true` for ``, `<(-token>`, `<[-token>`, and `<{-token>` - `isBlockCloserTokenType(tokenType)` – returns `true` for `<)-token>`, `<]-token>`, and `<}-token>` - `getBlockTokenPairIndex(tokenIndex)` – returns the index of the pair token for a block, or `-1` if no pair exists - Changed `generate()` to not auto insert whitespaces between tokens for raw values (#356) - Fixed `fork()` to extend `node` definitions instead of overriding them. For example, `fork({ node: { Dimension: { generate() { /* ... */ } } } })` will now update only the `generate()` method on the `Dimension` node, while inheriting all other properties from the previous syntax definition. - Bumped `mdn/data` to 2.27.1 and various fixes in syntaxes ### v3.1.0 — 3.1.0 - Date: 2024-12-06 - Version: v3.1.0 - Original notes: https://github.com/csstree/csstree/releases/tag/v3.1.0 - Permalink: https://whatsnew.fyi/product/csstree/releases/v3.1.0 - **added** — Support for boolean expression multiplier in syntax definition, i.e. `` - **added** — Add `source`, `startOffset`, `startLine`, and `startColumn` parameters to `OffsetToLocation` constructor - **added** — Expose `OffsetToLocation` class in the main entry point - **fixed** — Fix `Raw` node value consumption by ignoring stop tokens inside blocks - **fixed** — Fix `TokenStream#balance` computation to handle unmatched brackets correctly - **fixed** — Fix syntax definition parser to allow a token to be followed by a multiplier - **fixed** — Fix location for `Layer` node - Added support for [boolean expression multiplier](https://drafts.csswg.org/css-values-5/#boolean) in syntax definition, i.e. `` (#304) - Added `source`, `startOffset`, `startLine`, and `startColumn` parameters to `OffsetToLocation` constructor, eliminating the need to call `setSource()` after creating a new `OffsetToLocation` instance - Exposed `OffsetToLocation` class in the main entry point, which was previously accessible only via `css-tree/tokenizer` - Fixed `Raw` node value consumption by ignoring stop tokens inside blocks, resolving an issue where `Raw` value consumption stopped prematurely. This fix also enables parsing of functions whose content includes stop characters (e.g., semicolons and curly braces) within declaration values, aligning with the latest draft of [CSS Values and Units L5](https://drafts.csswg.org/css-values-5/). - Fixed `TokenStream#balance` computation to handle unmatched brackets correctly. Previously, when encountering a closing bracket, the `TokenStream` would prioritize it over unmatched opening brackets, leading to improper parsing. For example, the parser would incorrectly consume the declaration value of `.a { prop: ([{); }` as `([{)` instead of consuming it until all opened brackets were closed (`([{); }`). Now, unmatched closing brackets are discarded unless they match the most recent opening bracket on the stack. This change aligns CSSTree with CSS specifications and browser behavior. - Fixed syntax definition parser to allow a token to be followed by a multiplier (#303) - Fixed location for `Layer` node (#310) - Bumped `mdn/data` to 2.12.2 ### v3.0.1 — 3.0.1 - Date: 2024-11-02 - Version: v3.0.1 - Original notes: https://github.com/csstree/csstree/releases/tag/v3.0.1 - Permalink: https://whatsnew.fyi/product/csstree/releases/v3.0.1 - **changed** — Bumped mdn/data to 2.12.1 - **added** — Added errors array to the Lexer#validate() method result, providing details on problematic syntax - **added** — Added Lexer#cssWideKeywords dictionary to list CSS-wide keywords - **changed** — Updated the Lexer's constructor to consider config.cssWideKeywords for overriding the default list - **changed** — Expanded the lexer's dump output to include the cssWideKeywords dictionary - **changed** — Modified the fork() method to accept a cssWideKeywords option, allowing the addition of new keywords to the existing list - **fixed** — Reverted changes to Block to include { and }, and Atrule and Rule to exclude { and } for a block - **removed** — Removed second parameter (assign) for the callback in the fork() method - **fixed** — Fixed syntaxes for , and <'stroke-opacity'> - Bumped `mdn/data` to 2.12.1 - Added `errors` array to the `Lexer#validate()` method result, providing details on problematic syntax. - Added CSS wide keyword customization and introspection: - Added a `Lexer#cssWideKeywords` dictionary to list CSS-wide keywords - Updated the Lexer's constructor to consider `config.cssWideKeywords` for overriding the default list - Expanded the lexer's dump output to include the `cssWideKeywords` dictionary - Modified the `fork()` method to accept a `cssWideKeywords` option, allowing the addition of new keywords to the existing list - Reverted changes to `Block` to include `{` and `}`, and `Atrule` and `Rule` to exclude `{` and `}` for a `block` (#296) - Removed second parameter (`assign`) for the callback in the `fork()` method (e.g., `syntax.fork((config, assign) => { ... })`), as it simply refers to `Object.assign()` - Fixes in syntaxes: ``, `` and `<'stroke-opacity'>` ### v3.0.0 — 3.0.0 - Date: 2024-09-11 - Version: v3.0.0 - Original notes: https://github.com/csstree/csstree/releases/tag/v3.0.0 - Permalink: https://whatsnew.fyi/product/csstree/releases/v3.0.0 - **added** — Support for the @container at-rule - **added** — Support for the @starting-style at-rule - **added** — Support for the @scope at-rule - **added** — Support for the @position-try at-rule - **added** — Support for the @layer at-rule - **added** — Support for layer, layer() and supports() in the @media at-rule - **added** — Layer and LayerList node types - **added** — TokenStream#lookupTypeNonSC() method - **added** — to generic types - **added** — Feature, FeatureRange, FeatureFunction, Condition, and GeneralEnclosure node types for query-related at-rules - **added** — Support for functions in features and features in range context - **added** — SupportsDeclaration node type to encapsulate a declaration in a @supports query - **added** — Support for the selector() feature in @supports at-rule via FeatureFunction node - **changed** — Aligned <'font'> to CSS Fonts 4 - **changed** — Aligned to CSS Color 5 - **changed** — Block to not include { and } - **changed** — Atrule and Rule to include { and } for a block - **changed** — Ratio parsing to use nodes instead of strings for left and right parts, allow any number for both parts, support functions in both parts, and permit omitting the right part - **changed** — MediaFeature node type transitioned to Feature node type with kind: "media" in @media at-rule - **changed** — MediaQuery node structure to include modifier, mediaType, and condition properties - **fixed** — Initialization when Object.prototype is extended or polluted - **fixed** — fork() method to consider the generic option when creating a Lexer instance - **fixed** — Crash on parse error when custom line or offset is specified via options - **fixed** — speak syntax patch - **fixed** — :lang() to accept a list of or per spec - **fixed** — Lexer matching for syntaxes referred to as <'property'> when the syntax has a top-level #-multiplier - **fixed** — Parsing of syntax definition to allow whitespaces in range multiplier - **changed** — parseWithFallback() to rollback tokenIndex before calling a fallback - Added support for the [`@container`](https://drafts.csswg.org/css-contain-3/#container-rule) at-rule - Added support for the [`@starting-style`](https://drafts.csswg.org/css-transitions-2/#defining-before-change-style) at-rule - Added support for the [`@scope`](https://drafts.csswg.org/css-cascade-6/#scoped-styles) at-rule - Added support for the [`@position-try`](https://developer.mozilla.org/en-US/docs/Web/CSS/@position-try) at-rule - Added support for the [`@layer`](https://drafts.csswg.org/css-cascade-5/#at-layer) at-rule - Added support for `layer`, `layer()` and `supports()` in the `@media` at-rule (according to [the @import rule](https://drafts.csswg.org/css-cascade-5/#at-import) in Cascading and Inheritance 5) - Added `Layer` and `LayerList` node types - Added `TokenStream#lookupTypeNonSC()` method - Added `` to generic types - Bumped `mdn/data` to `2.10.0` - Aligned `<'font'>` to [CSS Fonts 4](https://drafts.csswg.org/css-fonts-4/) - Aligned `` to [CSS Color 5](https://drafts.csswg.org/css-color-5/) - Fixed initialization when `Object.prototype` is extended or polluted (#262) - Fixed `fork()` method to consider the `generic` option when creating a Lexer instance (#266) - Fixed crash on parse error when custom `line` or `offset` is specified via options (#251) - Fixed `speak` syntax patch (#241) - Fixed `:lang()` to accept a list of `` or `` per [spec](https://drafts.csswg.org/selectors/#the-lang-pseudo) (#265) - Fixed lexer matching for syntaxes referred to as `<'property'>`, when the syntax has a top-level `#`-multiplier (#102) - Relaxed parsing of syntax definition to allow whitespaces in range multiplier (#270) - Changed `parseWithFallback()` to rollback `tokenIndex` before calling a fallback - Changed `Block` to not include `{` and `}` - Changed `Atrule` and `Rule` to include `{` and `}` for a block - Changed `Ratio` parsing: - Left and right parts contain nodes instead of strings - Both left and right parts of a ratio can now be any number; validation of number range is no longer within the parser's scope. - Both parts can now be functions. Although not explicitly mentioned in the specification, mathematical functions can replace numbers, addressing potential use cases (#162). - As per the [CSS Values and Units Level 4](https://drafts.csswg.org/css-values-4/#ratios) specification, the right part of `Ratio` can be omitted. While this can't be a parser output (which would produce a `Number` node), it's feasible during `Ratio` node construction or transformation. - Changes to query-related at-rules: - Added new node types: - [`Feature`](./docs/ast.md#feature): represents features like `(feature)` and `(feature: value)`, fundamental for both `@media` and `@container` at-rules - [`FeatureRange`](./docs/ast.md#featurerange): represents [features in a range context](https://www.w3.org/TR/mediaqueries-4/#mq-range-context) - [`FeatureFunction`](./docs/ast.md#featurefunction): represents functional features such as `@supports`'s `selector()` or `@container`'s `style()` - [`Condition`](./docs/ast.md#condition): used across all query-like at-rules, encapsulating queries with features and the `not`, `and`, and `or` operators - [`GeneralEnclosure`](./docs/ast.md#condition): represents the [``](https://www.w3.org/TR/mediaqueries-4/#typedef-general-enclosed) production, which caters to unparsed parentheses or functional expressions > Note: All new nodes include a `kind` property to define the at-rule type. Supported kinds are `media`, `supports`, and `container` - Added support for functions for features and features in a range context, e.g. `(width: calc(100cm / 6))` - Added a `condition` value for the parser's context option to parse queries. Use the `kind` option to specify the condition type, e.g., `parse('...', { context: 'condition', kind: 'media' })` - _[Truncated at 4000 characters — full notes: https://github.com/csstree/csstree/releases/tag/v3.0.0]_