Skip to content

Less Language Operations

SomMeri edited this page Oct 16, 2012 · 11 revisions

Operations

Less language supports four arithmetical operations plus '+', minus '-', multiplication '*', division '/' and parentheses '(' ')'. Operations are evaluated in usual order:

  • parentheses are evaluated first,
  • multiplication/division takes precedence over addition and subtraction,
  • non commutative operations are evaluated from left to right.

Only operations on numbers and colors are supported. Operations on strings, identifiers or anything else are not.

Units

Numbers in CSS can have specified units: 21px 14cm 4.56%. Less does not convert between different units, it takes numbers as they are. The result of mathematical operation is assigned leftmost explicitly stated unit type.

Example:

  • Input: property: 2 + 5px - 3cm
  • Output: property: 4px

Example:

  • Input: property: (2 + 5px) - 3%
  • Output: property: 4px

Colors

Colors are split into their red, green and blue dimensions and the operation is applied to each dimension separately. E.g., if the user added two colors, then the green dimension of the result is equal to sum of green dimensions of input colors. The same goes for red and blue dimensions.

Example:

  • Input: color: #112233 + #010203;
  • Output: color: #122436;

An operation on two colors always produces valid color. If some dimension of the result ends up being bigger than 'ff' or smaller than '00', the dimension is rounded to either 'ff' or '00'.

Example:

  • Input1: color: #fe01fe + #040404;;
  • Output1: color: #ff05ff;
  • Input2: color: #01fe01 - #040404;
  • Output2: color: #00fa00;

An operation between color and number results in color too. Similarly to the previous case, the number is applied to each dimension separately. Operation between colors and numbers have two limitations: it is impossible to subtract a color from the number and it is impossible to divide a number by a color.

Example:

  • Input: color: #112233 + 4;
  • Output: color: #152637;

Incorrect Less:

  • Input: color: 4 - #112233;
  • Output: color: 4 / #112233;

Example:

  • Input: color: #112233 + 4;
  • Output: color: #152637;

Operations on colors split the color into TODO

Empty Separator and Whitespaces

Less language allows spaces inside mathematical expressions and those spaces are considered insignificant: this 10 - 5 is equivalent to 10-5.

This is very reasonable feature, but it has an unfortunate conflict with CSS separators. CSS allows spaces as separators - this is called an empty separator. For example, following declaration uses an empty separator: declaration: 10 23;. CSS allows also negative numbers as parameters and valid declaration can contain two negative numbers separated by an empty separator 10 -5.

The result is an ambiguity: a space can either represent a separator or can be just an unimportant part of the expression. Less4j solves this ambiguity in following way: a space before minus '-' represents an empty separator only if:

  • does not follow arithmetical operator 10+<not a separtor>-5,
  • is followed by minus '-',
  • that minus is not followed by another space.

Note: there is slight subtle difference between less4j and less.js handling of the space around unary minus. This difference will be dealt with in the future, see: TODO link the associated issue


selector {
  declaration: 10 - -5;//not an unary operator - compiles into "declaration: 15"
  declaration: 10 - 5;//space after '-' - compiles into "declaration: 5"
  declaration: 10- 5;//space after '-' - compiles into "declaration: 5"
  declaration: 10-5;//no space anywhere - compiles into "declaration: 5"
  declaration: 10 -5;//element space operator element no - it is an empty separator and compiles into "declaration: 10 -5"
}

Important: the same rules apply for expressions in parentheses. This may lead to unintuitive results and compile errors. The example of unintuitive result is the something: (12 (13 + 10 -23)) declaration. The space before '-' is interpreted as a separator and the expression compiles into a list of three numbers something: 12 23 -23.

Compile errors happen when user tries to perform an operation over a parentheses with a list. For example, ((13 -23) + 12) is parsed as "the list of two numbers (13 -23) plus 12". This causes compilation errors, because arithmetic operators can act only on numbers.

The above expression can be fixed either by

  • adding a space between '-' and 23 e.g., ((13 - 23) + 12),
  • removing space before '-' e.g., ((13-23) + 12).

It is possible that less.js will change this behavior in the future. Related issue and discussion on the topic: https://github.com/cloudhead/less.js/issues/952 . However, even if it changes, the space as a separator vs meaningless space ambiguity will remain in top-level expressions (those without parentheses).

Ignored In

As the font property can contain a ratio font: 12pt/14pt sans-serif, math expressions following the font property are not evaluated. Note: less4j implementation may remove some whitespaces from the font declarations. If it turns out to be a problem, we will fix it.

The same holds for aspect-ratio and device-aspect-ratio media features. As they can contain ratio, ratio expressions in them are ignored.

List of all properties and media features with ignored expressions:

  • font,
  • aspect-ratio,
  • device-aspect-ratio,
  • min-aspect-ratio,
  • max-aspect-ratio,
  • min-device-aspect-ratio,
  • max-device-aspect-ratio.

The following input remains unchanged by the translation:

@media (max-aspect-ratio: 58/80) {
  property: 3em;
}
selector {
  font: 12px/16px Arial;
}