csssvggruntjsgrunt-contrib-cssmin

Prevent cssMin from removing svg styles


When running the grunt.js task cssMin https://github.com/gruntjs/grunt-contrib-cssmin

Svg css properties are being removed.

For example:

.testClass {
   r: 4;
   width: 3px;
   margin-left: 18px !important;
}

Gets converted to

.testClass {
   width: 3px;
   margin-left: 18px !important;
}

How can I prevent this from happening?


Solution

  • grunt-contrib-cssmin uses clean-css internally, as stated in options, and any native (clean-css) options "are passed to clean-css".

    clean-css groups optimizations into levels, for convenience. There are two options controlling removal of rules, both found under level 2:

    restructureRules: false, // should disable all removals
    skipProperties: []       // specify individual rules to skip
    

    This should do it:

    cssmin: {
      options: {
        skipProperties: ['r']
      }
    }
    


    Starting with clean-css 4.2.0 a "comment" block method for skipping fragments entirely will be available:

    /* clean-css ignore:start */
    .testClass {
       r: 4;
       width: 3px;
       margin-left: 18px !important;
    }
    /* clean-css ignore:end */
    

    Note 4.2 has not been released yet.


    After a bit of testing, none of the above seems to actually work, although they "should", according to documentation.
    The only alternative I have is replacing grunt-contrib-cssmin with grunt-postcss cssnano (which is what I use with grunt for minification):

    npm install grunt-postcss cssnano
    
    grunt.initConfig({
      postcss: {
        processors: [
          require('cssnano')({
            // options here...
          })
        ]
      },
    });
    
    grunt.loadNpmTasks('grunt-postcss');
    grunt.registerTask('postcss', ["postcss"]);
    

    In practice, I use more postcss addons.
    Here's a practical example with autoprefixer, pixrem, postcss-flexbox and cssnano:

    module.exports = function(grunt) {
        grunt.initConfig({
            postcss: {
                options: {
                    processors: [
                        require('pixrem'),
                        require('autoprefixer')({browsers: ['> 0%']}),
                        require('postcss-flexboxfixer'),
                        require('cssnano')({
                          autoprefixer:false,
                          zindex: false
                        })
                    ]
                },
                jack: {
                    files: [{
                        expand:true,
                        flatten:true,
                        cwd: 'assets/',
                        src: ['scss/*.css', '!**/variables.css'],
                        dest:'assets/css/'
                    }]
                }
            },
            watch: {
                styles: {
                    files: [
                        'assets/scss/*.css'
                    ],
                    tasks:['postcss:jack']
                }
            }
        });
        grunt.loadNpmTasks('grunt-postcss');
        grunt.loadNpmTasks('grunt-contrib-watch');
        grunt.registerTask('default', ["watch:styles"]);
        grunt.registerTask('jack', ["postcss:jack"]);
    };
    

    I purposefully registered a task that only runs the postcss plugin:

    grunt jack
    

    Don't forget you need to install each addon for usage with postcss. For the above, you'd need:

    npm install grunt-postcss cssnano pixrem autoprefixer postcss-flexboxfixer
    

    ... and, most likely, you'll want to change files to match whatever you have.

    This time around, I tested. The r property makes it into the minified file:

    .testClass{r:20;width:3px;margin-left:18px!important}