Carl Thomas
Carl Thomas

Reputation: 3823

Calculate just a value in less

In less I can create a function which will convert px into em and return just the value

@em($target, $context: 16px) {
  @return ($target / $context) * 1rem;
}

This way I can use the function like

.body {
  font-size: em(22px);
  padding: 0 em(10px);
}

which will output

.body {
  font-size: 1.375em;
  padding: 0 0.625em;
}

However in less, the only way I can see to do the same function, is to pass the selector into the function too

.em(@selector, @target, @context: 16px) {
  @{selector}: unit((@target / @context), em);
}

And it needs to be used in the following way

.body {
  .em(font-size: 22px);
}

Which will output

.body {
  font-size: 1.375em;
}

This way is fine if I have one selector and one value, but as in the Sass example above, if I need a padding with a 0 and a 0.675em, then I cannot use the Less function to do this.

Is there a way to return just a value from a function in Less just like Sass does, so I do not have to pass the selector into the function?

Upvotes: 3

Views: 4186

Answers (3)

gwildu
gwildu

Reputation: 3921

What you can do is define a variable inside the mixin and then after executing the mixin assign this variable to whatever you need it for as described here.

I did something similar to get rem values from px:

.px2rem(@px-value) {
  @px2rem-xs: unit((@px-value / @root-font-size-xs ), rem);
  @px2rem-sm: unit((@px-value / @root-font-size-sm ), rem);
  @px2rem-ms: unit((@px-value / @root-font-size-ms ), rem);
  @px2rem-md: unit((@px-value / @root-font-size-md ), rem);
  @px2rem-lg: unit((@px-value / @root-font-size-lg ), rem);
}

By executing the mixin:

.px2rem(10px);

The variables are set and can be used later on

.something{
  margin: @px2rem-xs;
  @media screen and (min-width: @screen-md-min) {
    margin: @px2rem-md;
  }
}

Upvotes: 0

seven-phases-max
seven-phases-max

Reputation: 11820

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).

Upvotes: 2

jdunham
jdunham

Reputation: 439

What I did in my own less files is create a mixin for the specific properties. The main reason was to enable a quick fix if browser support needed to extend to non-rem enabled browsers such as IE8.

I created a @base-font-size variable and set to 16 per my normalize css.

.font-size(@pixels) {
    @remValue: (@pixels / @base-font-size);
    @pxValue: (@pixels * 1);
    font-size: ~"@{pxValue}px";
    font-size: ~"@{remValue}rem";
}

p { .font-size(20); }

Upvotes: -1

Related Questions