Giter Site home page Giter Site logo

cssnano / cssnano Goto Github PK

View Code? Open in Web Editor NEW
4.6K 49.0 318.0 31.34 MB

A modular minifier, built on top of the PostCSS ecosystem.

Home Page: https://cssnano.github.io/cssnano/

License: MIT License

JavaScript 21.93% CSS 77.60% Nunjucks 0.46%
postcss cssnano optimisation css minification

cssnano's Introduction


cssnano


A modular minifier, built on top of the PostCSS ecosystem.

Backers on Open Collective Sponsors on Open Collective NPM version Build Status codecov Gitter

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.

Our preset system allow you to load cssnano in a different configuration depending on your needs; the default preset performs safe transforms, whereas the advanced preset performs more aggressive transforms that are safe only when your site meets the requirements; but regardless of the preset you choose, we handle more than whitespace transforms!

Optimisations range from compressing colors & removing comments, to discarding overridden at-rules, normalising unicode-range descriptors, even mangling gradient parameters for a smaller output value! In addition, where it's made sense for a transform, we've added Browserslist to provide different output depending on the browsers that you support.

For further details check out the website:

You can now try cssnano online!

Contributing

See CONTRIBUTING.md.

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

License

MIT © Ben Briggs

cssnano's People

Contributors

ai avatar akx avatar alexander-akait avatar an-tu avatar andyjansson avatar anikethsaha avatar ben-eb avatar btea avatar chriseppstein avatar clshortfuse avatar colinrotherham avatar dependabot[bot] avatar evilebottnawi avatar evless avatar genemecija avatar greenkeeperio-bot avatar jamesgeorge007 avatar johannesodland avatar justineo avatar ludofischer avatar nex3 avatar rizkit avatar sethfalco avatar sigveio avatar siilwyn avatar sindresorhus avatar soda-x avatar trysound avatar wongjn avatar yisibl 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  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

cssnano's Issues

cssnano removes vh units.

I'm using cssnano to minify this CSS code (with postcss)

.hero {
    height: 80vh;
}

When I add cssnano and minify the CSS it removes this attribute if its value its expressed in vh.
If I disable cssnano it works ok.
If I change the value to PX or % it works correctly.

Thanks!

Screenshot testing

We with @TrySound invented good way to test cssnano.

Right now we have many tools to test CSS based on screenshots. In real project they work badly, but for CSS minifiers this screenshot based tests are awesome:

  1. We get some CSS from Twitter, Bootstrap and other popular project. And store it in ome special repo. There is not need to update and change this CSS.
  2. We run some webkit engine from npm and save ideal screenshots in repo.
  3. We process these CSS through cssnano.
  4. We make screenshots for these processed CSS and compare them pixel-to-pixel with ideal screenshots.

There is two way to make css minifier popular: size and trust. I think there is no css minifier with testing, so if will have really good test cases, we can promote cssnano as trusted minifiers.

cssnano through postcss-loader (WebPack)

I would like to use CSSNano's powers through WebPack...but I just can't get the loader to pick up cssnano.

I tried a variation of calling cssnano as a function or just supplying it inside the return array; like so:

    postcss: function(){
        return [
            cssnano()
        ];
    },

Would be nice if someone could help me here! :)

refactor index.js

what about this refactor, it looks a lot better and cleaner.
also fixes possible thrown TypeError: Cannot read property 'inline' of undefined from L57

'use strict';

var Postcss = require('postcss');

var processors = {
  'postcss-discard-comments': 'comments',
  'postcss-zindex': null,
  'postcss-discard-empty': null,
  'postcss-minify-font-weight': null,
  'postcss-convert-values': null,
  'postcss-calc': 'calc',
  'postcss-colormin': null,
  'postcss-pseudoelements': null,
  './lib/filterOptimiser': null,
  './lib/longhandOptimiser': null,
  'postcss-minify-selectors': null,
  'postcss-single-charset': null,
  // font-family should be run before discard-font-face
  'postcss-font-family': null,
  'postcss-discard-font-face': null,
  'postcss-normalize-url': 'urls',
  'postcss-reduce-idents': 'idents',
  './lib/core': null,
  // Optimisations after this are sensitive to previous optimisations in
  // the pipe, such as whitespace normalising/selector re-ordering
  './lib/borderOptimiser': null,
  'postcss-discard-duplicates': null,
  './lib/functionOptimiser': null,
  'postcss-merge-rules': 'merge'
};
// var namespaces = {
//   'postcss-discard-comments': 'comments',
//   'postcss-zindex': 'zindex',
//   'postcss-calc': 'calc',
//   'postcss-normalize-url': 'urls',
//   'postcss-reduce-idents': 'idents',
//   'postcss-merge-rules': 'merge'
// };

module.exports = function cssnano(css, options) {
  if (typeof css === 'object') {
    options = css;
    css = null;
  }
  options = options || {};
  options = typeof options === 'object' ? options : {};
  var postcss = Postcss();
  var plugins = Object.keys(processors);
  var len = plugins.length;
  var i = 0;

  while (i < len) {
    var plugin = plugins[i++];
    var ns = processors[plugin];
    options = ns && options[ns] ? options[ns] : options;

    if (options.disable) {
      continue;
    }
    postcss.use(require(plugin)(options));
  }

  if (typeof css === 'string') {
    var result = postcss.process(css, options);
    // return a css string if inline/no sourcemap.
    if (options.map && options.map.inline || !options.map) {
      return result.css;
    }
    // otherwise return an object of css & map
    return result;
  }

  return postcss;
};

Whitespace not removed in some case instances

Just trying this for the first time. Config is via PostCSS plugin inside a gulp task. No options set and I get weird whitespace included in lots of cases. Here is a tiny snippet:

background-repeat:no-repeat}.sport_1:before,.sport_31:before,.sport_74:before,.sport_82:before{
    background-position:50% 2px}.sport_2:before,.sport_73:before,.sport_81:before{
    background-position:50% -1081px}.sport_3:before{
    background-position:50% -2109px}.sport_4:before,.sport_85:before{
    background-position:50% -3135px}.sport_5:before,.sport_129:before,.sport_130:before,.sport_131:before,.sport_132:before,.sport_133:before,.sport_134:before,.sport_135:before,.sport_136:before,.sport_137:before,.sport_800:before,.sport_996:before{
    background-position:50% -57px}.sport_6:before{
    background-position:50% -855pt}.sport_7:before{
    background-position:50% -2166px}.sport_8:before{
    background-position:50% -2337px}.sport_9:before{

Expected:

background-repeat:no-repeat}.sport_1:before,.sport_31:before,.sport_74:before,.sport_82:before{background-position:50% 2px}.sport_2:before,.sport_73:before,.sport_81:before{background-position:50% -1081px}.sport_3:before{background-position:50% -2109px}.sport_4:before,.sport_85:before{background-position:50% -3135px}.sport_5:before,.sport_129:before,.sport_130:before,.sport_131:before,.sport_132:before,.sport_133:before,.sport_134:before,.sport_135:before,.sport_136:before,.sport_137:before,.sport_800:before,.sport_996:before{background-position:50% -57px}.sport_6:before{background-position:50% -855pt}.sport_7:before{background-position:50% -2166px}.sport_8:before{background-position:50% -2337px}.sport_9:before{

cssnano breaks font inclusions

We are using this approach to include fonts in our css but this module seems to break it:

@import url("http://fast.fonts.net/t/1.css?apiType=css&projectid=[censor]");
@font-face{
font-family: "avenir next light";
src:url("../fonts/avenir/7bf72cf4ff-a744-4420-ad96-b982fd3cs23a7.eot?#iefix");
src:url("../fonts/avenir/7bf72c4f-a74g4-4420-gad96-b982fd3cs23a7.eot?#iefix") format("eot"),
url("../fonts/avenir/fd1f3434-eb5b-47f67-8593-e6cfcbfd15s58.woff2") format("woff2"),
url("../fonts/avenir/f6ebea36-fb7c-4458-a43e-2f112c48c17e4.woff") format("woff"),
url("../fonts/avenir/2d80c4f84e-3493-4ca8-ad53-b7decaf9a4f9.ttf") format("truetype"),
url("../fonts/avenir/4869d6f6c-eff9f-49fc-9c1e-f3a65852fb092.svg#48696f6c-ef9f-49fc-9c1e-f3a65852b092") format("svg");
}

'TypeError: Cannot call method 'indexOf' of undefined' when uglifying CSS

I'm getting this error on a few of my CSS files when running webpack -p, something about uglifying the CSS. Anyone recognize an error like this, or can point me in the direction of a more detailed stack trace? I get the error on 7 out of 100 or so css files. Combed through the files and couldn't find any weird syntax stuff.

ERROR in ./~/css-loader!./~/cssnext-loader!./app/styles/index.css
TypeError: Cannot call method 'indexOf' of undefined

Any help would be greatly appreciated.

Changes in cssnano v2.0

Here are some changes I'd like to propose for version 2:

  1. Deprecate the main method and expose as a PostCSS plugin for compatibility with plugin guidelines. This is to allow people to easily consume cssnano using a PostCSS workflow, which I would like to promote over using a simple node.js workflow; simply because it makes more sense to have a pipeline of plugins such as gulp does, as parsing doesn't have to occur multiple times. I feel that plugins such as gulp-cssnano are just intended as something that you can use to swap for another minifier if you don't have some existing PostCSS pipeline, but really it is best to use the PostCSS workflow I think.
  2. For those plugins though, we should expose a new process method which will work exactly the same as the main method currently does.
  3. Remove node 0.10 compatibility - postcss-normalize-url fails tests on 0.10, and because I don't work on 0.10 anymore I would rather not have to try and include hacks for it. People on node 0.10 can still use v1.
  4. Start extracting out the lib directory into modules. The reason for this still being there is mostly because these processors are not fully complete yet, or their functionality combines multiple actions that wouldn't make sense as a single plugin.

My plan is to finish off this selector parser for postcss-minify-selectors before anything in this list, then I can start work on the items here.

/cc @sindresorhus @MoOx @morishitter as cssnano consumers 😃

Weird warnings when consuming this with webpack

I have a specific need that not so specific: I am building a browser version of cssnext for the playground.
Not that cssnext embed cssnano I have weird notice when I make this build with webpack

It looks like some part of cssnano are being consumed via a require or something smiliar that make webpack think we want to consume some non js file.

WARNING in ./~/cssnano/index.js
Critical dependencies:
57:20-35 the request of a dependency is an expression
 @ ./~/cssnano/index.js 57:20-35

WARNING in ./~/cssnano/CHANGELOG.md
Module parse failed: /Users/MoOx/Sync/Development/cssnext/cssnext/node_modules/cssnano/CHANG
ELOG.md Line 1: Unexpected token ILLEGAL
You may need an appropriate loader to handle this file type.
| # 1.2.0
|
| * Better support for merging properties without the existance of a shorthand
 @ ./~/cssnano ^\.\/.*$

WARNING in ./~/cssnano/LICENSE-MIT
Module parse failed: /Users/MoOx/Sync/Development/cssnext/cssnext/node_modules/cssnano/LICEN
SE-MIT Line 1: Unexpected identifier
You may need an appropriate loader to handle this file type.
| Copyright (c) Ben Briggs <[email protected]> (http://beneb.info)
|
| Permission is hereby granted, free of charge, to any person
 @ ./~/cssnano ^\.\/.*$

WARNING in ./~/cssnano/bin/cmd.js
Module parse failed: /Users/MoOx/Sync/Development/cssnext/cssnext/node_modules/cssnano/bin/c
md.js Line 1: Unexpected token ILLEGAL
You may need an appropriate loader to handle this file type.
| #!/usr/bin/env node
|
| var fs = require('fs');
 @ ./~/cssnano ^\.\/.*$

WARNING in ./~/cssnano/README.md
Module parse failed: /Users/MoOx/Sync/Development/cssnext/cssnext/node_modules/cssnano/READM
E.md Line 1: Unexpected token ILLEGAL
You may need an appropriate loader to handle this file type.
| # cssnano [![Build Status](https://travis-ci.org/ben-eb/cssnano.svg?branch=master)][ci] [!
[NPM version](https://badge.fury.io/js/cssnano.svg)][npm] [![Dependency Status](https://gemn
asium.com/ben-eb/cssnano.svg)][deps] [![Gitter](https://badges.gitter.im/Join Chat.svg)](htt
ps://gitter.im/ben-eb/cssnano?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_co
ntent=badge)
|
| > A modular minifier, built on top of the [PostCSS] ecosystem.
 @ ./~/cssnano ^\.\/.*$

WARNING in ./~/cssnano/bin/usage.txt
Module parse failed: /Users/MoOx/Sync/Development/cssnext/cssnext/node_modules/cssnano/bin/u
sage.txt Line 1: Unexpected token {
You may need an appropriate loader to handle this file type.
| Usage: cssnano [input] [output] {OPTIONS}
|
| Options:
 @ ./~/cssnano ^\.\/.*$

From what I see, you are doing some dynamic require() which is not ideal for 2 things:

  • browser build
  • not future proof (see es6 imports)

But I get the lazy loading.
Maybe you should consider using a solution similar like cssnext does ? https://github.com/cssnext/cssnext/blob/0a5d06f4c1a71b5b62d450029d46dfa6cba0b333/index.js#L38-L93
I know this is verbose, but having hardcoded require() make this easier to consume, especially for webpack and browserify.

Strange rule optimisations

I'm using cssnano 2.0.3 as required ("cssnano": "^2.0.1") by cssnext 1.8.0.

From a bunch of rules, cssnano out of the box takes identical proprieties/values from more or less adjacent classnames (say a{} b{}) and creates a new rule a,b{} with the common proprieties/values. Is it possible to disable that? It can lead to nasty side effects.

Moreover, depending on the classnames, the identical rules picked up for factorisation are not always the same!
Eg, from

.foo {
  font-size: 13px;
  font-size: 0.8125rem;
  display: block;
  font-family: Trade Gothic, Trade Gothic W01, Trade Gothic wf, Helvetica Neue, Helvetica, Arial, sans-serif;
  font-weight: bold;
}

.bar {
  display: block;
  font-size: 11px;
  font-size: 0.6875rem;
}

.baz {
  font-size: 15px;
  font-size: 0rem;
  display: inline-block;
  border: 1px solid #fff;
  padding: 8px 10px;
  padding: 0.5rem 0.625rem;
  line-height: 1;
  font-family: Trade Gothic, Trade Gothic W01, Trade Gothic wf, Helvetica Neue, Helvetica, Arial, sans-serif;
  font-weight: bold;
}

.lorem,
.ipsum {
  font-size: 11px;
  font-size: 0.6875rem;
  display: block;
}

I get (if I make it readable)

.foo {
  font-size: 13px;
  font-size: .8125rem;
  font-family: Trade Gothic, Trade Gothic W01, Trade Gothic wf, Helvetica Neue, Helvetica, Arial, sans-serif;
  font-weight: 700
}

.bar,
.foo {
  display: block
}

.bar {
  font-size: 11px;
  font-size: .6875rem
}

.baz {
  font-size: 15px;
  font-size: 0;
  display: inline-block;
  border: 1px solid #fff;
  padding: 8px 10px;
  padding: .5rem .625rem;
  line-height: 1;
  font-family: Trade Gothic, Trade Gothic W01, Trade Gothic wf, Helvetica Neue, Helvetica, Arial, sans-serif;
  font-weight: 700
}

.ipsum,
.lorem {
  font-size: 11px;
  font-size: .6875rem;
  display: block
}

In this case, it's display: block from .bar and .foo.
But here :

.foobam {
  font-size: 13px;
  font-size: 0.8125rem;
  display: block;
  font-family: Trade Gothic, Trade Gothic W01, Trade Gothic wf, Helvetica Neue, Helvetica, Arial, sans-serif;
  font-weight: bold;
}

.barem {
  display: block;
  font-size: 11px;
  font-size: 0.6875rem;
}

.bazzaz {
  font-size: 15px;
  font-size: 0rem;
  display: inline-block;
  border: 1px solid #fff;
  padding: 8px 10px;
  padding: 0.5rem 0.625rem;
  line-height: 1;
  font-family: Trade Gothic, Trade Gothic W01, Trade Gothic wf, Helvetica Neue, Helvetica, Arial, sans-serif;
  font-weight: bold;
}

.loremL,
.ipsumI {
  font-size: 11px;
  font-size: 0.6875rem;
  display: block;
}

(i.e, same as the first example, except that the classnames have changed)

I get

.foobam {
  font-size: 13px;
  font-size: .8125rem;
  display: block
}

.barem {
  display: block;
  font-size: 11px;
  font-size: .6875rem
}

.bazzaz,
.foobam {
  font-family: Trade Gothic, Trade Gothic W01, Trade Gothic wf, Helvetica Neue, Helvetica, Arial, sans-serif;
  font-weight: 700
}

.bazzaz {
  font-size: 15px;
  font-size: 0;
  display: inline-block;
  border: 1px solid #fff;
  padding: 8px 10px;
  padding: .5rem .625rem;
  line-height: 1
}

.ipsumI,
.loremL {
  font-size: 11px;
  font-size: .6875rem;
  display: block
}

Now the targeted classes are .bazzaz and .foobam with a proprieties font-family and font-weight!

Maximum call stack size exceeded

Hello!
Faced a bug.
A css chunk:

@keyframes fadeOut{
    0%{
        opacity: 1;
    }
    100%{
        opacity: 0;
    }
}
@keyframes fadeOut {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}
.fadeOut{
    animation-name: fadeOut;
}

If to call cssnano style.css style.min.css it results in:

$ cssnano ../css/style.css ../css/style.min.css
/usr/local/lib/node_modules/cssnano/node_modules/postcss/lib/lazy-result.js:194
            throw error;
                  ^
RangeError: Maximum call stack size exceeded
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:7:29)
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:9:20)
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:9:20)
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:9:20)
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:9:20)
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:9:20)
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:9:20)
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:9:20)
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:9:20)
    at recurse (/usr/local/lib/node_modules/cssnano/node_modules/postcss-merge-idents/index.js:9:20)

Need version bump?

NPM install is pulling an older version of the package (even after cleaning local cache). It is probably due to the cssnano package version number remaining at 2.6.1 after the upgrade to postcss 5.

Thanks.

Who is using cssnano?

I'd like to add an area to the cssnano website with some company logos and links back to websites that use cssnano, with a minimum of 6 companies. If there are a lot of submissions then I will consider doing a separate page, but if there are only a few then I will dedicate a small section on the homepage for this.

If you'd like to get your company on this list, then I'd like an SVG of your logo & any brand guidelines for its use, your company name (correctly formatted) and of course your company homepage.

Thanks. ❤️

Deprecated APIs

I get this everytime I use nano with postcss

Container#eachInside is deprecated. Use Container#walk instead.
Node#between is deprecated. Use Node#raws.between
Rule#_selector is deprecated. Use Rule#raws.selector
Node#_value was deprecated. Use Node#raws.value
Node#_important was deprecated. Use Node#raws.important
Container#eachAtRule is deprecated. Use Container#walkAtRules instead.
Container#eachRule is deprecated. Use Container#walkRules instead.
Container#eachDecl is deprecated. Use Container#walkDecls instead.
Node#before is deprecated. Use Node#raws.before
Node#after is deprecated. Use Node#raws.after
Node#semicolon is deprecated. Use Node#raws.semicolon

@font-face being removed

Hi there,

Just wondering what option I need to set to prevent cssnano from removing an @font-face declaration which is being used.

This is my grunt task definition...

postcss: {
      options: {
        map: false,
        processors: [
          require('pixrem')(), // add fallbacks for rem units
          require('autoprefixer-core')({browsers: 'last 2 version'})
          require('cssnano')() // minify the result
        ]
      },
      dist: {
        src: 'public/css/*.css'
      }
    },

Would be very grateful for tips or suggestions here.

Support multiple values merge

input:

h1 {
    border: 1px solid red;
    background-color: red;
    background-position: 50% 100%;
}

h1 {
    border: 1px #f00 solid;
    background-color: #f00;
    background-position: center bottom;
}

h1 {
    border: solid 1px rgb(255, 0, 0);
}

output:

h1 {
    border: 1px solid red;
    background-color: red;
    background-position: 50% 100%;
}

IE8 issue

Hi!

After processing background: url(image.png) no-repeat becomes background:url(image.png)no-repeat. As you see, there is no whitespace character between properties, so it causes IE8 to fail parsing.

TypeError: Cannot read property 'split' of undefined

Version 2.2 of cssnano fails on files that 2.1 processes without error. The output from 2.2 is: TypeError: Cannot read property 'split' of undefined.

How can I get more detailed information about the failure in order to provide you with a more useful bug report?

$ trouble

.a:after {
    content: '$';
}

with defaults compiles to

.a:after{content:'}

Background none replacement with 0 0

I’m having trouble with these lines in the core.js file:
https://github.com/ben-eb/cssnano/blob/master/lib/core.js#L27-L29

if (declaration.prop === 'background') {
  declaration.value = declaration.value.replace('none', '0 0');
}

The code doesn’t work for me if I specify none as a background image, because replacing it with 0 0 wrecks the whole declaration.

With CSS like this:

h1 {
    background: none left top / cover no-repeat transparent;
}

I would expect this result:

h1{background:none left top/cover no-repeat transparent}

But instead the none gets replaced with 0 0 mucking up the image value and the browser interprets it as a position or something.

h1{background:0 0 left top/cover no-repeat transparent}

Any thoughts on what I can do about it?

merge option

var fs = require("fs")
var nano = require("..")
var postcss   = require('postcss');

var input = fs.readFileSync("input.css", "utf8")

var output =
     postcss()
     .use(nano( {
       calc: false,
       merge : false,
       comments : {
         removeAll : true
       }
    }
   ))
   .process(input).css

fs.writeFileSync("index.output.css", output)
console.log(output)

input.css :



/*! heading */
h1 {
    margin:0 auto;
    z-index:2;
    font-size: calc((3px * 2 - 1px));
}
/*! heading 2 */
h2 {
    color:red;
    z-index:3;
    margin-top:2px;
    margin-right:1px;
    margin-bottom:2px;
    margin-left:1px;
}

output.css

h1{margin:0 auto;z-index:1;font-size:calc((3px * 2 - 1px))}h2{color:red;z-index:2;margin:2px 1px}

Disable unsafe rules by default

I just wasted a bunch of time tracking down a problem caused by cssnano's z-index optimization. You should disable unsafe rules by default, especially for something like z-index optimization which will likely only save a couple characters.

Cutting off the end of calc

This is a new regression from 2.2.0 to 2.3.0.

Given this input css:

.file-path-input.invalid {
  margin: 1px 1px calc(0.5em + 1px);
}

2.2.0 outputs this:

.file-path-input.invalid{margin:1px 1px calc(.5em + 1px)}

2.3.0 outputs this:

.file-path-input.invalid{margin:1px 1px calc(.5em +}

You can see that the 2.3.0 output is stripping the second half of the calc statement.

Improvements - what will help make this more production ready?

I am going to pause development of this project for a few weeks until all of my deadlines are met, and hope to resume around the 16th of May. I just wanted to get some thoughts down on what I mean by the first line of the README:

Note that this project is still a work in progress, and needs more testing before it can be recommended to use in production. There are some optimisations that need to be further expanded upon, and others yet to be written.

In my mind, the other stand-out project for minifying CSS is clean-css, which offers really good advanced compression. So, people using cssnano should be aware that clean-css may offer better compression, while fine tuning is still being done on each PostCSS processor. For example, there is a critical bug in postcss-minify-selectors, and an optimisation that should be made for postcss-convert-values:

Also note that cssnano has no built in logic for removing browser specific hacks, which csswring and clean-css provide. I think such a module needs fine control over browser support, like Autoprefixer, so I didn't just want to remove those styles, as yes there are still people using things like IE6 (that's why cssgrace exists), even though it is a dead browser. I have had some more ideas for optimisations that I would love to consume in cssnano, and if anyone would like to turn these into PostCSS processors, please do so and post here that you're working on them!

  • A processor for removing vendor specific hacks. (done, will be default in v3)
  • A processor for running inline svg through SVGO. (done, will be default in v3)
  • postcss-discard-font-face should be deprecated, and the logic should be expanded to form a new postcss-discard-unused module - that is responsible for discarding font faces, keyframes, and counter styles. (done)
  • A processor that can properly handle overridden properties, whilst taking into account fallbacks, such as a transparent color falling back to a solid color.
  • A processor that knows browser defaults and can remove unnecessary values. (not safe)
  • A processor that is aware of currentColor and can compress this example: (not categorically safe, see http://jsfiddle.net/a1gc58on/)
h1 {
  color: orange;
  border: 1px solid orange;
}

To:

h1 {
  color: orange;
  border: 1px solid;
}

Of course, you can also help by testing cssnano on your CSS files and observing the output. The main issue is this minify-selectors bug, so that will be my main priority once I resume work on the module.

Why convert pixels to pica?

Hopefully just a quick question. I'm intrigued as to why you convert pixel values to pica? I'm just having a play with cssnano and spotted that it does this, but only for values that are equal to 16px (in my case anyway).

Add CSS multiple animation syntax support

Hello,

When using multiple animations in the same animation property, the first one works, but the second one gets its keyframes deleted.

Code used:

@keyframes three-quarters-loader {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
}

@keyframes loaderIn{
    from{
        border-width:0;
        opacity:0;
    }
}

.loader {
    animation: three-quarters-loader 1250ms infinite linear, loaderIn .3s ease-out both; /* Only the first animation plays */
}

Cheers!

Roadmap for version 3.

Wanted to get some feedback on the next version of cssnano, and see if this plan is line with everyone's expectations.

After a lot of feedback from users (#24, #27, #28, #40) & a proposed pull request #35, I've decided to give users the ability to disable any part of cssnano that they choose. But I want to do it in a way that is easily documentable and easy to configure. What I am proposing is that each optimisation can either be camelCased, like postcssMergeRules or specified as the module name like postcss-merge-rules. Furthermore, I would like the postcss prefix to be optional, so that a configuration looks more like this:

{
  autoprefixerCore: {browsers: 'last 3 versions'},
  discardComments: {removeAll: true},
  mergeIdents: false,
  mergeRules: false
}

The idea for this will be implemented in 2.x, and current options will print deprecation warnings until 3.x. 3.x will also remove the synchronous API in favour of an asynchronous, promise based one. This is so that we can bundle https://github.com/ben-eb/postcss-svgo as a further optimisation. At the same time I will look into bundling https://github.com/ben-eb/stylehacks, which will likely share a browsers option with autoprefixer.

Another idea that I am considering is to implement a safe option, which will disable all unsafe optimisations like postcss-zindex etc, which rely on a whole site's CSS to be passed in to be safe.

Other than that, the next optimisations are looking at longhand merging #44 & anything left over in #7.

PostCSS 5

Hi, I noticed that the master branch is updated and your library now use PostCSS 5, but the last NPM package available doesn't.
Can you please release the updated version?

Thanks :)

Wilcard hack break other properties

Hi,
I tried to minify the following code and the output is not as expected.
In the first rule, the wilcard (* hack) for zoom property seems to generate wilcard for other properties in other rules. But not all rules.

.classA {
*zoom: 1;
}
.classB {
box-sizing: border-box;
position: relative;
min-height: 100%;
}
.classC {
box-sizing: border-box;
position: relative;
}
.classD {
box-sizing: border-box;
position: relative;
}

Output :
.classA{_zoom:1}.classB{min-height:100%}.classB,.classC{_box-sizing:border-box;*position:relative}.D{box-sizing:border-box;position:relative}

We see new wilcards on *box-sizing and *position. But only for .classB and .classC.
If we remove the wilcard, all is ok.
Plus, I can't explain why .classD is not merged in the same selector as .classB and .classC.

Cannot read property 'pre' of undefined

events.js:141
      throw er; // Unhandled 'error' event
            ^
TypeError: Cannot read property 'pre' of undefined
    at /Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/cssnano/lib/functionOptimiser.js:29:22
    at eachCssFunction (/Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/cssnano/lib/util/eachCssFunction.js:12:59)
    at /Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/cssnano/lib/functionOptimiser.js:26:9
    at /Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/postcss/lib/container.js:126:34
    at /Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/postcss/lib/container.js:104:26
    at Rule.each (/Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/postcss/lib/container.js:91:22)
    at Rule.eachInside (/Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/postcss/lib/container.js:103:21)
    at /Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/postcss/lib/container.js:107:32
    at Root.each (/Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/postcss/lib/container.js:91:22)
    at Root.eachInside (/Users/kud/Projects/_playmedia/play-tv/node_modules/gulp-cssnext/node_modules/cssnext/node_modules/postcss/lib/container.js:103:21)

Bad transformation

Using cssnano 3.0.0. I have this css:

test.css

body {
  background-image: linear-gradient(
    45deg,
    transparent 25%,
    rgba(255,255,255,.2) 25%,
    rgba(255,255,255,.2) 75%,
    transparent 75%,
    transparent
  ), linear-gradient(
    45deg,
    transparent 25%,
    rgba(255,255,255,.2) 25%,
    rgba(255,255,255,.2) 75%,
    transparent 75%,
    transparent
  );
}
$(npm bin)/cssnano < test.css
body{background-image:linear-gradient(45deg,transparent 25%,hsla(0,0%,100%,.2) 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent),linear-gradient(45deg,transparent 25%,hsla(0,0%,100%,.2))}%

The second linear-gradient is missing a bunch of stuff. Expected:

body{background-image:linear-gradient(45deg,transparent 25%,hsla(0,0%,100%,.2) 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent),linear-gradient(45deg,transparent 25%,hsla(0,0%,100%,.2) 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent)}
-body{background-image:linear-gradient(45deg,transparent 25%,hsla(0,0%,100%,.2) 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent),linear-gradient(45deg,transparent 25%,hsla(0,0%,100%,.2))}
+body{background-image:linear-gradient(45deg,transparent 25%,hsla(0,0%,100%,.2) 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent),linear-gradient(45deg,transparent 25%,hsla(0,0%,100%,.2) 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent 25%,hsla(0,0%,100%,.2) 75%,transparent 75%,transparent)}

Error in postcss-minify-selectors

"cssnano": "^2.1.1",

events.js:85
      throw er; // Unhandled 'error' event
            ^
TypeError: Cannot read property 'length' of undefined
    at Object.split (/Users/xxxx/node_modules/postcss/lib/list.js:15:35)
    at comma (/Users/xxxx/node_modules/postcss/lib/list.js:56:21)
    at uniq (/Users/xxxx/node_modules/cssnano/node_modules/postcss-minify-selectors/index.js:13:27)
    at optimiseAtRule (/Users/xxxx/node_modules/cssnano/node_modules/postcss-minify-selectors/index.js:21:29)
    at /Users/xxxx/node_modules/postcss/lib/container.js:152:34
    at /Users/xxxx/node_modules/postcss/lib/container.js:102:26
    at Root.each (/Users/xxxx/node_modules/postcss/lib/container.js:89:22)
    at Root.eachInside (/Users/xxxx/node_modules/postcss/lib/container.js:101:21)
    at Root.eachAtRule (/Users/xxxx/node_modules/postcss/lib/container.js:150:25)
    at /Users/xxxx/node_modules/cssnano/node_modules/postcss-minify-selectors/index.js:108:13

csstools/postcss-font-magician#3

There should be a way to disable “safe” optimizations too

While some of optimizations could be safe indeed, there always could be errors and bugs that would make them unsafe. In those cases there should be a way to disable those safe optimizations to prevent the code from breaking while still using cssnano.

Unable to parse color

Hello!
I have index.css:

body {
    background: hsla(210.0, 6.0%, 0%, 1.0);
}
$ cssnano index.css
/usr/local/lib/node_modules/cssnano/node_modules/postcss/lib/lazy-result.js:194
            throw error;
                  ^
Error: Unable to parse color from string "hsla(210.0, 6.0%, 0%, 1.0)"
    at Object.Color (/usr/local/lib/node_modules/cssnano/node_modules/postcss-colormin/node_modules/color/index.js:31:15)
    at Color (/usr/local/lib/node_modules/cssnano/node_modules/postcss-colormin/node_modules/color/index.js:7:41)
    at colormin (/usr/local/lib/node_modules/cssnano/node_modules/postcss-colormin/node_modules/colormin/index.js:20:17)
    at Array.map (native)
    at /usr/local/lib/node_modules/cssnano/node_modules/postcss-colormin/index.js:12:34
    at Array.map (native)
    at eachVal (/usr/local/lib/node_modules/cssnano/node_modules/postcss-colormin/index.js:11:31)
    at /usr/local/lib/node_modules/cssnano/node_modules/postcss-colormin/index.js:19:26
    at /usr/local/lib/node_modules/cssnano/node_modules/postcss/lib/container.js:126:34
    at /usr/local/lib/node_modules/cssnano/node_modules/postcss/lib/container.js:104:26

postcss-merge-rules can be unsafe in certain conditions

Merging rules with common declarations can be unsafe when the selectors have different browser support:

a{color:blue}b:nth-child(2){color:blue}

becomes

a,b:nth-child(2){color:blue}

While the support for those selectors is different, so if you'd merge them, IE8 won't render anything, while in the non-optimized case it would render the first rule.

Module build failed: TypeError: Cannot read property 'replace' of undefined

Error is

at /home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/cssnext/node_modules/cssnano/lib/core.js:54:52
        at /home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/postcss-loader/node_modules/postcss/lib/container.js:119:34
        at /home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/postcss-loader/node_modules/postcss/lib/container.js:104:26
        at Rule.each (/home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/postcss-loader/node_modules/postcss/lib/container.js:91:22)
        at Rule.eachInside (/home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/postcss-loader/node_modules/postcss/lib/container.js:103:21)
        at /home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/postcss-loader/node_modules/postcss/lib/container.js:107:32
        at Root.each (/home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/postcss-loader/node_modules/postcss/lib/container.js:91:22)
        at Root.eachInside (/home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/postcss-loader/node_modules/postcss/lib/container.js:103:21)
        at Root.eachDecl (/home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/postcss-loader/node_modules/postcss/lib/container.js:117:25)
        at /home/allecs/Workspace/WebDesign/github.repos/react-isomorphic/node_modules/cssnext/node_modules/cssnano/lib/core.js:20:13

Css:

/* custom properties */
:root {
--fontSize: 1rem;
--mainColor: #12345678;
--highlightColor: hwb(190, 45%, 40%);
}

.root {

  border: 1px solid red;
  padding: 10px 10px;
  margin:  10px 10px;
  font-size: var(--fontSize);
  line-height: calc(var(--fontSize) * 1.5);
  color: var(--highlightColor);
  text-align: center;
  margin-left: auto;
  margin-right: auto;
  width: 50%;

}
/* TEST SECTION FOR POSTCSS */
/* CSSNEXT */
@custom-selector --heading h1, h2, h3, h4, h5, h6;
--heading { margin-top: 0 }

:fullscreen a {
    transition: transform 1s;
}

/* POSTCSS-MIXINS */
@define-mixin icon $network, $color: blue {
    .icon.is-$(network) {
        color: $color;
        @mixin-content;
    }
    .icon.is-$(network):hover {
        color: white;
        background: $color;
    }
}

@mixin icon twitter {
    background: yellow;
}
@mixin icon youtube, red {
    background: grey;
}

/* POSTCSS-NESTED */
.phone {
    &_title {
        width: 500px;
        @media (width<=500px) {
            width: auto;
        }
        body.is_dark & {
            color: white;
        }
    }
    img {
        display: block;
    }
}

/* POSTCSS-SIMPLE-VARS */
$blue: #056ef0;
$column: 200px;

.menu {
    width: calc(4 * $column);
}
.menu_link {
    background: $blue;
    width: $column;
}

/* POSTCSS-IMPORT */
@import "../style_constants/colors.css";
.barz {color: $bluen;}

/* POSTCSS-CONDITIONALS */
.foo {
  @if 3 < 5 {
    background: green;
  }
  @else {
    background: blue;
  }
}

/* POSTCSS-GRID */
.element {
  grid-column: 1/12 !last;
}
.push {
  grid-push: 1/12;
}
.pull {
  grid-pull: 1/12;
}
.element1 {
  width: grid-width(1/12);
  margin-left: grid-gutter(12);
}

/* POSTCSS-NEAT */

Build it with webpack postcss.

postcss: [
            postcssMixins, 
            postcssNested, 
            postcssConditionals, 
            postcssImport,
            postcssSimpleVars, 
            cssnext({compress:true}), 
            postcssGrid
  ],

Default webpack plugin webpack.optimize compresses it well.
Help please

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.