Question

Using Sass Variables Inside CSS calc()

csssasscss-calc

Question

I am trying to use the CSS calc() function in a Sass stylesheet, but the Sass variable is not being replaced inside the calc() expression.

Here is the code:

$body_padding: 50px

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

If I write the value directly as 50px, the output is correct. But when I use the variable, Sass produces this CSS:

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

How can I make Sass replace the variable correctly inside the calc() function?

Short Answer

By the end of this page, you will understand why Sass sometimes leaves variables untouched inside calc(), how interpolation solves that problem, and how to write calc() expressions that compile correctly and stay valid CSS.

Concept

Sass variables are normally replaced during compilation. For example, if $spacing is 20px, Sass usually turns margin-top: $spacing into margin-top: 20px.

However, calc() is a special case because it is also a native CSS function. Sass sometimes treats parts of a calc() expression as plain CSS to preserve the browser's own calculation rules. When that happens, a Sass variable written directly inside the expression may not always be evaluated the way you expect.

The common solution is interpolation, written as #{...}. Interpolation tells Sass: “insert the final value here as text before generating the CSS.”

Example:

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

This compiles to:

height: calc(100% - 50px)

Why this matters:

  • calc() is widely used for layout calculations.
  • Sass variables help keep spacing and sizing consistent.
  • Combining them correctly makes stylesheets easier to maintain.
  • If you misunderstand how Sass parses CSS functions, you can end up with broken output or confusing bugs.

In short: when Sass does not evaluate a variable inside calc(), use interpolation to explicitly inject the value.

Mental Model

Think of Sass as a template engine that fills in blanks before the browser sees the CSS.

  • A Sass variable is like a labeled sticky note: $body_padding = 50px
  • A normal property such as padding-top: $body_padding is easy for Sass to fill in.
  • But calc() is like a sealed formula box that the browser wants to evaluate later.
  • Sometimes Sass leaves the contents alone unless you explicitly open the box and place the value inside.

Interpolation #{...} is that explicit instruction.

So this:

calc(100% - #{$body_padding})

means:

“Before you output the CSS, take the value stored in $body_padding and paste it into this exact spot.”

Take Quiz

Syntax and Examples

Core syntax

Use interpolation when inserting a Sass variable into calc():

$body_padding: 50px

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

Compiled CSS:

body {
  height: calc(100% - 50px);
}

Another example

$sidebar-width: 250px;

.main {
  width: calc(100% - #{$sidebar-width});
}

Compiled CSS:

.main {
  width: calc(100% - 250px);
}

Why interpolation works

#{...} tells Sass to resolve the variable and insert its value directly into the final CSS string.

Example with multiple values

$header-height: 80px;
$footer-height: 40px;

.content {
  min-height: calc(100vh - #{$header-height} - #{$footer-height});
}

Compiled CSS:

.content {
  min-height: calc(100vh - 80px - 40px);
}

Beginner tip

If a Sass variable works in regular properties but not inside a CSS function such as calc(), interpolation is often the first thing to try.

Step by Step Execution

Consider this Sass code:

$body_padding: 50px

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

Here is what happens step by step:

  1. Sass reads the variable declaration:

    • $body_padding stores 50px
  2. Sass processes padding-top: $body_padding

    • This is a normal property value
    • Sass replaces $body_padding with 50px
  3. Sass processes height: calc(100% - #{$body_padding})

    • It sees interpolation: #{$body_padding}
    • It resolves the variable value to 50px
    • It inserts that text into the expression
  4. The final CSS becomes:

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

Small trace example

$gap: 16px;
.box {
  width: calc(100% - #{$gap});
}

Trace:

  • $gap = 16px
  • #{$gap} becomes 16px
  • Output: width: calc(100% - 16px)

Real World Use Cases

calc() with Sass variables is useful whenever part of a layout is fixed and part is flexible.

Common scenarios

  • Full-height content below a header

    $header-height: 64px;
    .page-content {
      min-height: calc(100vh - #{$header-height});
    }
    
  • Main area next to a fixed sidebar

    $sidebar-width: 280px;
    .main {
      width: calc(100% - #{$sidebar-width});
    }
    
  • Responsive cards with a shared gap

    $gap: 24px;
    .card {
      width: calc(50% - #{$gap});
    }
    
  • Viewport-based spacing with design tokens

    $toolbar-height: 56px;
    .panel {
      height: calc(100vh - #{$toolbar-height});
    }
    

These patterns appear in dashboards, admin panels, landing pages, mobile layouts, and component libraries.

Take Quiz

Real Codebase Usage

In real projects, developers usually combine Sass variables in calc() with reusable design values and layout patterns.

Common patterns

Design tokens

Teams often store spacing and size values in variables:

$nav-height: 72px;
$container-gap: 24px;

Then use them across components:

.layout {
  min-height: calc(100vh - #{$nav-height});
  padding: calc(#{$container-gap} / 2);
}

Configuration-driven layouts

A sidebar width or header height may be defined once and reused everywhere:

$sidebar-width: 260px;

.content {
  margin-left: $sidebar-width;
  width: calc(100% - #{$sidebar-width});
}

Guarding consistency

Using variables prevents magic numbers from being repeated:

  • Change one variable
  • Recompile Sass
  • Every related calc() updates automatically

Component-based styling

In large codebases, components may depend on shared layout dimensions:

$modal-header-height: 48px;

.modal-body {
  max-height: calc(80vh - #{$modal-header-height});
}

The main idea is maintainability: define dimensions once, then safely inject them into browser-side calculations.

Common Mistakes

1. Using a variable directly when interpolation is needed

Broken:

$body_padding: 50px
body
  height: calc(100% - $body_padding)

Possible output:

height: calc(100% - $body_padding);

Fixed:

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

2. Forgetting units

Broken:

$header-height: 50;
.main {
  height: calc(100vh - #{$header-height});
}

This becomes calc(100vh - 50), which is often invalid for layout sizing.

Fixed:

$header-height: 50px;

3. Mixing incompatible values

Broken idea:

$color: red;
.box {
  width: calc(100% - #{$color});
}

A color cannot be subtracted from a length.

4. Assuming Sass and CSS calculations are the same thing

Sass can do math at compile time, while calc() is evaluated by the browser at runtime.

Example:

$space: 20px;
.box {
  margin: $space * 2; // Sass math
  width: calc(100% - #{$space}); // CSS runtime math
}

5. Overusing interpolation everywhere

Interpolation is useful, but do not use it for ordinary variable replacement when it is not needed.

Less clear:

padding-top: #{$body_padding};

Clearer:

padding-top: $body_padding;

Use interpolation mainly where Sass parsing needs help, such as inside some CSS functions or combined strings.

Comparisons

Sass variable replacement vs interpolation

ApproachExampleWhen to use itResult
Normal variable usagepadding: $gap;Standard property valuesSass replaces the variable normally
Interpolationcalc(100% - #{$gap})When inserting a value into a CSS expression or string-like contextSass injects the resolved value

Sass math vs CSS calc()

FeatureSass mathCSS calc()
When it runsDuring compilationIn the browser
Example$double: 20px * 2;width: calc(100% - 40px);
Best forFixed calculations known in advanceMixing relative and absolute units like % and px
Can handle % - px directly?Not in the same way as the browser layout engineYes

Hard-coded values vs variables in calc()

ApproachExampleProsCons
Hard-codedcalc(100% - 50px)SimpleHarder to maintain
Sass variablecalc(100% - #{$body_padding})Reusable and consistentRequires understanding interpolation
Take Quiz

Cheat Sheet

Quick reference

Define a variable

$body_padding: 50px;

Use it normally

padding-top: $body_padding;

Use it inside calc()

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

Compiled output

height: calc(100% - 50px);

Rule of thumb

  • Use $variable for normal property values
  • Use #{$variable} when Sass needs explicit interpolation inside a CSS expression

Common pattern

$header-height: 64px;
$content-gap: 24px;

.main {
  min-height: calc(100vh - #{$header-height});
  width: calc(100% - #{$content-gap});
}

Watch out for

  • Missing units like 50 instead of 50px
  • Invalid value types like colors inside length calculations
  • Confusing Sass compile-time math with browser runtime math

Useful memory aid

If a variable works outside calc() but not inside it, try:

#{$variable}

FAQ

Why does Sass not replace my variable inside calc()?

Because calc() is a native CSS function, and Sass may preserve its contents instead of evaluating the variable directly. Interpolation tells Sass to insert the value explicitly.

What is the correct syntax for a Sass variable in calc()?

Use interpolation:

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

Can I use Sass math instead of calc()?

Sometimes, yes, if the whole calculation can be resolved at compile time. But if you are mixing values like % and px, calc() is usually necessary because the browser must compute it during layout.

Does this work in both .sass and .scss syntax?

Yes. The idea is the same. Only the file syntax differs.

Should I always use interpolation with Sass variables?

No. For normal properties, use the variable directly. Use interpolation when Sass needs help inserting the value into a CSS expression or string-like context.

Can I put multiple Sass variables in one calc()?

Yes.

height: calc(100vh - #{$header-height} - #{$footer-height});

Is calc() evaluated by Sass or by the browser?

calc() is a CSS function evaluated by the browser. Sass only prepares the final CSS text before it is sent to the browser.

Take Quiz

Mini Project

Description

Build a simple page layout with a fixed header and a content section that fills the remaining viewport height. This demonstrates a very common reason for combining Sass variables with CSS calc(): one part of the layout has a fixed size, while another must adapt dynamically.

Goal

Create a layout where the content area automatically subtracts the header height using a Sass variable inside calc().

Requirements

  • Define a Sass variable for the header height.
  • Apply that variable to the header height.
  • Make the main content height equal to the viewport height minus the header height.
  • Use the correct Sass syntax so the compiled CSS contains a valid calc() expression.
Take Quiz

Keep learning

Related questions

View more