Sass Variable in CSS calc() function

Asked 2023-09-21 08:10:16 View 975,931

I'm trying to use the calc() function in a Sass stylesheet, but I'm having some issues. Here's my code:

$body_padding: 50px

body
    padding-top: $body_padding
    height: calc(100% - $body_padding)

If I use the literal 50px instead of my body_padding variable, I get exactly what I want. However, when I switch to the variable, this is the output:

body {
    padding-top: 50px;
    height: calc(100% - $body_padding);
}

How can I get Sass to recognize that it needs to replace the variable within the calc function?

  • possible duplicate of Usa a Variable in a Mixin - anyone
  • @user3705055 You do need calc as Sass can't calculate 100% - 50px as the units are different. This can only be calculated by the browser, once it knows how big the container is in order to convert 100% to px before adding the values. This is the exact reason why calc exists. - anyone
  • @cimmanon Well, the other way around now, since this question got way more popular. - anyone

Answers

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

Answered   2023-09-21 08:10:16

  • box-sizing: border-box; would be the ideal way to go, in my opinion, of course. In general, the box sizing model should make t - anyone
  • Many thanks! I was about to go the css route with calc(100% - var(--body_padding)) - anyone
  • @leachim Sass interpolation is evaluated by the Sass compiler, not by the browser. - anyone
  • Even if it is OP's question, it’s almost always a bad idea to use interpolation with numbers. Interpolation returns unquoted strings that can’t be used for any further math, and it avoids Sass’s built-in safeguards to ensure that units are used correctly. This case should be better handled with sass' units - anyone
  • Note interpolation is no longer needed since sass 1.40.0 per changelog entry "Sass variables and functions can now be used in calc() expressions.". So you can simple use height: calc(100% - $body_padding). Using the interpolation in calc is now actually discouraged by sass documentation at sass-lang.com/documentation/values/calculations. - anyone

To use $variables inside your calc() of the height property:

HTML:

<div></div>

SCSS:

$a: 4em;

div {
  height: calc(#{$a} + 7px);
  background: #e53b2c;
}

Answered   2023-09-21 08:10:16

  • For some reason, I find this answer clearer. I don't do a lot of scss work, so this was "plainer" and easier for me to understand. - anyone
  • This is definitely a clearer answer than the accepted. 'Interpolate:' meant nothing to me. - anyone
  • @JacquesMathieu sass-lang.com/documentation/interpolation - If it doesn't mean anything to you and it's an answer with so many votes, probably you should understand what the fuss is about. Just my two cents... - anyone
  • @A. Chiesa sure, that defines interpolation. However the OP and I did not know of interpolation in SASS, otherwise this question would have never been asked. Thus just stating a word one may have never heard before without a definition or any pretense does not aid in creating an all inclusive answer. That link is certainly helpful though. Would have been nice to see that on the accepted answer. - anyone
  • I was stuck on this for more than 1 hour. - anyone

Even though its not directly related. But I found that the CALC code won't work if you do not put spaces properly.

So this did not work for me calc(#{$a}+7px)

But this worked calc(#{$a} + 7px)

Took me sometime to figure this out.

Answered   2023-09-21 08:10:16

  • also an additional space after calc ist not allowed. calc (#{$a} + 7px) won't work out. - anyone
  • The person above used spaces correctly, so this doesn't really answer their question, but it answered mine. Thank you! - anyone
  • Yes this worked for me. I tried height:calc(100%-95px); (i.e without proper space. ) at first and it didn't work. But with proper spacing it worked without interpolation - anyone
  • care, this does not work in IE and Edge HTML - anyone

I have tried this then i fixed my issue. It will calculate all media-breakpoint automatically by given rate (base-size/rate-size)


$base-size: 16;
$rate-size-xl: 24;

    // set default size for all cases;
    :root {
      --size: #{$base-size};
    }

    // if it's smaller then LG it will set size rate to 16/16;
    // example: if size set to 14px, it will be 14px * 16 / 16 = 14px
    @include media-breakpoint-down(lg) {
      :root {
        --size: #{$base-size};
      }
    }

    // if it is bigger then XL it will set size rate to 24/16;
    // example: if size set to 14px, it will be 14px * 24 / 16 = 21px
    @include media-breakpoint-up(xl) {
      :root {
        --size: #{$rate-size-xl};
      }
    }

@function size($px) {
   @return calc(#{$px} / $base-size * var(--size));
}

div {
  font-size: size(14px);
  width: size(150px);
}

Answered   2023-09-21 08:10:16

Here is a really simple solution using SASS/SCSS and a math formula style:

/* frame circle */
.container {
    position: relative;
    border-radius: 50%;
    background-color: white;
    overflow: hidden;
    width: 400px;
    height: 400px; }

/* circle sectors */
.menu-frame-sector {
    position: absolute;
    width: 50%;
    height: 50%;
    z-index: 10000;
    transform-origin: 100% 100%;
  }

$sector_count: 8;
$sector_width: 360deg / $sector_count;

.sec0 {
    transform: rotate(0 * $sector_width) skew($sector_width);
    background-color: red; }
.sec1 {
    transform: rotate(1 * $sector_width) skew($sector_width);
    background-color: blue; }
.sec2 {
    transform: rotate(2 * $sector_width) skew($sector_width);
    background-color: red; }
.sec3 {
    transform: rotate(3 * $sector_width) skew($sector_width);
    background-color: blue; }
.sec4 {
    transform: rotate(4 * $sector_width) skew($sector_width);
    background-color: red; }
.sec5 {
    transform: rotate(5 * $sector_width) skew($sector_width);
    background-color: blue; }
.sec6 {
    transform: rotate(6 * $sector_width) skew($sector_width);
    background-color: red; }
.sec7 {
    transform: rotate(7 * $sector_width) skew($sector_width);
    background-color: blue; }

To conclude, I strongly suggest you to understand transform-origin, rotate() and skew():

https://tympanus.net/codrops/2013/08/09/building-a-circular-navigation-with-css-transforms/

Answered   2023-09-21 08:10:16

Try this:

@mixin heightBox($body_padding){
   height: calc(100% - $body_padding);
}

body{
   @include heightBox(100% - 25%);
   box-sizing: border-box
   padding:10px;
}

Answered   2023-09-21 08:10:16

  • It won't work by the same reason as the code in the question. - anyone