Sass Control Directives — @if, @else, and Conditional Logic
In this tutorial, you will learn about Sass Control Directives. We cover key concepts, practical examples, and best practices to help you master this topic.
Sass control directives @if, @else if, and @else enable conditional style generation based on variable values, configuration flags, and data structure checks.
What You'll Learn
You will learn how to write conditional logic in Sass, chain conditions, combine with operators, and use conditions in mixins and functions.
Why It Matters
Conditionals enable flexible patterns. DodaTech uses @if in all responsive mixins to generate breakpoint-specific styles from a single source.
Real-World Use
Durga Antivirus Pro uses conditional logic in its theming system to generate different component styles based on the active theme variable.
flowchart LR
A[Placeholders] --> B[Control Directives]
B --> C[@if]
B --> D[@else if]
B --> E[@else]
B --> F[Operators]
style B fill:#c69,stroke:#c69,color:#fff
style C fill:#22c55e,stroke:#16a34a,color:#fff
Basic @if
$debug: true;
@if $debug {
body {
outline: 1px solid red;
}
}
Expected output: If $debug is true, the body gets a red outline. If false, no output.
@if @else if @else
$theme: "dark";
.card {
background: white;
@if $theme == "dark" {
background: #1e293b;
color: #e2e8f0;
} @else if $theme == "contrast" {
background: black;
color: white;
} @else {
background: white;
color: #1a202c;
}
}
Expected output: Different card styles depending on the theme variable value.
Comparison Operators
$columns: 3;
$gutter: 1rem;
.container {
@if $columns > 0 and $columns <= 12 {
display: grid;
grid-template-columns: repeat($columns, 1fr);
gap: $gutter;
} @else {
display: block;
}
}
$responsive: true;
$mobile: false;
@if $responsive and not $mobile {
.sidebar { width: 250px; }
}
Expected output: Operator-based conditional logic.
Truthiness and Falsiness
In Sass, only false and null are falsy. Everything else is truthy:
$enable-shadows: true;
$variant: "primary";
$count: 1;
$empty-list: ();
@if $enable-shadows {
.card { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); }
}
@if $variant {
.btn { background: #7c3aed; } // Always true — non-null string
}
@if $count {
.show { display: block; } // Always true — non-zero number
}
@if $empty-list {
.empty { display: block; } // Truthy (lists are truthy even when empty)
}
Expected output: Understanding truthy/falsy behavior prevents logic errors.
@if in Mixins
@mixin button-size($size: md) {
@if $size == sm {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
} @else if $size == md {
padding: 0.5rem 1rem;
font-size: 1rem;
} @else if $size == lg {
padding: 0.75rem 1.5rem;
font-size: 1.125rem;
} @else {
@error "Unknown size: #{$size}";
}
}
.btn-sm { @include button-size(sm); }
.btn-lg { @include button-size(lg); }
Expected output: Size-based button styling from a single mixin.
@if in Functions
@function contrast-color($bg) {
@if lightness($bg) > 50% {
@return #1a202c; // Dark text on light bg
} @else {
@return white; // Light text on dark bg
}
}
.card-dark {
background: #1e293b;
color: contrast-color(#1e293b); // white
}
.card-light {
background: #f8fafc;
color: contrast-color(#f8fafc); // #1a202c
}
Expected output: Functions returning different values based on input conditions.
Nested @if
@mixin themed($element, $theme: "light") {
@if $element == "button" {
@if $theme == "light" {
background: #7c3aed;
color: white;
} @else if $theme == "dark" {
background: #a78bfa;
color: black;
}
} @else if $element == "card" {
@if $theme == "light" {
background: white;
border: 1px solid #ddd;
} @else if $theme == "dark" {
background: #1e293b;
border: 1px solid #334155;
}
}
}
Expected output: Nested conditionals for multi-dimensional configuration.
Using @error and @warn
@mixin set-width($width) {
@if type-of($width) != number {
@error "set-width requires a number. Got #{type-of($width)}: #{$width}";
}
@if not unitless($width) and unit($width) != "px" and unit($width) != "%" {
@warn "set-width works best with px or % units. Got #{$width}";
}
width: $width;
}
Expected output: Clear error messages for invalid inputs, warnings for suboptimal inputs.
Common Mistakes
1. Using Single Equals Instead of ==
@if $var = "value" is assignment, not comparison. Use == for comparison.
2. Confusing and/or with && ||
Sass uses and, or, and not (not &&, ||, !).
3. Truthy String Assumptions
Non-empty strings are truthy. @if "false" is truthy because "false" is a non-empty string.
4. Missing @else for Edge Cases
Always include an @else or @else if to handle unexpected values. Use @error for invalid inputs.
5. Complex Nested Conditions
Deeply nested @if chains are hard to read. Consider separating into multiple mixins or functions.
Practice Questions
What operators does Sass use for logical AND, OR, NOT?
and,or,notare the Sass logical operators.What values are falsy in Sass? Only
falseandnullare falsy. Everything else (including0,"") is truthy.How do you raise an error in Sass?
@error "message";stops compilation with the error message.How do you check if a value is a number?
type-of($value) == numberchecks the data type.Can @if be used at the root level? Yes. @if works at the root, inside selectors, mixins, and functions.
Challenge
Create a responsive-font mixin that accepts a map of breakpoint-to-font-size pairs. Use @if, @else if, and @else to generate the correct media query for each breakpoint. Include an @error for unknown breakpoints.
FAQ
Mini Project
Build a theming system that accepts a $theme variable (light, dark, high-contrast). Use @if/@else if/@else to generate complete component styles for buttons, cards, alerts, and forms. Each theme should have different colors, borders, and shadows.
What's Next
Learn Sass Loops for generating repeated CSS with @each, @for, and @while. Then explore Sass Interpolation for dynamic selector names.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro