Lesscss - Use Calculation and Return Value

LESSCSS - use calculation and return value

LESS has no way as of yet to create a true "function," so we cope with it.

First

You can just use the unit function, like so:

LESS

.someClass {  padding: unit(@basevalue, @unit); }
.someOtherClass { padding: unit(@basevalue*0.5, @unit); }

CSS

.someClass {
padding: 1em;
}
.someOtherClass {
padding: 0.5em;
}

Second

The mixins as functions is okay in some situations, but as you discovered, has the limitation of only setting the value once on the first call (and that is assuming a variable of the same name does not exist in that scope already).

LESS (first works right, second doesn't)

.returnUnit(@val:1) { 
@return: unit(@basevalue*@val, @unit);
}

.someThirdClass {
.returnUnit(0.4);
padding: @return;
}
.someOoopsClass {
.returnUnit(0.4);
padding: @return;
.returnUnit(0.3);
margin: @return;
}

CSS Output

.someThirdClass {
padding: 0.4em;
}
.someOoopsClass {
padding: 0.4em;
margin: 0.4em; /* Ooops! Not 0.3em! */
}

Third

Limitation of the Second idea can be avoided by a second wrapping, as it isolates the scope for each variable returned by .returnUnit(), like so:

LESS

.someAccurateClass { 
& {
.returnUnit(0.4);
padding: @return;
}
& {
.returnUnit(0.3);
margin: @return;
}
}

CSS Output

.someAccurateClass {
padding: 0.4em;
margin: 0.3em; /* Yes! */
}

Fourth

It may be better to merge ideas from the First and Third by adding some global variables and doing this:

LESS

@unit:em;
@basevalue:1;
@val: 1;
@setUnit: unit(@basevalue*@val, @unit);

.someAwesomeClass {
& {
@val: .2;
padding: @setUnit;
}
& {
@val: .1;
margin: @setUnit;
}
}

CSS Output

.someAwesomeClass {
padding: 0.2em;
margin: 0.1em;
}

So here we are using the unit function still as the First idea, but have assigned it to the variable @setUnit, so each time the variable is called, it runs the function. We still isolate our property blocks using the & {} syntax like in the Third solution, but now we just set the @val to what we want and call the @setUnit where we want.

Calculate just a value in less

In short, no, you can't define "true" functions in Less. So for the particular use-case the most compact approach is something like this:

@context: 16px;
@u: 1em / @context;

.body {
font-size: 22 * @u;
padding: 0 10 * @u;
}

Or this:

@context: 16px;
@u: 1em / @context;

.body {
font-size: @u * 22px;
padding: 0 @u * 10px;
}

whichever you find more readable (note that arithmetic expressions require parens if you use --strict-math=on option).

LESSCSS: Assign a value to a property taken from another one's

This is possible starting with v3 of LESS! Here is the documentation on it.

The example use case they provide ends up with the background-color getting the same value as the color property when compiled:

.widget {
color: #efefef;
background-color: $color;
}

Less CSS - How to return value in viewport with (vw)

The best way to achieve the expected output would be to multiply the value by 100vw. This would be the most meaningful and easily understandable method.

a{
width: 700/1400 * 100vw;
}

The below method of using unit() function works too but I wouldn't really recommend it.

One of the primary reasons why I wouldn't recommend it is because I am not sure if that is supposed to work as it does. The unit() function is supposed to take a number as its first parameter and add the units to it but a percentage value is not exactly a number and this may not work in future versions depending on how the Less core team view it.

I read the docs and it seems like the first parameter can be a number with or without a dimension but I still wouldn't recommend it because the earlier method is far more easier to understand than the usage of functions.

b{
width: unit(percentage(700/1400), vw);
}

How to get value in percentage (%) or pixel (px) after doing some maths? | Lesscss

use:

unit(@yourvalue,px)

or

unit(@yourvalue,~"%")

read more here

Additional note:
by default the first occurring unit in the calculation will be assigned to the result. For example unit((1 / 2 * 3),px); and (1px / 2% * 3rem) will both return 1.5px.

Is there a way to use variables in Less for the ~ operator, like ~calc(100% - @spacing);

To disable the calculation which LESS does automatically when discovering a - between two numeric values but still being able to use variables, you can write one of the following:

1) Only escape the operator that triggers the calculation and use the variable like you normally do

@padding: 20px;
body {
padding: calc(100% ~"-" @padding);
}

2) Escape the whole expression and interpolate the variable with the @{padding} notation

@padding: 20px;
body {
padding: ~"calc(100% - @{padding})";
}

I prefer the second version, since it resembles javascript's template literals and looks a bit cleaner, but either way works just fine.

Both solutions disable the automatic Less calculation and compile to the correct result:

body {
padding: calc(100% - 20px);
}

How to calculate percentages in LESS CSS?

According to the LESS CSS website, you need to change the order of your equation

The output is pretty much what you expect—LESS understands the difference between colors and units. If a unit is used in an operation, like in:

@var: 1px + 5;

LESS will use that unit for the final output—6px in this case.

It should be:

width: 100%*(140/620);

Can numbers be rounded (math term) using LESS CSS?

Yes they can:

line-height: ceil(@height * .666);      // 20px (round up)
line-height: floor(@height * .666); // 19px (round down)
line-height: round(@height * .666); // 20px (round to closest integer)
line-height: round(@height * .666, 1); // 20.0px (round to 1 decimal place)

LESS CSS Functions: Utilize Different Values

You could use the & selector and just put it there twice. This pulls the mixins into 2 different scopes and keeps them from conflicting with one another. It's a bit hacky and not the cleanest looking thing but it does work, like so:

div {
&{
.emSpacing(16);
margin-top: @emSpacing;
}
&{
.emSpacing(32);
margin-bottom: @emSpacing;
}
}

This allows you to use the mixin twice with 2 different values using the same as the parent's selector. You'd then group all the properties you want to use that value into the same block.

You could clean up the look of single line uses a bit by doing something like:

div {
&{.emSpacing(16); margin-top: @emSpacing;}
&{.emSpacing(32); margin-bottom: @emSpacing;}
}

Still don't think it's super clean though it doesn't seem there's an alternative.

Edit

Looks like there's a plugin that would give you the format you want.

Less Plugin Functions

Instructions on use are in the readme.



Related Topics



Leave a reply



Submit