343

The Less compilers that I'm using (OrangeBits and dotless 1.3.0.5) are aggressively translating

body { width: calc(100% - 250px - 1.5em); }

into

body { width: calc(-151.5%); }

Which is obviously not desired. I'm wondering if there is a way to signal to the Less compiler to essentially ignore the attribute during compilation. I've searched through the Less documentation and both compilers' documentation, and I could not find anything.

Does Less or a Less compiler support this?

If not, is there a CSS extender that does?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Nick Babcock
  • 5,842
  • 3
  • 24
  • 39

4 Answers4

543

Less no longer evaluates expression inside calc by default since v3.00.


Original answer (Less v1.x...2.x):

Do this:

body { width: calc(~"100% - 250px - 1.5em"); }

In Less 1.4.0 we will have a strictMaths option which requires all Less calculations to be within brackets, so the calc will work "out-of-the-box". This is an option since it is a major breaking change. Early betas of 1.4.0 had this option on by default. The release version has it off by default.

seven-phases-max
  • 11,491
  • 1
  • 41
  • 57
Luke Page
  • 7,968
  • 1
  • 18
  • 22
  • Brilliant! Thank you so much, I must have misinterpreted the "Escaping" portion of the documentation. – Nick Babcock Aug 15 '12 at 16:45
  • 2
    Note that if you're compiling less with twitter's recess it [ignores this escaping](https://github.com/twitter/recess/issues/59). At least at the time of writing this comment. – Attila Fulop Nov 13 '12 at 12:12
  • Awesome! That's just helped me out a lot. – samael May 30 '13 at 11:45
  • 1
    I just tried `calc(100% - 50px)` in less.css 1.4.0 and the result was `calc(50%)`. The awesome `~"..."` trick continues to work, but I am confused by the "out-of-the-box" statement, which makes me think the above would work. Luke, how does support for `calc` change in Less 1.4.0? Thanks! – Brian M. Hunt Jun 11 '13 at 13:30
  • I have updated the answer to be correct given changes in the release, thanks. – Luke Page Jun 25 '13 at 07:54
  • 2
    The question is why did less.js attempt to compute this in the first place? It should throw an error for "100% - 250px" as it can't compute a sensible answer. – mpen Aug 02 '13 at 18:33
  • **Update:** I see there's a `--strict-units` option which prevents these kinds of errors. Awesome! – mpen Aug 02 '13 at 19:28
  • Thanks for this answer. Saved me a lot of headache. – Sean Thompson Aug 27 '13 at 18:02
  • Does this still work? I'm when trying with `calc(~"100% + 20px");` the compiled css is `calc(120%);` note: I am using grunt to build the less and js files – b.kelley Nov 15 '13 at 17:35
  • 73
    For future readers, you can also escape just the operator, enabling you to use variables as well. Example: `calc(@somePercent ~"-" @someLength)` – 0b10011 Aug 07 '14 at 20:51
  • 10
    Instead of less miscalculating this or throwing an error why can it not realize what the user is trying to do and leave it alone? Obviously a percentage and a pixel value cannot be calculated together in less. – dfmiller Feb 09 '16 at 00:17
  • This issue made me go crazy, I actually forgot I am using less and I can't find out why my CSS is different in the browser and in the IDE. only after an hour or so I realized oh we're using LESS right maybe it got its own calc and then landed here. Thanks. – Vignesh Mar 08 '18 at 09:25
37

A very common usecase of calc is take 100% width and adding some margin around the element.

One can do so with:

@someMarginVariable = 15px;

margin: @someMarginVariable;
width: calc(~"100% - "@someMarginVariable*2);
width: -moz-calc(~"100% - "@someMarginVariable*2);
width: -webkit-calc(~"100% - "@someMarginVariable*2);
Sebastien Lorber
  • 79,294
  • 59
  • 260
  • 386
28

There is several escaping options with same result:

body { width: ~"calc(100% - 250px - 1.5em)"; }
body { width: calc(~"100% - 250px - 1.5em"); }
body { width: calc(100% ~"-" 250px ~"-" 1.5em); }
icl7126
  • 3,952
  • 3
  • 43
  • 43
9

There's a tidier way to include variables inside the escaped calc, as explained in this post: CSS3 calc() function doesn't work with Less #974

@variable: 2em;

body{ width: calc(~"100% - @{variable} * 2");}

By using the curly brackets you don't need to close and reopen the escaping quotes.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
brohr
  • 556
  • 6
  • 12