29

I have css statements like this:

margin-left: calc(50% - 480px);

Which work fine unminified but as soon as I begin minifying, the statement gets changed to:

margin-left: calc(50%- 480px);

Rendering all calc statements broken. Similar things happen with width, max-width, min-width, etc. Is there any way I can change the behavior of the bundle to leave those CSS properties alone?

Currently I'm just using bundles.Add(new Bundle()) to prevent minification entirely, but it would be nice if I could minify correctly.

RobVious
  • 12,685
  • 25
  • 99
  • 181
  • Have you set `` in `Web.config` or `BundleTable.EnableOptimizations = true;` in `BundleConfig.cs`? – John H Jan 02 '14 at 17:27
  • @JohnH - yes to the first, no to the second – RobVious Jan 02 '14 at 17:31
  • 1
    @RobVious `calc` works fine minified in mine. Try updating to the latest Web Grease – LostInComputer Jan 29 '14 at 16:06
  • 1
    Since it's a css feature that's new and not implemented by all browsers why not put only this kind of css in separate file, name it like *.calc.css and add this exception to BundleCollection.IgnoreList property in BundleConfig.cs – riadh gomri Jan 29 '14 at 16:26
  • 4
    The calc feature is still in a Candidate Recomendation period. Therefore Microsoft did not include it in it's bundling. You can see this related post for more informations and recommendations : http://stackoverflow.com/questions/19361403/mvc4-bundling-minification-failed-because-of-css3-feature – Max Nad Jan 29 '14 at 17:41
  • This appears fixed in newer versions of MVC. Updated 4 to 5.2.7 and it is no longer happening. – Brian Apr 16 '19 at 20:20

7 Answers7

37

This is an issue of the optimizer.

To avoid the miniffier to remove the whitespaces, group the affected element with parenthesis. That workarrounds the issue.

margin-left: calc((50%) - 480px);
wOOdy...
  • 659
  • 13
  • 25
8

In addition to the answer above: if you use:

margin-left: calc((50%) + 480px);

You should rewrite it as:

margin-left: calc((50%) - -480px);

Since it didn't seem to fix (50%)+ for me.

Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
kows
  • 121
  • 1
  • 7
3

If the default css minification is not doing what you need, you can always use a third party one.

bundling allows you to use your own transformations using IBundleTransform

var bundle = new Bundle("~/Content/css", myCustomCssTransform);

there are many different bundlers - nuget

for example you could use YUI compressor:

    using System.IO;
using System.Web.Optimization;
using Yahoo.Yui.Compressor;

namespace Bundler.Utilities
{
 public enum contentType
 {
  javascript,
  css
 }

 public class YUITransform : IBundleTransform
 {

  readonly string _contentType = string.Empty;

  public YUITransform(contentType contentType)
  {
   if (contentType == contentType.css)
   {
    this._contentType = "text/css";
   }
   else
   {
    this._contentType = "text/javascript";
   }
  }

  public void Process(BundleContext context, BundleResponse bundle)
  {
   bundle.ContentType = this._contentType;

   string content = string.Empty;


   foreach (FileInfo file in bundle.Files)
   {

    using (StreamReader fileReader = new
StreamReader(file.FullName)) {
     content += fileReader.ReadToEnd();
     fileReader.Close();
    }

   }

   bundle.Content = Compress(content);
  }

  string Compress(string content) {

   if (_contentType == "text/javascript")
   {
     return JavaScriptCompressor.Compress(content);
   }
   else
   {
    return CssCompressor.Compress(content,
                           CssCompressionType.StockYuiCompressor
);
   }
  }
 }
}
herostwist
  • 3,778
  • 1
  • 26
  • 34
1

This is totally normal as referring to CSS Values and Units Module it states

The following features are at-risk and may be dropped during the CR period: ‘calc()’, ‘toggle()’, ‘attr()’."

If you could skip the spaces there, that wouldn't be a complete minifying. An option is replacing spaces with unicode caracter \00A0

Kuzgun
  • 4,649
  • 4
  • 34
  • 48
1

No idea why but calc((50%) - 480px) didnt work for me, however the following worked:

subtraction:

margin-left: calc(((100%) - (480px)))

addition:

margin-left: calc((100%) - -480px)
mrplatina
  • 239
  • 4
  • 7
1

Beware of using variables in calc. You can end up with another CssMinify() bug:

@myVariable: 0em;
margin-left: calc((50%) - @myVariable);

is compressed and unit is cut off:

margin-left: calc((50%) - 0);

and it is not valid calc() call too!

lukyer
  • 7,595
  • 3
  • 37
  • 31
0

It seems the issue has been fixed in the version 2.4.9 of YUI Compressor, which can be accessed from here https://mvnrepository.com/artifact/com.yahoo.platform.yui/yuicompressor?repo=bsi-business-systems-integration-ag-scout. I have used this css file:

body{
    font-size: calc(50% - 3px);
    font-size: calc(50% + 3px);
    font-size: calc(50% + +3px);
    font-size: calc((50%) + (3px));
    font-size: calc(50% + (+3px));
    font-size: calc(50% + (3px));
    font-size: calc(50% - (-3px));
    font-size: calc(50% - -3px);
}

and running this command:

java -jar yuicompressor-2.4.9-BSI-2.jar --line-break 0 -o process.css.min.gz file.css

generates this output, which looks good:

body{font-size:calc(50% - 3px);font-size:calc(50% + 3px);font-size:calc(50% + +3px);font-size:calc((50%)+(3px));font-size:calc(50% + (+3px));font-size:calc(50% + (3px));font-size:calc(50% - (-3px));font-size:calc(50% - -3px)}
Fran García
  • 2,011
  • 16
  • 24