Thanks to visit codestin.com
Credit goes to github.com

Skip to content

csskit/csskit_transform/css_parse: Improve transform architecture. Minify lengths#815

Merged
keithamus merged 1 commit intomainfrom
csskit-csskit-transform-css-parse-improve-transform-architecture-minify-lengths
Jan 19, 2026
Merged

csskit/csskit_transform/css_parse: Improve transform architecture. Minify lengths#815
keithamus merged 1 commit intomainfrom
csskit-csskit-transform-css-parse-improve-transform-architecture-minify-lengths

Conversation

@keithamus
Copy link
Member

This closes #774. By introducing a new OverlaySegment system in
css_parse, we can insert new snippets of css before, after or replacing chunks
of css. This allows us to then use this in the transformer trait to write
reasonably ergonomic transformers which can stack.

This also closes #777 by introducing the ReduceLengths transformer which is the
first to use this kind of logic.

…nify lengths

This closes #774. By introducing a new OverlaySegment system in
css_parse, we can insert new snippets of css before, after or replacing chunks
of css. This allows us to then use this in the transformer trait to write
reasonably ergonomic transformers which can stack.

This also closes #777 by introducing the ReduceLengths transformer which is the
first to use this kind of logic.
@keithamus keithamus enabled auto-merge (squash) January 19, 2026 17:31
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All CI jobs have passed. Approving.

@keithamus keithamus merged commit 466d01a into main Jan 19, 2026
15 of 16 checks passed
@keithamus keithamus deleted the csskit-csskit-transform-css-parse-improve-transform-architecture-minify-lengths branch January 19, 2026 17:38
keithamus added a commit that referenced this pull request Jan 21, 2026
…icable

In #777 @yisibl pointed out a bug in ReduceLengths (#815) in that unitless zero
is not always semantically equivalent to `0px`. This is because:

- Some values, e.g. `line-height` and `tab-size` have distinct `<number>` and
  `<length>` types. These types are distinct because they have semantic meaning
	(line-height uses number as a multiplier, so `1` is "1x font-size", tab-size
	uses number as "the number of spaces"). While for a single property a
	line-height of `0` vs `0px` might be _visually_ equivalent, this can cause
	issues with animation.
- Calc's system for resolving the type requires units to be equivalent, so
	`calc(100px - 0px)` returns a Length, while `calc(100px - 0)` returns a Number
	which will be invalid in some contexts.
- For unknown properties (or custom ones) we cannot make the determination
	whether or not they'll be used in calc, or whether or not this is a property
	we're not-yet parsing.

Because of these gotchas, unitless zero is not _always_ equivalent to `0px`.
Therefore it is not safe for us to always convert `0px` to unitless zero.
However, we can reason about this using metadata.

This change introduces a new UnitlessZeroResolves metadata bit, which can be
used to determine how a declaration might reason about unitless zero in an
abstract way (without looking up property names). The metadata system propagates
through nodes, so later on when we parse calc/custom properties better, we can
set the UnitlessZeroResolves::Number flag and it should retain this new
behaviour.

ReduceLengths has now been extended so that when it visits a declaration it will
set a boolean based on this value, meaning traversing into the declaration, it
can be aware as to whether or not it should coerce these values.

This allows us to continue to reduce `0px` to `0` when they are semantically
equivalent, while also ensuring we're only doing so when they actually are.
keithamus added a commit that referenced this pull request Jan 21, 2026
…icable

In #777 @yisibl pointed out a bug in ReduceLengths (#815) in that unitless zero
is not always semantically equivalent to `0px`. This is because:

- Some values, e.g. `line-height` and `tab-size` have distinct `<number>` and
  `<length>` types. These types are distinct because they have semantic meaning
	(line-height uses number as a multiplier, so `1` is "1x font-size", tab-size
	uses number as "the number of spaces"). While for a single property a
	line-height of `0` vs `0px` might be _visually_ equivalent, this can cause
	issues with animation.
- Calc's system for resolving the type requires units to be equivalent, so
	`calc(100px - 0px)` returns a Length, while `calc(100px - 0)` returns a Number
	which will be invalid in some contexts.
- For unknown properties (or custom ones) we cannot make the determination
	whether or not they'll be used in calc, or whether or not this is a property
	we're not-yet parsing.

This was separated out into #820.

Because of these gotchas, unitless zero is not _always_ equivalent to `0px`.
Therefore it is not safe for us to always convert `0px` to unitless zero.
However, we can reason about this using metadata.

This change introduces a new UnitlessZeroResolves metadata bit, which can be
used to determine how a declaration might reason about unitless zero in an
abstract way (without looking up property names). The metadata system propagates
through nodes, so later on when we parse calc/custom properties better, we can
set the UnitlessZeroResolves::Number flag and it should retain this new
behaviour.

ReduceLengths has now been extended so that when it visits a declaration it will
set a boolean based on this value, meaning traversing into the declaration, it
can be aware as to whether or not it should coerce these values.

This allows us to continue to reduce `0px` to `0` when they are semantically
equivalent, while also ensuring we're only doing so when they actually are.

This fixes #820.
keithamus added a commit that referenced this pull request Jan 21, 2026
…icable (#821)

In #777 @yisibl pointed out a bug in ReduceLengths (#815) in that
unitless zero
is not always semantically equivalent to `0px`. This is because:

- Some values, e.g. `line-height` and `tab-size` have distinct
`<number>` and
`<length>` types. These types are distinct because they have semantic
meaning
(line-height uses number as a multiplier, so `1` is "1x font-size",
tab-size
	uses number as "the number of spaces"). While for a single property a
line-height of `0` vs `0px` might be _visually_ equivalent, this can
cause
	issues with animation.
- Calc's system for resolving the type requires units to be equivalent,
so
`calc(100px - 0px)` returns a Length, while `calc(100px - 0)` returns a
Number
	which will be invalid in some contexts.
- For unknown properties (or custom ones) we cannot make the
determination
whether or not they'll be used in calc, or whether or not this is a
property
	we're not-yet parsing.

This was separated out into #820.

Because of these gotchas, unitless zero is not _always_ equivalent to
`0px`.
Therefore it is not safe for us to always convert `0px` to unitless
zero.
However, we can reason about this using metadata.

This change introduces a new UnitlessZeroResolves metadata bit, which
can be
used to determine how a declaration might reason about unitless zero in
an
abstract way (without looking up property names). The metadata system
propagates
through nodes, so later on when we parse calc/custom properties better,
we can
set the UnitlessZeroResolves::Number flag and it should retain this new
behaviour.

ReduceLengths has now been extended so that when it visits a declaration
it will
set a boolean based on this value, meaning traversing into the
declaration, it
can be aware as to whether or not it should coerce these values.

This allows us to continue to reduce `0px` to `0` when they are
semantically
equivalent, while also ensuring we're only doing so when they actually
are.

This fixes #820.
github-actions bot pushed a commit that referenced this pull request Jan 22, 2026
## [0.0.14] - 2026-01-22

### Other Changes
- Coverage: Add `:unknown` coverage testing to all popular CSS libraries (#796) ([#796](#796))

### Chromashift
- chromashift: Fix lossy alpha conversions (#784) ([#784](#784))

### Css_ast
- Regenerate css_ast/src/values from csswg drafts (#789) ([#789](#789))
- css_ast: Fixup MediaQueryList & ContainerConditionList to use CommaSeparated (#795) ([#795](#795))
- css_ast: Add support for parsing `@import` rules (#797) ([#797](#797))
- css_ast: enables `<display>` (#799) ([#799](#799))
- css_ast/csskit_proc_macro: Provide system for easily renaming auto-generated types (#800) ([#800](#800))
- Regenerate css_ast/src/values from csswg drafts (#801) ([#801](#801))
- Regenerate css_ast/src/values from csswg drafts (#808) ([#808](#808))
- csskit_transform: Reduce more color types (#818) ([#818](#818))
- csskit_transform: Add ReduceTimeUnits transform (#819) ([#819](#819))
- css_ast/css_transform: Only reduce lengths to unitless zero when applicable (#821) ([#821](#821))
- csskit_spec_generator/css_ast: Generate many more values (#823) ([#823](#823))

### Css_lexer
- css_lexer/css_parse: Add SourceCursor compacting, ensure CursorCompactWriteSink compacts cursors before write (#782) ([#782](#782))

### Css_parse
- csskit/csskit_transform/css_parse: Improve transform architecture. Minify lengths (#815) ([#815](#815))

### Csskit
- chore(deps): update dependencies (patch) (#790) ([#790](#790))

### Csskit_ast
- csskit_ast: Add benchmarks for linting with example cks files (#788) ([#788](#788))

### Csskit_transform
- csskit_transform: Add Reduce colors (#816) ([#816](#816))

### Csskit_vscode
- chore(deps): update dependency oxlint to v1.36.0 (#791) ([#791](#791))
- chore(deps): update dependency @types/vscode to v1.108.1 (#803) ([#803](#803))
- chore(deps): update dependency oxlint to v1.38.0 (#805) ([#805](#805))
- chore(deps): update dependencies (patch) (#802) ([#802](#802))
- fix(deps): update dependencies (patch) (#809) ([#809](#809))
- chore(deps): update dependency oxlint to v1.39.0 (#811) ([#811](#811))
- chore(deps): update dependency prettier to v3.8.0 (#813) ([#813](#813))

### Csskit_wasm
- website: fix pages deploy (#807) ([#807](#807))
- csskit_wasm: Use minifier transform architecture (#817) ([#817](#817))

[forcebuild]
@keithamus keithamus mentioned this pull request Jan 22, 2026
github-actions bot pushed a commit that referenced this pull request Jan 22, 2026
## [0.0.14] - 2026-01-22

### Other Changes
- Coverage: Add `:unknown` coverage testing to all popular CSS libraries (#796) ([#796](#796))

### Chromashift
- chromashift: Fix lossy alpha conversions (#784) ([#784](#784))

### Css_ast
- Regenerate css_ast/src/values from csswg drafts (#789) ([#789](#789))
- css_ast: Fixup MediaQueryList & ContainerConditionList to use CommaSeparated (#795) ([#795](#795))
- css_ast: Add support for parsing `@import` rules (#797) ([#797](#797))
- css_ast: enables `<display>` (#799) ([#799](#799))
- css_ast/csskit_proc_macro: Provide system for easily renaming auto-generated types (#800) ([#800](#800))
- Regenerate css_ast/src/values from csswg drafts (#801) ([#801](#801))
- Regenerate css_ast/src/values from csswg drafts (#808) ([#808](#808))
- csskit_transform: Reduce more color types (#818) ([#818](#818))
- csskit_transform: Add ReduceTimeUnits transform (#819) ([#819](#819))
- css_ast/css_transform: Only reduce lengths to unitless zero when applicable (#821) ([#821](#821))
- csskit_spec_generator/css_ast: Generate many more values (#823) ([#823](#823))

### Css_lexer
- css_lexer/css_parse: Add SourceCursor compacting, ensure CursorCompactWriteSink compacts cursors before write (#782) ([#782](#782))

### Css_parse
- csskit/csskit_transform/css_parse: Improve transform architecture. Minify lengths (#815) ([#815](#815))

### Csskit
- chore(deps): update dependencies (patch) (#790) ([#790](#790))

### Csskit_ast
- csskit_ast: Add benchmarks for linting with example cks files (#788) ([#788](#788))

### Csskit_transform
- csskit_transform: Add Reduce colors (#816) ([#816](#816))

### Csskit_vscode
- chore(deps): update dependency oxlint to v1.36.0 (#791) ([#791](#791))
- chore(deps): update dependency @types/vscode to v1.108.1 (#803) ([#803](#803))
- chore(deps): update dependency oxlint to v1.38.0 (#805) ([#805](#805))
- chore(deps): update dependencies (patch) (#802) ([#802](#802))
- fix(deps): update dependencies (patch) (#809) ([#809](#809))
- chore(deps): update dependency oxlint to v1.39.0 (#811) ([#811](#811))
- chore(deps): update dependency prettier to v3.8.0 (#813) ([#813](#813))

### Csskit_wasm
- website: fix pages deploy (#807) ([#807](#807))
- csskit_wasm: Use minifier transform architecture (#817) ([#817](#817))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Todo: Minify lengths Build out minifier architecture

1 participant