Parse error with CSS custom properties with default values including a nested calc
wessberg opened this issue ยท 23 comments
The following CSS:
div {
margin-right: calc(var(--b, calc(var(--c) * 1)));
}
Leads to the following parser error:
JisonParserError: Parse error on line 1:
var(--b, calc(var(--c)*1))
-------------------------^
Expecting end of input, "ADD", "SUB", "MUL", "DIV", got unexpected "RPAREN"
Looking at the Stack trace, here's the chain of the last few operations leading to the issue:
at Parser.parseError (/node_modules/postcss-calc/dist/parser.js:1164:15)
at Parser.parse (/node_modules/postcss-calc/dist/parser.js:1680:30)
at /node_modules/postcss-calc/dist/lib/transform.js:30:30
Removing the last * 1
part removes the parser error.
Thanks for issue, it is bug
Looks like the same error for this:
JisonParserError: Parse error on line 1:
max(5px, calc(env(safe-area-inset-right) - 4px))
-----------------------------------------------^
Expecting end of input, "ADD", "SUB", "MUL", "DIV", got unexpected "RPAREN"
Yes, right now i rewrite plugin and parser, i think release will be on end of week or next week
As a workaround, disable postcss-calc
in package.json
to pass gatsby build
in my case.
"cssnano": {
"preset": [
"default",
{
"calc": false
}
]
}
Will enable again once this bug fixed. Thanks!
Btw I have the very same problem without having nested variables :
const postcssCalc = require('postcss-calc');
const css = `
.baz{
height:calc( calc(16px + 0.8)+calc(1.5 + 0.9));
}
`
postcssCalc.process( css ).catch( error => console.error(error.toString()) );
This breaks with error :
JisonParserError: Parse error on line 1:
calc(16px + 0.8)2.4
----------------^
Expecting end of input, "ADD", "SUB", "MUL", "DIV", got unexpected "NUMBER"
I assume having nested calc with no space between breaks it, since
height:calc( calc(16px + 0.8)+ calc(1.5 + 0.9));
// ^ note space
works normally.
@drinchev feel free to send a PR
@evilebottnawi Actually my bug is unrelated to this one.
Just checked and it seems to work with the latest master branch.
test(
'should handle nested calc statements with 2 calc parameters',
testValue,
'calc(calc(16px + 0.8)+ calc(1.5 + 0.9))',
'calc(16px + 3.2)'
);
test(
'should handle nested calc statements with 2 calc parameters with no spaces',
testValue,
'calc( calc(16px + 0.8)+calc(1.5 + 0.9))',
'calc(16px + 3.2)'
);
Both tests work on current master
, but don't pass in 7.0.1
tag.
Any plans to release soon?
7.0.1 is dependency of the current cssnano
, which is dependency of the current create-react-app
.
@drinchev thanks for investigate looks on this in near future
@wessberg, Thanks for opening this issue. I was also struggling with same calc() issue inside CSS file
I get a similar error when using css-loader's @value properties in calc functions.
@value avatar-size: 36px;
.avatar {
width: avatar-size;
height: avatar-size;
margin-top: calc((avatar-size) / 2);
}
Results in this error
Erroneous area:
1: (avatar-size) / 2
^...^
at Object.parseError (/Users/jonathan/app/node_modules/postcss-calc/dist/parser.js:1164:15)
at Object.lexer_parseError [as parseError] (/Users/jonathan/app/node_modules/postcss-calc/dist/parser.js:2297:44)
at Object.lexer_next [as next] (/Users/jonathan/app/node_modules/postcss-calc/dist/parser.js:3292:22)
at Object.lexer_fastLex [as fastLex] (/Users/jonathan/app/node_modules/postcss-calc/dist/parser.js:3367:18)
at fastLex (/Users/jonathan/app/node_modules/postcss-calc/dist/parser.js:1567:27)
at Parser.parse (/Users/jonathan/app/node_modules/postcss-calc/dist/parser.js:1641:30)
at /Users/jonathan/app/node_modules/postcss-calc/dist/lib/transform.js:33:28
at walk (/Users/jonathan/app/node_modules/postcss-value-parser/lib/walk.js:19:7)
at ValueParser.walk (/Users/jonathan/app/node_modules/postcss-value-parser/lib/index.js:18:3)
at transformValue (/Users/jonathan/app/node_modules/postcss-calc/dist/lib/transform.js:24:50)
at _default (/Users/jonathan/app/node_modules/postcss-calc/dist/lib/transform.js:66:100)
at /Users/jonathan/app/node_modules/postcss-calc/dist/index.js:25:51
at /Users/jonathan/app/node_modules/postcss/lib/container.js:135:18
at Rule.each (/Users/jonathan/app/node_modules/postcss/lib/container.js:101:16)
at Rule.walk (/Users/jonathan/app/node_modules/postcss/lib/container.js:131:17)
at /Users/jonathan/app/node_modules/postcss/lib/container.js:148:24
at Root.each (/Users/jonathan/app/node_modules/postcss/lib/container.js:101:16)
at Root.walk (/Users/jonathan/app/node_modules/postcss/lib/container.js:131:17)
at /Users/jonathan/app/node_modules/postcss-calc/dist/index.js:23:9
at initializePlugin (/Users/jonathan/app/node_modules/cssnano/dist/index.js:31:51)
The @value properties are processed by css-loader, which runs after postcss-loader. If nothing else, it seems appropriate for postcss-calc to just ignore calc values that fail to parse.
I was able to work around my issue by including the postcss-modules-values plugin before postcss-calc.
Any example of this for removing postcss-calc from Gatsby build please? I can't achieve this...
I tried to edit my postcss.config.js
, unsuccessful.
This bug happens because 'function' regexp not matching function which has many brackets inside:
Line 13 in 6260789
As I understand it is not possible to match nested brackets by regex so it should be rewritten from regex.
After transition from v7.0.0 to v7.0.[12], postcss-calc got a regression bug. Now I get the following error, though it has never been raised before:
:root {
/* ... */
--main-gap-mobile: calc((100vw - var(--main-width-mobile)) / 2);
}
JisonParserError in plugin "gulp-postcss"
Message:
Parse error on line 1:
- calc((100v...
--^
Expecting "ADD", "SUB", "LENGTH", "ANGLE", "TIME", "FREQ", "RES", "UNKNOWN_DIMENSION", "EMS", "EXS", "CHS", "REMS", "VHS", "VWS", "VMINS", "VMAXS", "PERCENTAGE", "NUMBER", "dimension", got unexpected "CALC"
Details:
hash: [object Object]
fileName: ./src/styles/main.css
domainEmitter: [object Object]
domain: [object Object]
domainThrown: false
Stack:
JisonParserError: Parse error on line 1:
- calc((100v...
--^
Expecting "ADD", "SUB", "LENGTH", "ANGLE", "TIME", "FREQ", "RES", "UNKNOWN_DIMENSION", "EMS", "EXS", "CHS", "REMS", "VHS", "VWS", "VMINS", "VMAXS", "PERCENTAGE", "NUMBER", "dimension", got unexpected "CALC"
at Parser.parseError (./node_modules/postcss-calc/dist/parser.js:1200:15)
at Parser.parse (./node_modules/postcss-calc/dist/parser.js:1716:30)
at ./node_modules/postcss-calc/dist/lib/transform.js:33:30
at walk (./node_modules/postcss-calc/node_modules/postcss-value-parser/lib/walk.js:7:16)
at ValueParser.walk (./node_modules/postcss-calc/node_modules/postcss-value-parser/lib/index.js:18:3)
at transformValue (./node_modules/postcss-calc/dist/lib/transform.js:24:50)
at _default (./node_modules/postcss-calc/dist/lib/transform.js:66:100)
at ./node_modules/postcss-calc/dist/index.js:27:32
at ./node_modules/postcss-import/node_modules/postcss/lib/container.js:144:26
at Rule.each (./node_modules/postcss-import/node_modules/postcss/lib/container.js:110:22)```
In my case it was caused by a third party library: sampotts/plyr#1816
It seems wrapping a variable inside #{}
(fix: creativetimofficial/ct-light-bootstrap-dashboard-pro-react#37 (comment) ) was able to solve my issue.
As per Semigradsky's comment, I think it is something to do with when there are too many parenthesis levels in the formula:
var(--a) + max(1px, min((1vw - 5.9px), 10px))
--------------------------------------------^
Expecting end of input, "ADD", "SUB", "MUL", "DIV", got unexpected "RPAREN"
Hm, looking at this issue, all these calc()
instructions aren't valid as per the CSS spec, which SCSS still has to obey, so this doesn't look like a bug in flagging errors, but a bug in how it's reporting what is wrong?
margin-right: calc(var(--b, calc(var(--c) * 1)));
is missing "stuff" aftervar(--b
(like) +
). As written, it isn't a valid calc statement.height: calc( calc(16px + 0.8)+calc(1.5 + 0.9));
does not have the spec-required whitespace around the+
(super easy to miss, made even worse by the fact that even though+
and-
must have whitespace,*
and/
may omit it)- parentheses are active syntax for calc, so
margin-top: calc((avatar-size) / 2);
isn't valid syntax. - which you also see for
--main-gap-mobile: calc((100vw - var(--main-width-mobile)) / 2);
, where(100vw - var(--main-width-mobile))
should becalc(100vw - var(--main-width-mobile))
.
margin-right: calc(var(--b, calc(var(--c) * 1)))
and --main-gap-mobile: calc((100vw - var(--main-width-mobile)) / 2)
are valid. You can check it just by add them via chrome devtools.
You're right - although that first one still makes no sense: those calc()
wrappers do nothing, and a decent tool would remove them since calc(var(--b, calc(var(--c) * 1)))
is identical to var(--b, var(--c))
(postcss-calc might certainly exhibit this bug for that input, but because it can be simplified so much it's not unambiguously that the symptom stems from the same cause)
In case this helps anyone, calc(var(--base-padding) * -1)
throws an error whereas calc(-1 * var(--base-padding))
does not.
In case this helps anyone, calc(var(--base-padding) * -1) throws an error whereas calc(-1 * var(--base-padding)) does not.
But does it just print an error message or does it crash?
It fails and prints a generic error. Something like "failed at line 1 column 26." I don't have the error in front of me anymore. The error message was not accurate. I found the issue by removing and adding back styles until I narrowed it down to the culprit.