Giter Club home page Giter Club logo

postcss-calc's Introduction

PostCSS

Philosopher’s stone, logo of PostCSS

PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.

PostCSS is used by industry leaders including Wikipedia, Twitter, Alibaba, and JetBrains. The Autoprefixer and Stylelint PostCSS plugins is one of the most popular CSS tools.


  Made in Evil Martians, product consulting for developer tools.


Sponsorship

PostCSS needs your support. We are accepting donations at Open Collective.

Sponsored by Tailwind CSS        Sponsored by ThemeIsle

Plugins

PostCSS takes a CSS file and provides an API to analyze and modify its rules (by transforming them into an Abstract Syntax Tree). This API can then be used by plugins to do a lot of useful things, e.g., to find errors automatically, or to insert vendor prefixes.

Currently, PostCSS has more than 200 plugins. You can find all of the plugins in the plugins list or in the searchable catalog. Below is a list of our favorite plugins — the best demonstrations of what can be built on top of PostCSS.

If you have any new ideas, PostCSS plugin development is really easy.

Solve Global CSS Problem

  • postcss-use allows you to explicitly set PostCSS plugins within CSS and execute them only for the current file.
  • postcss-modules and react-css-modules automatically isolate selectors within components.
  • postcss-autoreset is an alternative to using a global reset that is better for isolatable components.
  • postcss-initial adds all: initial support, which resets all inherited styles.
  • cq-prolyfill adds container query support, allowing styles that respond to the width of the parent.

Use Future CSS, Today

Better CSS Readability

Images and Fonts

Linters

  • stylelint is a modular stylesheet linter.
  • stylefmt is a tool that automatically formats CSS according stylelint rules.
  • doiuse lints CSS for browser support, using data from Can I Use.
  • colorguard helps you maintain a consistent color palette.

Other

  • cssnano is a modular CSS minifier.
  • lost is a feature-rich calc() grid system.
  • rtlcss mirrors styles for right-to-left locales.

Syntaxes

PostCSS can transform styles in any syntax, not just CSS. If there is not yet support for your favorite syntax, you can write a parser and/or stringifier to extend PostCSS.

  • sugarss is a indent-based syntax like Sass or Stylus.
  • postcss-syntax switch syntax automatically by file extensions.
  • postcss-html parsing styles in <style> tags of HTML-like files.
  • postcss-markdown parsing styles in code blocks of Markdown files.
  • postcss-styled-syntax parses styles in template literals CSS-in-JS like styled-components.
  • postcss-jsx parsing CSS in template / object literals of source files.
  • postcss-styled parsing CSS in template literals of source files.
  • postcss-scss allows you to work with SCSS (but does not compile SCSS to CSS).
  • postcss-sass allows you to work with Sass (but does not compile Sass to CSS).
  • postcss-less allows you to work with Less (but does not compile LESS to CSS).
  • postcss-less-engine allows you to work with Less (and DOES compile LESS to CSS using true Less.js evaluation).
  • postcss-js allows you to write styles in JS or transform React Inline Styles, Radium or JSS.
  • postcss-safe-parser finds and fixes CSS syntax errors.
  • midas converts a CSS string to highlighted HTML.

Articles

More articles and videos you can find on awesome-postcss list.

Books

Usage

You can start using PostCSS in just two steps:

  1. Find and add PostCSS extensions for your build tool.
  2. Select plugins and add them to your PostCSS process.

CSS-in-JS

The best way to use PostCSS with CSS-in-JS is astroturf. Add its loader to your webpack.config.js:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'postcss-loader'],
      },
      {
        test: /\.jsx?$/,
        use: ['babel-loader', 'astroturf/loader'],
      }
    ]
  }
}

Then create postcss.config.js:

/** @type {import('postcss-load-config').Config} */
const config = {
  plugins: [
    require('autoprefixer'),
    require('postcss-nested')
  ]
}

module.exports = config

Parcel

Parcel has built-in PostCSS support. It already uses Autoprefixer and cssnano. If you want to change plugins, create postcss.config.js in project’s root:

/** @type {import('postcss-load-config').Config} */
const config = {
  plugins: [
    require('autoprefixer'),
    require('postcss-nested')
  ]
}

module.exports = config

Parcel will even automatically install these plugins for you.

Please, be aware of the several issues in Version 1. Notice, Version 2 may resolve the issues via issue #2157.

Webpack

Use postcss-loader in webpack.config.js:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
            }
          },
          {
            loader: 'postcss-loader'
          }
        ]
      }
    ]
  }
}

Then create postcss.config.js:

/** @type {import('postcss-load-config').Config} */
const config = {
  plugins: [
    require('autoprefixer'),
    require('postcss-nested')
  ]
}

module.exports = config

Gulp

Use gulp-postcss and gulp-sourcemaps.

gulp.task('css', () => {
  const postcss    = require('gulp-postcss')
  const sourcemaps = require('gulp-sourcemaps')

  return gulp.src('src/**/*.css')
    .pipe( sourcemaps.init() )
    .pipe( postcss([ require('autoprefixer'), require('postcss-nested') ]) )
    .pipe( sourcemaps.write('.') )
    .pipe( gulp.dest('build/') )
})

npm Scripts

To use PostCSS from your command-line interface or with npm scripts there is postcss-cli.

postcss --use autoprefixer -o main.css css/*.css

Browser

If you want to compile CSS string in browser (for instance, in live edit tools like CodePen), just use Browserify or webpack. They will pack PostCSS and plugins files into a single file.

To apply PostCSS plugins to React Inline Styles, JSS, Radium and other CSS-in-JS, you can use postcss-js and transforms style objects.

const postcss  = require('postcss-js')
const prefixer = postcss.sync([ require('autoprefixer') ])

prefixer({ display: 'flex' }) //=> { display: ['-webkit-box', '-webkit-flex', '-ms-flexbox', 'flex'] }

Runners

JS API

For other environments, you can use the JS API:

const autoprefixer = require('autoprefixer')
const postcss = require('postcss')
const postcssNested = require('postcss-nested')
const fs = require('fs')

fs.readFile('src/app.css', (err, css) => {
  postcss([autoprefixer, postcssNested])
    .process(css, { from: 'src/app.css', to: 'dest/app.css' })
    .then(result => {
      fs.writeFile('dest/app.css', result.css, () => true)
      if ( result.map ) {
        fs.writeFile('dest/app.css.map', result.map.toString(), () => true)
      }
    })
})

Read the PostCSS API documentation for more details about the JS API.

All PostCSS runners should pass PostCSS Runner Guidelines.

Options

Most PostCSS runners accept two parameters:

  • An array of plugins.
  • An object of options.

Common options:

  • syntax: an object providing a syntax parser and a stringifier.
  • parser: a special syntax parser (for example, SCSS).
  • stringifier: a special syntax output generator (for example, Midas).
  • map: source map options.
  • from: the input file name (most runners set it automatically).
  • to: the output file name (most runners set it automatically).

Treat Warnings as Errors

In some situations it might be helpful to fail the build on any warning from PostCSS or one of its plugins. This guarantees that no warnings go unnoticed, and helps to avoid bugs. While there is no option to enable treating warnings as errors, it can easily be done by adding postcss-fail-on-warn plugin in the end of PostCSS plugins:

module.exports = {
  plugins: [
    require('autoprefixer'),
    require('postcss-fail-on-warn')
  ]
}

Editors & IDE Integration

VS Code

Sublime Text

Vim

WebStorm

To get support for PostCSS in WebStorm and other JetBrains IDEs you need to install this plugin.

Security Contact

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.

For Enterprise

Available as part of the Tidelift Subscription.

The maintainers of postcss and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.

postcss-calc's People

Contributors

ai avatar alexander-akait avatar alienlebarge avatar andyjansson avatar ben-eb avatar csr632 avatar dependabot[bot] avatar douglasduteil avatar evilebottnawi avatar jamiebuilds avatar jasminexie avatar jonathantneal avatar ludofischer avatar martijncuppens avatar martinkutter avatar mischnic avatar moox avatar semigradsky avatar tannerdolby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

postcss-calc's Issues

Ignoring proper order of operations

Found an issue where it's removing the inner parenthesis needed for correct ordering of calculations. For example, the following calculates the width minus the scroll bar(which some browsers include in the vw while others don't:
width: calc(100vw - (100vw - 100%))
That should return the width of the window minus the scroll bar, but the inner parenthesis are removed and it returns:
width: calc(0vw - 100%)

Use PostCSS 4.1 API

PostCSS Plugin Guidelines are mandatory right now. Because all of rules are about ecosystem health.

Parse error with CSS custom properties with default values including a nested calc

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.

css variables within calc hang

When i use postcss-calc without prior using postcss-custom-properties, the process just hangs.

Try it like this:

var postcss = require("postcss")
var calc = require("postcss-calc")

var css = postcss()
  .use(calc())
  .process('a {width: calc(var(--foo) + 10px);}')
  .css

If I remove the var() or first resolve it via postcss-custom-properties, it works fine

Negative value?

This calc(-1 * var(--space-xl)); should be a negative value.... but the -1 is ignored!
The output is 3.25em but should be -3.25em.

CSS:

    --space-unit: 1em;
    --space-xl: calc(3.25 * var(--space-unit));

    .offset {
      top: inherit; 
      @include mq(md) {
        top: calc(-1 * 3.25em); // this works
        top: calc(-1 * var(--space-xl)); // don't work - should be negative
      }
    }

Gulp Task:

    .pipe($.postcss([
      /*
      Stylelint
      */
      $.stylelint(),
      /*
      Parse CSS and add vendor prefixes to rules by Can I Use
       */
      $.autoprefixer(),
      /*
      cssnano is a modern, modular compression tool written on top of the PostCSS ecosystem, which allows us to use a lot of powerful features in order to compact CSS appropriately.
       */
      $.cssnano({
        discardComments: {
          removeAll: true
        },
        discardDuplicates: true,
        discardEmpty: true,
        minifyFontValues: true,
        minifySelectors: true
      }),
      /*
      PostCSS-Custom-Properties lets you use Custom Properties in CSS, following the CSS Custom Properties specification.
      Example: h1 { color: var(--color); } <-- BECOMES --> h1 { color: red; color: var(--color); }
       */
      $.postcssCustomProperties(), // IE 11 polyfill
      /*
      PostCSS plugin to reduce calc()

      IE11 don't understand nested calc functions like this:
      margin-bottom: calc(calc(1.25*1em)*1)
      */
      $.postcssCalc(),
      /*
      PostCSS Error Reporter
      */
      $.postcssReporter({
        clearReportedMessages: true
      })
    ]))

Any ideas?

Incorrect calc reduction of `0 - (A - B) / C`

Given the following CSS:

left: calc(0px - (100vw - 10px) / 2);

Which I expect to become:

left: calc((-100vw - - 10px) / 2);

Actually becomes the mathematically incorrect:

left: calc((-100vw - - 10px) / -2);

Calculations with the structure 0 - (A - B) / C are incorrectly reduced to (-A - -B) - C while the correct solve is (-A - -B) / C.

Remove "calc" from unresolved nested calcs

To provide a little context and very simple example -- while keeping this short and to the point -- I am using "postcss-calc" and "postcss-advanced-variables" together (but I fully expect this issue would exist with any simply variable plugin in postcss).

Simple code to demonstrate issue:

$a: calc(21vh + 80px * 1/3 + 5px);
$b: calc(10vw + 80px * 2/3);
.test {
height: calc(21vh + $a + $b);
}

With PostCSS I evaluate the variables and then the calcs. Since the nested calcs contain mixed units the expressions can not easily be resolved resulting in:

.test{
height: calc(21vh + calc(21vh + 80px * 1/3 + 5px) + calc(10vw + 80px * 2/3));
}

While Chrome understands the above expression, Edge and IE do not. What is the best approach to get postcss-calc to remove the nested calc function calls and retain the parenthesis when a nested expression can not be resolved. The result for the above would then be the following which will work in all browsers that support calc:

.test{
height: calc(21vh + (21vh + 80px * 1/3 + 5px) + (10vw + 80px * 2/3));
}

To be clear, I am not currently concerned with the above being simplified further by postcss-calc, but simply remove the unresolved nested "calc" and leave only the outer one.

Even though the code for this plugin and its dependencies are written very clearly and well, I am unsure the best approach to addressing the above.

Deal with %

If I write calc( 100% - 50px - 20px ) it outputs calc ( 100% - 50px - 20px ) instead of calc( 100% - 70px )

Remove units in same-unit-division

I stumbled across the problem that units are still present although I am dividing by a value with the same unit.

Example:

font-size: calc(10px/16px) // should give 0.625 but gives 0.625px

Is there a way to work around this issue or is there an option to make it work?

Thanks in advance! I have been using your plugin for several years and it has helped a ton!

support constant() and env()

Hey there,

in my build setup (optimize-css-assets-webpack-plugin using cssnano) I had to disable postcss-calc because it was killing any calc() that use constant() and env() (see Designing Websites for iPhone X). Note how the 100% turned into 1:

Input

body {
  height: 100%;
  /* iPhone X on iOS 11.0 */
  height: calc(100% + constant(safe-area-inset-top) + constant(safe-area-inset-bottom));
  /* iPhone X on iOS 11+ */
  height: calc(100% + env(safe-area-inset-top) + env(safe-area-inset-bottom));
}

Output

body {
  height: 100%;
  height: calc(1 + constant(safe-area-inset-top) + constant(safe-area-inset-bottom));
  height: calc(1 + env(safe-area-inset-top) + env(safe-area-inset-bottom))
}

I tried producing a minimal test case with only postcss-calc, but all I got was:

➜  node index.js
/…/post-css-calc/node_modules/postcss/lib/lazy-result.js:280
            throw error;
            ^

Error: Parse error on line 1:
100% + constant(safe-area-i
-------^
Expecting 'SUB', 'LPAREN', 'NESTED_CALC', 'NUMBER', 'CSS_VAR', 'LENGTH', 'ANGLE', 'TIME', 'FREQ', 'RES', 'EMS', 'EXS', 'CHS', 'REMS', 'VHS', 'VWS', 'VMINS', 'VMAXS', 'PERCENTAGE', got 'PREFIX'
    at Parser.parseError (/…/post-css-calc/node_modules/reduce-css-calc/dist/parser.js:160:21)
    at Parser.parse (/…/post-css-calc/node_modules/reduce-css-calc/dist/parser.js:226:22)
    at /…/post-css-calc/node_modules/reduce-css-calc/dist/index.js:35:30
    at walk (/…/post-css-calc/node_modules/postcss-value-parser/lib/walk.js:15:13)
    at ValueParser.walk (/…/post-css-calc/node_modules/postcss-value-parser/lib/index.js:18:5)
    at exports.default (/…/post-css-calc/node_modules/reduce-css-calc/dist/index.js:29:51)
    at transformValue (/…/post-css-calc/node_modules/postcss-calc/dist/lib/transform.js:24:45)
    at exports.default (/…/post-css-calc/node_modules/postcss-calc/dist/lib/transform.js:54:100)
    at /…/post-css-calc/node_modules/postcss-calc/dist/index.js:28:52
    at /…/post-css-calc/node_modules/postcss/lib/container.js:144:26

Adding a .eslintrc

I think we'll need an .eslintrc file to ensure the quality and consistency of the javascript code. For example I noticed the mixed usage of single and double quotes in the javascript files.

Cannot use constant values

iOS 11 Safari added support for constant declarations for safe areas, eg constant(safe-area-inset-bottom) which returns a dynamic value for the amount of margin or padding needed to avoid unsafe areas. Currently, when a constant value is used in calc, it causes postcss to fail generating 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',
 __safety: { toString: [Function: bound ] } }

'Selector' option throws TypeError

With the 'selector' option set to true using 6.0.0, the plugin throws the following error. This occurs even without any selectors being built with calc() in my stylesheets.

TypeError: Cannot read property 'charCodeAt' of undefined
  at module.exports (fakepath/node_modules/postcss-value-parser/lib/parse.js:17:21)
  at new ValueParser (fakepath/node_modules/postcss-value-parser/lib/index.js:7:22)
  at ValueParser (fakepath/node_modules/postcss-value-parser/lib/index.js:10:12)
  at exports.default (fakepath/node_modules/postcss-calc/node_modules/reduce-css-calc/dist/index.js:29:43)
  at transformValue (fakepath/node_modules/postcss-calc/dist/lib/transform.js:20:45)
  at fakepath/node_modules/postcss-calc/dist/lib/transform.js:36:19
  at fakepath/node_modules/postcss-selector-parser/dist/selectors/container.js:170:26
  at Selector.each (fakepath/node_modules/postcss-selector-parser/dist/selectors/container.js:153:22)
  at Selector.walk (fakepath/node_modules/postcss-selector-parser/dist/selectors/container.js:169:21)
  at fakepath/node_modules/postcss-selector-parser/dist/selectors/container.js:173:31

Running through the gulp-postcss 7.0.0, which is using PostCSS 6.0.0

remove space in `var` and default value

/cc @andyjansson Should postcss-calc remove space in var (between name variable and default value) or we should do this in cssnano?

Input:

calc(var(--width, 100px) + 1px)

Output:

calc(var(--width, 100px) + 1px)

Expected:

calc(var(--width,100px) + 1px)

[feat] Hope to support new units 'rpx'

In China, the Wechat applet is very popular. It defines a responsive unit,'rpx'

code:

width: calc(100% - 10rpx);

I hope the above code will work properly.

Try to modify the following code to make it work

([0-9]+("."[0-9]+)?|"."[0-9]+)px\b return 'LENGTH';

//update after
([0-9]+("."[0-9]+)?|"."[0-9]+)r?px\b              return 'LENGTH';

Is this proposal acceptable to you?

Further optimization

We can calculate expressions in inner parenthesis to produce simpler result

Example:

font-size: calc(14px + 6 * ((100vw - 320px) / 448)); 

Could be expressed as:

font-size: calc(1.3392857143vw + 9.7142857143px); 

or

font-size: calc(1.34vw + 9.71px); 

if rounding applied.

Transformation removes of inner calc

ccsnano offers some configurable optimizations, like calc. Using webpack with optimize-css-assets-webpack-plugin for production builds results in transforming
calc(100vh - 5rem - calc(10rem + 100px)) to calc(100vh - 5rem - 10rem + 100px).

This is not happening though when disabling calc optimizations on default preset

preset: [`default`, { calc: false }]

To be more specific I'm trying to solve this issue gatsbyjs/gatsby#9858

(Opening issue as mentioned in cssnano/cssnano#657 (comment))

Mixed units of time do not reduce

A property value of calc(1s - 50ms) will not be reduced. Since there's functionally no difference between 950ms and .95s, I would expect the latter as the output since it can be expressed in fewer characters.

This came to my attention because I'm using cssnano, which reduces time values such as 100ms to .1s, or .045s to 45ms. The reduction occurs prior to postcss-calc and may result in an un-reduced expression. This becomes especially problematic since some browsers will not accept calc() within the value of the transition property.

Remove gnuMessage

Why you use gnuMessage? PostCSS already return error message in GNU format.

Problem on variables with `calc` on the name

Hi,

First of all, thanks for this incredible lib. Saved me lots of sleeping hours.

I'm using it to reduce some calc and use the values into some pseudo-selectors...
Unfortunately i think i probably found a bug.

I have a variable called $offset-calc, and after the postcss-calc runs its replaced to $offset-...

Here is an example of a mixin i made that uses it:

@define-mixin elements-last-row $wrapper-selector, $selector, $row-size, $offset: 0 {
  /* last row, doesn't matter how many cells */
  $offset-calc: calc($offset + 1);
  $wrapper-selector:nth-last-child(-n + $row-size):nth-child($(row-size)n + $offset-calc), /* first element of the last row */
  $wrapper-selector:nth-last-child(-n + $row-size):nth-child($(row-size)n + $offset-calc) ~ $selector { /* all its following elements */
    @mixin-content;
  }
}

Using postcss-calc inside postcss-strip-units

When I put calc() function inside strip(), I get an error saying Couldn't parse strip(calc(24px * 2)). Got NaN.

I think this error occurs because postcss-strip-units is added before postcss-calc.
So I added postcss-calc twice before and after postcss-strip-units, but unfortunately it didn't work at all.

Any idea to achieve this or workaround?

The code is something like below.

variables.css

:root {
    --a-size: 24px;
    --b-size: calc(var(--a-size) * 2);
}

type.css

h1 {
    font-size: calc(strip(var(--b-size)) * 1 rem); /* => Couldn't parse strip(calc(24px * 2)) => NaN */
}

main.css

@import 'variables.css';
@import 'type.css';

PostCSS plugins order

require('postcss-devtools')(),
require('postcss-easy-import')({addDependencyTo: webpack,prefix: '_'}),
require('postcss-url')(),
require('postcss-mixins')(),
require('postcss-extend')(),
require('postcss-each')(),
require('postcss-for')(),
require('postcss-nth-list')(),
require('postcss-simple-vars')(),
require('postcss-custom-properties')(),
require('postcss-strip-units')(),
require('postcss-conditionals')(),
require('postcss-calc')({warnWhenCannotResolve: true}),
require('postcss-cssnext')({browsers: 'last 2 versions'}),
require('css-mqpacker')(),
require('postcss-utilities')(),
require('postcss-browser-reporter')(),
require('postcss-reporter')()

Support exponential math operations

Has there been any discussion about including support for more advanced math operations such as exponents? For example: calc(2 ^ 3) or calc(var(--x) ^ 3).

Exponents are extremely useful for setting up things like modular scales. However, right now you have to multiply long strings of variables together to achieve the same result, e.g., calc(2 * var(--y) * var(--y) * var(--y) * var(--y)). As you can see, it can get quite tedious. Ideally I would prefer to write something like calc(2 * var(--y) ^ 4) instead.

What are your thoughts on implementing support for exponents?

Cannot wrap inner value in negative

Not sure how to title this issue correctly, but the issue is if you do something like

left: calc(-(10px + (10px / 2)));

postcss-calc gets mad and says:

-(10px + (10px / 2))
-^
Expecting 'SUB', 'PREFIX', 'NUMBER', 'LENGTH', 'ANGLE', 'TIME', 'FREQ', 'RES', 'EMS', 'EXS', 'CHS', 'REMS', 'VHS', 'VWS', 'VMINS', 'VMAXS', 'PERCENTAGE', got 'LPAREN'

But I think this should work... and it did in older versions.

[edit] Added a test to verify, you can see the error if you attempt this test: TheSisb@375688a

Browserlist support

This is more a kind of question:

  • Would it make sense if postcss-calc transformations were based on the browsers support configured through browserlist?
  • How would this affect postcss-calc?
  • If postcss-calc is not the correct repository to implement such logic, which one would be? Would it be cssnano-preset-default or a different one?

For example by using cssnano-preset-default we can define this configuration in postcss.config.js:

module.exports = {
   plugins: [
       require('cssnano')({
         preset: ['default', {
             calc: false,
         }]
       }),
   ],
};

Why is default precision 5?

Re: MoOx/postcss-cssnext#254

calc(100px / 3) = 33.33px in IE

calc(100px / 3) = 33.328px in everything else

The consequence of this is http://codepen.io/corysimmons/pen/MKQVGp?editors=1100 is a 3 column grid in everything but IE, and with cssnext turned off, it works in IE.

Is there a particular reason the default precision is 5? If not, would it be possible to tinker around with the default precision (I think 2 might be a good one to start with since IE only works with 2 spots) and consider changing it so things like Lost and cssnext work side-by-side without special configuration?

Really hope we can figure this out as I'd love to pull postcss-calc into some projects by default (my calc functions are super hairy and I think postcss-calc would make them much more palatable).

Support or skip quirk unit?

I'm using cssnano with postcss-calc in wechat-mini-program development.

Wechat introduces a unique unit called 'rpx' represent 1/750 of the device width.

When using [email protected] with postcss-calc, an error

Error: Lexical error on line 1. Unrecognized text.
  100% - 50rpx
  -------^

returned..

Support for multiline calc()

Currently, postcss-calc only do the job when calc() value is on one line. But if it's on more that one line, it doesn't work.

One line

input.css

h1 {
    font-size: calc( 1rem * 1.26 * 1.26 * 1.26 );
}

output.css

h1 {
    font-size: font-size: 2.00038rem;
}

Multi line

input.css

h1 {
    font-size: calc( 
                       1rem 
                       * 1.26 
                       * 1.26
                       * 1.26
                   );
}

output.css

h1 {
    font-size: calc( 
                       1rem 
                       * 1.26 
                       * 1.26 
                       * 1.26 
                   );
}

Is it possible to support


There's a workaround in the meantime.
I use perfectionist before postcss-calc

Media Query Calc

Since this plugin only looks at declarations if you try using it for @media queries it won't work.

@media (calc(100px + 200px)) {}

Reading the specification this should be valid

Unable to install dependencies

After cloning project locally, I'm not able to install the dependencies with yarn install.

Generated error:
error Couldn't find package "@babel/cli" on the "npm" registry.

Seems like del-cli has a dependency on registry-auth-token which requires an auth token to complete npm related actions.

Missing unit after 0

I use postcss-calc in cssnano and calc(50% - 50vw + (100vw - 100vw) / 2 + 1em) gets optimized to calc(50% - 50vw + 0 / 2 + 1em). Unfortunately, the unit after 0 is missing and the browser does not calculate the calc()statement.

calc(50% - 50vw + 0vw / 2 + 1em) would be the correct optimization.

Or even better: calc(50% - 50vw + 1em)

0 vs 0+ unit.

(If you wonder why I calculate 100vw - 100vw: it’s been generated by a Sass mixin and in most cases it makes more sense.)

Nested calc not resolved (with mixed units).

Hey, so I have something like this:

font-size: calc(1.618 * calc(1.618 * calc(1.618 * 1em)));

This code is generated, from individual calc statements, which is why there is a calc and not only a () within the code.

Since safari can't handle calc within calc and starts crying, I would love this to be resolved to:

font-size: calc(1.618 *(1.618 *(1.618 * 1em)));

Any idea why it does not work? Is this because of the mixed unit? Couldn't this be handled, so that calc is reduced in any case?

Allow rounding option

This option allows users to limit the default precision to what's defined in precision, but doesn't round the number if the rounded number isn't equal to the number itself. This may sound a bit vague, so let's demonstrate this with an example:

Let's assume you have configured precision: 5 and allowRounding: false:

  • calc(100% / 3) will output calc(100% / 3) because calc(100% / 3) != 33.33333%
  • calc(100% / 4) will output 25% because calc(100% / 4) == 25%

What's the advantage? We never have rounded numbers which can cause issues like twbs/bootstrap#27374 and we don't have expressions like calc(100% / 4) that can be simplified.

PR: #61

Breaks CSS variables that include "calc" in their name

It appears that postcss-calcis incorrectly matching the word calc from within a css variable name.

The source:

transform: translateY(calc(-100% - var(--tooltip-calculated-offset)))

Is being transformed into

transform: translateY(calc(-100% - var(-ulated-offset)))

I suspect a more complex calc match regex would be needed to exclude variables that just contain the word fragment "calc".

[Question] Floor and Ceil?

Hi,

I'm wondering if there's a way to round pixel calculations up or down. For example the following:

:root {
  --fontSizeUnit: 1px;
  --fontSizeRatio: 0.75;
}

h1 {
  font-size: var(--fontSize);
}

Will come out as:

```css
h1 {
font-size: 0.75px;
}

I would like it to be:

h1 {
font-size: 1px;
}

TIA,
Ole

Add precision option

For the moment, the plugin uses 5 as a magic number to define the number of digits of precision.
I didn't find any line in the documentation which explains this choice but in some cases it doesn't make sense : Em values are rounded or truncated at 2 decimals.
I'm sure that if we search in your experience, we will find many problematic cases with the use of the decimals.

I'm trying an experience with this mathematical expression (100% * 1 / 3) to look at the other tools:

Tool Result Precision
Stylus 33.333333333333336% 15
Sass 33.33333% 5
Less.js 33.33333333% 8
cssnext 33.33333% 5
reworkcss 33.33333333333333% 14

I'm not surprised by this huge difference between tools, and obviously none of them clearly explains its choice about the precision.
For that, it could be interesting to allow users to define their own precision with an option (e.g.: precision) like Sass does.

Plus, if we decide to go ahead and that we take note of this article Using decimal percentage values in responsive design by Divya Manian, we could add a second option (e.g.: preserve) like the plugin postcss­-custom-properties to have an acceptable result (current working) but also it would allow browsers to do their own optimizations for accuracy with the calc() function.

Exemple with the options precision: 3 and preserve: true:

h1 {
  width: calc(1/6 * 100%)
}

you will get:

h1 {
  width: 16.667%;
  width: calc(1/6 * 100%)
}

I don't think it would be important to preserve calc() if the result is an integer (e.g.: calc(10px * 2)) but the behaviour could be disturbing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.