Fix CSS Minifier to Preserve Spaces in Mathematical Expressions in Nested CSS Structures #86
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
The CSS minifier works correctly for flat CSS structures but fails when modern CSS nesting syntax is present. In nested structures, the parser couldn't properly handle the CSS, leading to incorrect space removal around mathematical operators
(+, -, *, /)in functions likecalc(),clamp(),min(),max(), etc. resulting in invalid CSS. For flat CSS, expressions in property values were safely tokenized and protected.Root Cause
Flat CSS Succeeds: In
processRuleBodies(), property values likecalc(100% - 50px)are tokenized (replaced with placeholders like_CSSMIN_RBT_%d_) beforeprocessAtRulesAndSelectors()runs. This protects expressions from space-stripping regexes that remove spaces around+in selectors/at-rules.Nested CSS Fails: The parser (which is ancient and hasn't been updated since 2018-01-15) most likely doesn't support CSS nesting as it is quite a modern feature.
For nested CSS having mathematical expressions, it fails to tokenize rule bodies correctly, leaving expressions exposed to space removal in
processAtRulesAndSelectors()via the following code:This corrupts expressions in malformed nested CSS for the outer blocks.
Example of the Problem
Example Source CSS (Nested):
Broken Output:
Expected Output:
Potential Solution
Added early tokenization of mathematical expressions before any space processing occurs. This protects expressions regardless of CSS structure.
Changes Proposed
Why This Works
0.8239rem + 0.7512vwbefore parsing, replacing them with unique tokens that are restored later with original spacing.calc(),clamp(), etc.Limitations
Operand Operator Operand; may need expansion for chained or multi-operator mathematical expressions. For example,calc(1px + 2px)works, but the minifier might miss more complex ones likecalc(1px + 2px * 3px)or chained operations.Suggestion
There is another minifier which is actively maintained:
matthiasmullie/minifywhich can be looked into. In my local testing, it preserves the spaces around mathematical expressions by default, even inside nested CSS. It also handles multi-operator mathematical expressions correctly, such ascalc(1px + 2px * 3px).