Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SCSS: Inverting/Negating Variable Based on calc()

Tags:

css

sass

I am using SCSS and wanted to specify a variable at top that is based on a sum of a px and a rem value.

I understand that it is not possible to combine unit types in SCSS variables, so instead I use calc():

$navbar-top: calc(40px + 1 rem);

Further down in the style sheet, I wanted to include a negated version of $navbar-top.

I tried both these, with no success:

(-$navbar-top)
-#{$navbar-top}

Any idea how I can negate the SCSS variable, without having to declare a new variable, or writing calc again throughout the CSS.

Thanks.


EDIT

  • As noted in the comments below, this is not a duplicate of Sass negative variable value?
  • This question is about negating a variable set with calc(), which is unrelated to the above SO post. I have noted both solutions presented in that question, above. None of them work in this particular case.

EDIT 2: SCSS SOLUTION BASED ON TEMANI'S ANSWER BELOW

Declare the necessary variables at top, including a "negator" (-1):

$navbar-top: calc(40px + 1rem);
$neg: -1;

Then, the variable can be used throughout (negated or not), like this:

/* Non-negated */
margin: $navbar-top 0 0;

/* Negated */
margin: calc(#{$neg} * #{$navbar-top}) 0 0;

The negated version above will compile to the following CSS:

margin: calc(-1 * calc(40px + 1rem)) 0 0;
like image 575
Magnus Avatar asked May 20 '18 14:05

Magnus


2 Answers

Since calc is not a usual value you cannot simply append a - sign on it to obtain the negative value.

An idea would be to consider another parameter to control the sign. Here is an idea using pure CSS and CSS variable without the need of another calc()

.box {
  margin-top: calc( var(--s,1)*(40px + 1rem));
  height:100px;
  background:rgba(255,0,0,0.5);
}
<div class="box"></div>
<div class="box" style="--s:-1"></div>

You can define the negative value using class

.box {
  margin-top: calc( var(--s,1)*(40px + 1rem));
  height:100px;
  background:rgba(255,0,0,0.5);
}
.neg {
  --s:-1;
}
<div class="box"></div>
<div class="box neg"></div>

UPDATE

You may also consider the expression using variables:

:root {
  --exp:(40px + 1rem);
}

.box {
  margin-top: calc( var(--s,1)*var(--exp));
  height:100px;
  background:rgba(255,0,0,0.5);
}
<div class="box"></div>
<div class="box" style="--s:-1"></div>
like image 139
Temani Afif Avatar answered Oct 20 '22 12:10

Temani Afif


You can use an @function instead of a variable

DEMO

// The argument is defaulted to true,
// so you only need to pass an argument if you want a negative number
@function navbar-top($isPositive: true) {
    @if $isPositive { @return calc(40px + 1rem); }
    @else {@return calc((40px + 1rem) * -1); }
}

// Calling the function with the default value
.normal { margin-top: navbar-top(); }

// Calling the function with negative value
.negative { margin-top: navbar-top(false); }
like image 30
Ari Avatar answered Oct 20 '22 12:10

Ari