How to Get a Negative Value of a CSS Variables in a Calc() Expression

How can I get a negative value of a CSS variables in a calc() expression?

Yes you can do it. Simply multiply by -1:

:root {

--margin: 50px;

}

body {

margin: 0 100px;

border:1px solid;

}

.box-1 {

background: red;

height: 100px;

width: 200px;

margin-left: calc(-1 * var(--margin));

}

.box-2 {

background: green;

height: 100px;

width: 200px;

margin-left: calc(-1 * (-1 * var(--margin))); /* You can also nest calculation */

}
<div class="box-1">

</div>

<div class="box-2">

</div>

Using negative CSS Custom Properties

As of this posting, March 2018, the only way to use negative custom properties is by multiplying it by -1 with the calc function.

// Vanilla CSS
.class {
margin-bottom: calc(var(--margin-md) * -1);
}

SCSS: Inverting/Negating Variable Based on calc()

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>

Is there a way to make CSS calc() never be a negative value?

Premising that there's no way to bound the values computed by calc() you could use a mediaquery when max-height is at most 650px

.my-margin-top {
margin-top: calc(50vh - 325px);
}

@media all and (max-height: 650px) {
.my-margin-top {
margin-top: 0;
}
}

or you might also revert the logic by wrapping the existing rule into a min-height mediaquery

@media all and (min-height: 650px) {
.my-margin-top {
margin-top: calc(50vh - 325px);
}
}

SCSS: Inverting/Negating Variable Based on calc()

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>

Sass Variable in CSS calc() function

Interpolate:

body
height: calc(100% - #{$body_padding})

For this case, border-box would also suffice:

body
box-sizing: border-box
height: 100%
padding-top: $body_padding

Make variable value negaitve

Reason for the code in question not working: (all emphasis within quoted text are mine)

right: calc(0-var(--skyve-bredde));

The above wouldn't work for two reasons and they are as follows:

  • As per CSS calc() syntax there must be a space before and after the + or - operator.

    In addition, white space is required on both sides of the + and - operators. (The * and / operaters can be used without white space around them.)

  • As per Type Checking for CSS calc, 0 is a <number> whereas the other value is <percentage>. For properties like width, left, right etc, the <percentage> takes the <length> type and so the below check would fail (as the values are not of the same type) and so the expression will be treated as invalid.

    At + or -, check that both sides have the same type, or that one side is a <number> and the other is an <integer>. If both sides are the same type, resolve to that type. If one side is a <number> and the other is an <integer>, resolve to <number>.

    If an operator does not pass the above checks, the expression is invalid.


Solutions:

  • As already mentioned in the above answer and the comment, calc(var(--skyve-bredde) * -1) will work and produce the expected output.
  • Or alternately using the same type on either side, like calc(0% - var(--skyve-bredde)) should also work.

:root {

--skyve-bredde: 50%;

}

div {

position: absolute;

right: calc(0% - var(--skyve-bredde));

background: red;

}
<div>Some text</div>

CSS Calc - always achieve '0' or '1'

Use min()

--new: min(var(--size)*var(--size)*1000,1)

If size = 0 then the result is 0. If bigger than 0 or smaller than 0, multiplied with a big value (and itself) it will get bigger than 1 and will get clamped to 1

.box {
--new: min(var(--size)*var(--size)*1000,1);

height:50px;
background:blue;
margin:5px;

border:calc(var(--new)*5px) solid red; /* either 5px here or 0 */
}
<div class="box" style="--size:2"></div>

<div class="box" style="--size:0"></div>

<div class="box" style="--size:200"></div>

<div class="box" style="--size:-200"></div>

<div class="box" style="--size:-.5"></div>

<div class="box" style="--size:.8"></div>


Related Topics



Leave a reply



Submit