4

I have the following less code:

.@{namespace}users-row {
     height: calc(100% - (@search-row-height - @vh-antialiasing-number));
}

I have already tried:

.@{namespace}users-row {
     height: calc(100% - (@{search-row-height} - @{vh-antialiasing-number}));
}

but that throws errors during compilation.

Is there a way to make the inner parentheses evaluate to a single number, but not have LESS also evaluate the outer ones? I have StrictMath turned on for compilation, so that the outer ones are not evaluated. I would prefer to not row escape, due to how much it decreases the readability. This is ideally what I would like it to compile too:

.namespace-users-row {
     height: calc(100% - Xpx)
}

where X is the difference of the two variables (both have pixel values).

Tahsis Claus
  • 1,879
  • 1
  • 15
  • 27
  • possible duplicate of [Less Aggressive Compilation with CSS3 calc](http://stackoverflow.com/questions/11972084/less-aggressive-compilation-with-css3-calc) – TylerH Jan 28 '15 at 19:19
  • @TylerH I have already solved that user's question/problem by turning strict math on. The problem is lack of LESS interpretation (it ignores both operators), not too much of it (it evaluating both operators). I have edited my original question to more clearly state what the desired compiled CSS is. – Tahsis Claus Jan 28 '15 at 20:41
  • For `--strict-math=on` it's `height: calc(100% ~"-" (@search-row-height - @vh-antialiasing-number));`. Without `~"-"` the inner expression inherits options of the outer one so the whole statement is not evaluated. – seven-phases-max Jan 29 '15 at 10:00
  • @seven-phases-max That works. If you turn your comment into an answer, I'll mark it as correct. – Tahsis Claus Jan 29 '15 at 16:30
  • It's basically the same thing as Luca Detomi answered below (just a bit more readable). In both cases the trick is in hiding any arithmetic stuff of the outer expression (with ~"" around it is evaluated as a generic list value) so that the inner parens come into effect for `--strict-math=on`. – seven-phases-max Jan 29 '15 at 19:05
  • 1
    Oh and btw., I've just remembered also that *there's* canonicaly correct for this case syntax w/o `~""` hacks: `height:calc(100% - ((@search-row-height - @vh-antialiasing-number)));`. (Indeed: "only maths that is inside un-necessary parenthesis will be processed"). – seven-phases-max Jan 31 '15 at 00:59
  • @seven-phases-max This canonically correct version doesn't work anymore, see https://github.com/less/less.js/issues/3221 – Clément Aug 06 '23 at 09:00

2 Answers2

4

You must use "escape" function:

@namespace:namespace;
@search-row-height:100px;
@vh-antialiasing-number:30px;


.@{namespace}-users-row {
      height: calc(~"100% - " (@search-row-height - @vh-antialiasing-number));
}

UPDATE:

After @seven-phases-max's suggestion, you could also write rule limiting use of escape character ~ only to - symbol:

.@{namespace}-users-row {
      height:calc(100% ~"-" (@search-row-height - @vh-antialiasing-number));
}

Both of them will result in the following processed CSS:

.namespace-users-row {
  height: calc(100% - 70px);
}

P.S.: I set @namespace:namespace variable because I thought that you desired to have also selector name variable; for this particular purpose, variable name is equal to its value. If not necessary, obviously you can skip this declaration and remove { } writing directly .namespace-users-row

Luca Detomi
  • 5,564
  • 7
  • 52
  • 77
0

The behavior is (unfortunately) on purpose, according to the developers. The issue tracking it is here: https://github.com/less/less.js/issues/3221

The workaround offered in that thread is to use a Less function around the calculation; min works:

@search-row-height: 10px;
@vh-antialiasing-number: 5px;

a {
    height: calc(100% - min(@search-row-height - @vh-antialiasing-number));
}

Here's the output:

$ lessc test.less /dev/stdout
a {
  height: calc(100% - 5px);
}
Clément
  • 12,299
  • 15
  • 75
  • 115