moox / reduce-css-calc Goto Github PK
View Code? Open in Web Editor NEWReduce CSS calc() function at the maximum
License: MIT License
Reduce CSS calc() function at the maximum
License: MIT License
Hi, in reviewing the tests it looks like mis-matching units are evaluated, for example:
test(
'should reduce nested expression',
testFixture,
'calc( (1em - calc( 10px + 1em)) / 2)',
'-5px'
)
I'm unsure how this equates to 5px
unless you are also converting em to px.
Based on current browser implementations, mis-matching units are not evaluated and this would get converted to calc((1em - (10px + 1em)) / 2)
. I am wondering if this evaluation is intentional or a a bug.
So, I'm having an issue related to comments that are deleted when those are typed inside the property value.
In my case, I need to use comments
in order to use some RTLCSS features.
.title {
margin-top: calc(2rem * 2) /*rtl:2rem*/;
}
Expected Output:
.title {
margin-top: 4rem /*rtl:2rem*/;
}
Actual Output:
.title {
margin-top: 4rem;
}
Would it be possible to fix that?
Thank you.
Input
div {
margin-left: -calc(2px *2);
}
Output
div {
margin-left: 4px;
}
Expected?
div {
margin-left: -4px;
}
Reproducible on http://cssnext.io/playground/
reduce-css-calc is incorrect when subtracting different units:
reduceCSSCalc("calc(100% - calc(120px + 1em + 2em + 100px))")
> calc(100% - 220px + 3em)
reduceCSSCalc("calc(100% - (120px + 1em + 2em + 100px))")
> calc(100% - 220px + 3em)
reproduction test: https://repl.it/repls/LeafyMadTrials
After removing the line 38 it still is passing all the test, may you tell the reason for this comment
// CSS allow to omit 0 for 0.* values,
// but math-expression-evaluator does not
I want to know the test case for this it failed so that I can correct it. Thanks
This was reported in postcss-cssnext, but it was recommended to be reported here. The post below is nearly identical to the link below:
In version 2.11.0 of postcss-cssnext
, complex calc functions would not be simplified, so they would remain as is when compiled. However, I upgraded postcss-cssnext
and in version 3.1.0, postcss-cssnext
tries to simplify the calc function, but does so incorrectly. Maybe I'm doing something wrong on my end, but upgrading from 2.11.0 to 3.1.0 seems to mess up the result. For example:
calc(100% + (2 * 100px) - ((75.37% - 63.5px) - 900px));
incorrectly simplifies and compiles to:
calc(100% + 200px - 75.37% - 963.5px));
The double negative here is not handled properly.
Also, the following:
calc(((((100% + (2 * 30px) + 63.5px) / 0.7537) - (100vw - 60px)) / 2) + 30px);
incorrectly simplifies and compiles to:
calc((176.0366% + 217.4052px - 100vw - 60px) / 2 + 30px);
I have no idea what is happening here, but it's completely wrong.
I know I could simplify my calcs, but there are some semantics behind organizing it this way in my code.
In version 2.11.0, when the compiled calcs were sent to the browser without being simplified, they worked as expected.
http://requirebin.com/?gist=d519007759f777a3b9fb7c52834389e4
reduceCSSCalc("calc(100% - 120px - 60px)") === "calc(100% - 60px)"
reduceCSSCalc("calc(100% - 10px - 20px)" === "calc(100% - -10px)"
iOS Safari 11 introduces constant values to account for the safe zone, which in browser is supported in calc. When a constant value is used in a calc with this plug in, the compiler fails with the following error:
Expecting 'SUB', 'LPAREN', 'NESTED_CALC', 'NUMBER', 'CSS_VAR', 'LENGTH', 'ANGLE', 'TIME', 'FREQ', 'RES', 'EMS', 'EXS', 'CHS', 'REMS', 'VHS', 'VWS', 'VMINS', 'VMAXS', 'PERCENTAGE', got 'PREFIX']
message: 'Parse error on line 1:\nconstant(safe-area-i\n^\nExpecting \'SUB\', \'LPAREN\', \'NESTED_CALC\', \'NUMBER\', \'CSS_VAR\', \'LENGTH\', \'ANGLE\', \'TIME\', \'FREQ\', \'RES\', \'EMS\', \'EXS\', \'CHS\', \'REMS\', \'VHS\', \'VWS\', \'VMINS\', \'VMAXS\', \'PERCENTAGE\', got \'PREFIX\'',
showStack: false,
showProperties: true,
plugin: 'gulp-postcss',
> reduceCSSCalc('calc((100% / 3) * 3)')
'100%'
> reduceCSSCalc('calc(calc(100% / 3) * 3)')
'99.99999%'
We also can go deeper lol:
> reduceCSSCalc('calc(calc(100% / 30000000) * 30000000)')
'0%'
Note that it works in Firefox and Chrome:
calc(100vw - (100vw - 100%))
I'm using this hack to solve ios scroll bug.
1.3.0: calc(100vw - (100vw - 100%))
2.0: calc(0vw - 100%)
Can't understand new math with different units. This is totally incorrect. I can understand calc(0vw + 100%)
, but current behavior looks very suspicious.
The following CSS transform used to work in 1.X
/* source */
foo {
left: calc(-(100px - 10px));
}
/* expected */
foo {
left: -90px;
}
However, as of 2.X, this just throws an error.
If you past the source
example above into http://cssnext.io/playground/, you can see that nothing is produced (which I take to mean it couldn't compile).
might be related to #34. but 100%
is transformed to 1
, only in the body of @supports while the condition stays 100%
input
@supports (width:calc(100% - constant(safe-area-inset-left))){
.a{
width:calc(100% - constant(safe-area-inset-left))
}
}
output
@supports (width:calc(100% - constant(safe-area-inset-left))){
.a{
width:calc(1- constant(safe-area-inset-left))
}
}
For example calc(50% - 42Px)
is translated to calc(0.5 - 42Px)
(We declare some units in capital case in conjunction with postcss-pxtorem
)
Hi :)
I'm using postcss and have following expression:
div {
width: calc(100% - $width - $margin);
}
and I found strange behavior when try to use zero values:
// $width: 200px;
// $margin: 0; or $margin: 0px; or $margin: 0px;
// output:
div {
width: calc(100% - 200px - 0); // this is not valid expression inside 'calc' and browsers don't calculate it
}
but these are valid expressions:
width: calc(100% - 200px - 0px);
width: calc(100% - 200px - 0%);
so my question is: Could you fix this? Or this is a normal behavior?
thank you :)
I noticed that the way math expressions are reduced is by using eval()
(
Line 75 in 1ce8bd0
.foo {
width: calc(2.5px >>> 0);
}
See this codepen as an example.
Personally I view this as a feature, and feel like it should be documented rather than just being an implementation detail. What do you think?
The parser will fail if using nested custom properties with fallbacks which themselves are custom properties.
This code:
.my-class {
width: calc(var(--xxx, var(--yyy)) / 2);
}
Will throw this error:
Error: Parse error on line 1:
...ar(--xxx, var(--yyy)) / 2
-----------------------^
Expecting 'EOF', 'ADD', 'SUB', 'MUL', 'DIV', got 'RPAREN'
I tried putting together a PR using recursive rules for the parser but realized someone else with a better understanding of Bison syntax could do a better job than me.
The best I could come up with is a regex which handles two levels of nesting which is enough for my use case but not really fool proof. I figured I should open an issue before submitting a PR with the following change to the parser:
- (var\([^\)]*\)) return 'CSS_VAR';
+ (var\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)) return 'CSS_VAR';
When trying to use this library within create-react-app and performing a yarn build
, I'm getting the following error:
It looks to be caused by template literals here:
which are not being transpiled out. I was going to use the es6 src instead of dist but it's omitted from the npm package.
I see the build target is for node 4+ and not browser. Any chance of supporting a browser target or exposing the es6 for browser libraries. Btw, version 1.3.0
works fine and is what I'm currently using my react-svg-text component
I haven't created a cut down replication case for this yet, but while I do I thought you might want to start looking into it.
Stack trace from grunt:
Warning: Circular reference detected (.files.src[0]) Use --force to continue.
Error: Circular reference detected (.files.src[0])
at recurse (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt-legacy-util/index.js:99:15)
at /home/ephox/jenkins/workspace/fusebox/node_modules/grunt-legacy-util/index.js:110:16
at Array.map (native)
at recurse (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt-legacy-util/index.js:109:20)
at recurse (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt-legacy-util/index.js:119:20)
at recurse (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt-legacy-util/index.js:119:20)
at Object.util.recurse (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt-legacy-util/index.js:130:10)
at Function.config.process (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/grunt/config.js:52:21)
at Function.config.get (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/grunt/config.js:46:17)
at /home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/grunt/config.js:98:19
at Array.filter (native)
at Object.config.requires [as requiresConfig] (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/grunt/config.js:97:40)
at Object.<anonymous> (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/grunt/task.js:225:10)
at Object.thisTask.fn (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/grunt/task.js:73:16)
at Object.<anonymous> (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/util/task.js:294:30)
at Task.runTaskFn (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/util/task.js:244:24)
at Task.<anonymous> (/home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/util/task.js:293:12)
at /home/ephox/jenkins/workspace/fusebox/node_modules/grunt/lib/util/task.js:220:11
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
at Function.Module.runMain (module.js:449:11)
at startup (node.js:148:18)
at node.js:405:3
Analysing my build server logs, the only change in my node dependencies is:
--- passing.txt 2016-08-22 17:29:32.000000000 +1000
+++ failing.txt 2016-08-22 17:28:51.000000000 +1000
@@ -177,8 +177,9 @@
├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
-│ └─┬ [email protected]
+│ └─┬ [email protected]
│ ├── [email protected]
+│ ├── [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
and I confirmed rolling back to 1.2.4 resolves the grunt error.
Since v2: http://requirebin.com/?gist=5d1cbb2779f115b02a57ebb75c14ed4a
Expressions like "calc(100% - calc(50% + 25px))"
causes parsing error from the jison parser
Not sure if nested calc()
are standard but its working on Chrome at least.
"reduce-css-calc": "^2.1.8"
var reduceCSSCalc = require('reduce-css-calc')
console.log(reduceCSSCalc("calc(100% + 2px)"))
console.log(reduceCSSCalc("calc(100% + 2PX)")) // error
Using postcss-calc wrapper, I've found a case that the library seems to struggle to resolve:
font-size: calc(26.140174776426555px + (43.56695796071093 - 26.140174776426555) * ((100vw - 600px) / (1140 - 600)));
If there's anything I can do to give more info let me know! The symptom I get is a (very very) long resolution time when the plug-in is on (500s vs 7s for a webpack run)
I'm not sure if this is a dumb thing, but I'm having issue while using cssnext with reduce-css-calc
My Code:
height: calc(20 / 1.618)rem;
Output:
height: 12.36094 rem
Expected Output:
height: 12.36094rem
Is my syntax wrong?
Reducing the expression calc( (1em - calc( 10px + 1em)) / 2)
reduces incorrectly to calc(1em - 5px)
(the correct one should be -5px
).
A workaround is to add another operation, however this is far from ideal: calc( (1em + (-1 * calc( 10px + 1em))) / 2)
.
I know the expressions look weird, but these actually are real-world examples from SASS-generated CSS (the inner calc
expression is stored in a variable).
Would it be possible to discard parts of the calc()
function that operate on zero values? For example:
div {
width: calc(100vw / 2 - 6px + 0px);
}
Can be:
div {
width: calc(100vw / 2 - 6px);
}
And:
div {
width: calc(500px - 0px);
}
Can be:
div {
width: 500px;
}
It's from this edge case in CSSO:
reduce('calc(var(--popupHeight) / 2)')
//=> NaN
Using reduce-css-calc via cssnano via optimize-cssnano-plugin.
The input CSS I believe is coming from Bootstrap 4, possibly this line, but it's hard to pinpoint based on the error.
height: calc(calc(2.25rem + 2px) - 1px * 2);
Getting:
ERROR Error: CSS minification error: Parse error on line 1:
auto - 1px * 2
^
Expecting 'SUB', 'LPAREN', 'NESTED_CALC', 'NUMBER', 'CSS_VAR', 'LENGTH', 'ANGLE', 'TIME', 'FREQ', 'RES', 'EMS', 'EXS', 'CHS', 'REMS', 'VHS', 'VWS', 'VMINS', 'VMAXS', 'PERCENTAGE', got 'PREFIX'. File: css/app.a46e10bb.css
Error: CSS minification error: Parse error on line 1:
auto - 1px * 2
^
Expecting 'SUB', 'LPAREN', 'NESTED_CALC', 'NUMBER', 'CSS_VAR', 'LENGTH', 'ANGLE', 'TIME', 'FREQ', 'RES', 'EMS', 'EXS', 'CHS', 'REMS', 'VHS', 'VWS', 'VMINS', 'VMAXS', 'PERCENTAGE', got 'PREFIX'. File: css/app.a46e10bb.css
at /develop/node_modules/@intervolga/optimize-cssnano-plugin/index.js:106:21
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build-prod: `vue-cli-service build && /bin/bash build/prod-server-replace-vars.sh`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build-prod script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2018-10-02T18_06_56_983Z-debug.log
Any ideas?
Version 2.0.0 included a breaking change that makes sense but has an error. That change was:
While a unit like "px" times "px" should throw an error, a percent ("%") is not a unit; it denotes a fraction of 100. It is legitimate to multiple 50% by 50%, as it is the exact same mathematical meaning as 50/100 * 50/100
.
I may be wrong here, but I'm pretty sure. Thoughts?
Hi, I am using postcss-calc
(which uses reduce-css-calc
if I'm correct), thanks for your work.
I was under the impression that mixed units should work (I even saw some tests for it) so I am confused why the following throws an error:
Could not reduce expression: calc(.25em - 1px) [postcss-calc]
I am simply using it as:
.c-linklist a {
display: block;
padding-top: .25em;
padding-bottom: calc(.25em - 1px);
}
Am I missing something?
Input:
calc(1em + (1em - 5px))
Yields:
calc(2em + 5px)
Expected:
calc(2em - 5px)
Now this library reducing correct calc
expressions.
For some people it would be convenient to write shorter but incorrect calc
expressions.
For example
div {
margin-left: -calc(2px *2);
}
instead
div {
margin-left: calc(-1*(2px * 2));
}
There are some issues about this: #30, #32
I think that we should decide: use ONLY the correct syntax or start supporting an informal syntax.
If we choose the second option, we need to agree on what it will be.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.