1867

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?

3
  • 10
    possible duplicate of Usa a Variable in a Mixin Commented Jul 31, 2013 at 22:36
  • 24
    @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. Commented Jul 18, 2016 at 16:05
  • @cimmanon Well, the other way around now, since this question got way more popular. Commented Feb 18, 2022 at 18:23

6 Answers 6

3472

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
Sign up to request clarification or add additional context in comments.

6 Comments

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
Many thanks! I was about to go the css route with calc(100% - var(--body_padding))
@leachim Sass interpolation is evaluated by the Sass compiler, not by the browser.
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
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.
|
145

To use $variables in calc() for any SCSS property:

HTML:

<div></div>

SCSS:

$a: 4em;

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

6 Comments

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.
This is definitely a clearer answer than the accepted. 'Interpolate:' meant nothing to me.
@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...
@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.
I was stuck on this for more than 1 hour.
|
60

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.

4 Comments

also an additional space after calc ist not allowed. calc (#{$a} + 7px) won't work out.
The person above used spaces correctly, so this doesn't really answer their question, but it answered mine. Thank you!
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
care, this does not work in IE and Edge HTML
7

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);
}

Comments

2

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/

Comments

-7

Try this:

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

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

1 Comment

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.