Sass @if Rule

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
Conditionals

What You’ll Learn

Sass @if decides whether a block of styles (or other Sass statements) runs at compile time. This page focuses on @if itself: syntax, truthiness, boolean operators, and five examples. @else and @else if are covered on a separate page.

01

Branch

@if

02

Truthy

What counts

03

Falsey

false & null

04

Booleans

and / or / not

05

Flags

Optional styles

06

Practice

5 examples

What Is @if?

Official docs: the @if rule is written @if <expression> { … } and controls whether or not its block gets evaluated (including emitting any styles as CSS). The expression usually returns true or false—if it returns true, the block is evaluated; if false, it is not.

  • Runs at compile time—browsers never see @if.
  • Skipped blocks emit no CSS for that branch.
  • Common inside mixins and functions.
  • Works with any truthy/falsey expression, not only booleans.
💡
Beginner tip

Think of @if as a compile-time switch: “only include these styles when this config/argument is on.”

📝 Syntax

styles.scss
@use "sass:math";

@mixin avatar($size, $circle: false) {
  width: $size;
  height: $size;

  @if $circle {
    border-radius: math.div($size, 2);
  }
}

When $circle is true, the border-radius block runs. When it is false, that block is skipped entirely.

✅ Truthiness and Falsiness

Official docs: anywhere true or false are allowed, you can use other values too.

  • Falsey — only false and null.
  • Truthy — every other value (including 0, "", and empty lists).
⚠️
Heads up

Some languages treat empty strings, empty lists, or 0 as falsey. Sass does not. Those values succeed in an @if condition.

Practical pattern: string.index($string, " ") returns null when the substring is missing (falsey) and a number when it is found (truthy)—so you can write @if string.index($text, " ") { … } without comparing to null.

⚖️ Boolean Operators With @if

Official docs: conditional expressions may contain boolean operators (and, or, not). See also Sass boolean operators.

styles.scss
@if $theme == dark and $density == compact { … }
@if $theme == light or $theme == dark { … }
@if not ($theme == light) { … }

📄 What About @else / @else if?

An @if can optionally be followed by @else when you need a two-way fallback, or by a chain of @else if branches for many outcomes. This page stays focused on single-branch @if—optional styles, flags, and truthiness.

💡
Scope of this page

Master single-branch @if first. Continue with the @else tutorial for exclusive alternatives (light/dark, primary/ghost). Multi-condition @else if chains get their own page.

⚡ Quick Reference

GoalCode
Optional block@if $circle { border-radius: …; }
Compare values@if $theme == dark { … }
Combine conditions@if $a and $b { … }
Negate@if not $flag { … }
Null means “missing”@if string.index($s, " ") { … }
Falsey valuesOnly false and null

Examples Gallery

Every example uses @if only (no @else chains). Open View Compiled CSS for verified output.

📚 Getting Started

Turn optional styles on or off with a condition.

Example 1 — Optional Mixin Styles

Official-style avatar: add a radius only when $circle is true.

styles.scss
@use "sass:math";

@mixin avatar($size, $circle: false) {
  width: $size;
  height: $size;

  @if $circle {
    border-radius: math.div($size, 2);
  }
}

.square-av {
  @include avatar(100px, $circle: false);
}

.circle-av {
  @include avatar(100px, $circle: true);
}

How It Works

Both avatars get width/height. Only the circle call evaluates the @if $circle block, so only it gets border-radius.

Example 2 — Feature Flags

Config variables gate whole rules or nested declarations.

styles.scss
$enable-shadows: true;
$is-rtl: false;

.card {
  padding: 1rem;

  @if $enable-shadows {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  }

  @if $is-rtl {
    margin-right: auto;
  }
}

@if $enable-shadows {
  .floating {
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
  }
}

How It Works

Shadows are on, so those blocks emit. $is-rtl is false, so no RTL margin appears in the CSS.

📈 Null Checks, Booleans & Truthiness

Use real Sass values as conditions—not only true/false.

Example 3 — null From string.index

Treat a missing substring as falsey without writing != null.

styles.scss
@use "sass:string";

@mixin spaced-label($text) {
  content: $text;

  @if string.index($text, " ") {
    letter-spacing: 0.04em;
  }
}

.one-word {
  &::before {
    @include spaced-label("Hello");
  }
}

.two-words {
  &::before {
    @include spaced-label("Hello World");
  }
}

How It Works

No space → string.index returns null (falsey). A space returns an index number (truthy), so letter-spacing is emitted.

Example 4 — and / or / not

Combine comparisons inside a single @if.

styles.scss
$theme: dark;
$density: compact;

.panel {
  padding: 1rem;

  @if $theme == dark and $density == compact {
    background: #111;
    color: #eee;
    padding: 0.5rem;
  }

  @if $theme == light or $theme == dark {
    border: 1px solid currentColor;
  }

  @if not ($theme == light) {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  }
}

How It Works

All three conditions pass for dark + compact, so each block contributes declarations (later padding overrides the earlier one).

Example 5 — Surprising Truthy Values

Empty strings, 0, and empty lists are truthy; false and null are not.

styles.scss
@mixin truth-demo($value, $label) {
  @if $value {
    --#{$label}: on;
  }
}

.checks {
  @include truth-demo("", "empty-string");
  @include truth-demo(0, "zero");
  @include truth-demo((), "empty-list");
  @include truth-demo(false, "false");
  @include truth-demo(null, "null");
}

How It Works

Only the three truthy calls emit custom properties. false and null skip their blocks completely.

🚀 Real-World Use Cases

  • Optional mixin knobs$circle, $border, $shadow.
  • Build flags — enable debug outlines or reduced-motion helpers.
  • Theme tokens — emit a block only for a matching theme name.
  • Null-as-missing — treat null returns as “skip this style.”
  • Guard clauses — pair with @error on a separate branch page when you need hard fails.

🧠 How Compilation Works

1

Evaluate the expression

Sass computes the condition (boolean, comparison, or other value).

Check
2

Decide truthiness

Only false and null fail the condition.

Truthy?
3

Run or skip the block

Truthy → evaluate styles; falsey → emit nothing from that block.

Branch
4

CSS ships

Only the styles from successful branches appear in the output.

⚠️ Common Pitfalls

  • Treating 0 or "" as false — they are truthy in Sass.
  • Expecting runtime CSS conditions@if cannot react to the browser.
  • Forgetting keyword argsavatar(100px, true) vs $circle: true for clarity.
  • Over-nesting flags — too many compile flags make stylesheets hard to reason about.
  • Confusing with CSS if() — CSS has its own evolving if(); Sass @if is compile-time only.

💡 Best Practices

✅ Do

  • Use @if for optional mixin styles and config flags
  • Rely on null as “missing” from helpers like string.index
  • Prefer clear comparisons: $theme == dark
  • Keep boolean flags named for intent ($enable-shadows)
  • Learn @else / @else if when you need alternate branches

❌ Don’t

  • Assume empty strings or 0 are falsey
  • Use @if for hover/media that must change in the browser
  • Hide critical required styles behind a default false flag
  • Write vague conditions without naming what you check
  • Stuff full if/else trees here—use the dedicated else page

Key Takeaways

Knowledge Unlocked

Five things to remember about Sass @if

Compile-time branches: truthy runs the block; falsey skips it.

5
Core concepts
02

Truthy

almost everything

Values
03

Falsey

false & null

Only
⚖️ 04

Combine

and / or / not

Logic
05

Compile

CSS only result

Output

❓ Frequently Asked Questions

It controls whether its block is evaluated (including emitting CSS). If the expression is truthy, the block runs; if it is falsey, the block is skipped.
Only false and null. Every other value is truthy—including 0, empty strings, and empty lists.
Yes. Conditional expressions may use boolean operators: @if $a and $b { … }, @if $a or $b { … }, @if not $a { … }.
No. @if is compile-time only. Browsers see only the styles from blocks that evaluated to true.
@if decides whether one block runs. @else provides the alternate branch when the @if condition fails. See the dedicated Sass @else Rule page for two-way branches; @else if chains are covered separately.
Inside mixins and functions for optional styles, feature flags, keyword checks, and any compile-time branch based on arguments or config variables.
Did you know?

Official Sass docs highlight that empty strings, empty lists, and the number 0 are all truthy—a common surprise for developers coming from JavaScript.

Conclusion

@if is Sass’s compile-time conditional: run a block when the expression is truthy, skip it when it is falsey. Remember that only false and null fail—then use flags and mixin knobs to keep CSS lean. When you need an exclusive alternate, continue with @else.

Continue with @else or boolean operators.

Next: Sass @else

Add a two-way fallback branch for themes, variants, and function returns.

@else rule →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful