🏠 Home / Hub

💅 SCSS Lesson 07 — Control Flow

← Back to SCSS Menu  |  🏠 Hub

1. @if / @else if / @else

// @if — conditional CSS generation
@mixin theme-color($theme) {
  @if $theme == 'dark' {
    background: #1a1a1a;
    color: #ffffff;
  } @else if $theme == 'light' {
    background: #ffffff;
    color: #333333;
  } @else if $theme == 'ocean' {
    background: #0a2a4a;
    color: #7eb8f7;
  } @else {
    @error "Unknown theme: #{$theme}";  // compile error
  }
}

.card-dark   { @include theme-color('dark'); }
.card-light  { @include theme-color('light'); }
.card-ocean  { @include theme-color('ocean'); }

// @if with operators
@mixin responsive-font($size) {
  font-size: $size;
  @if $size > 24px {
    line-height: 1.3;
    font-weight: bold;
  } @else if $size > 16px {
    line-height: 1.5;
  } @else {
    line-height: 1.7;
  }
}

// @if with type checking (sass:meta)
@use 'sass:meta';

@mixin safe-border($color) {
  @if meta.type-of($color) != color {
    @warn "Expected a color, got #{meta.type-of($color)}";
    border: 1px solid gray;
  } @else {
    border: 1px solid $color;
  }
}

2. @each — Loop Over Lists & Maps

// @each over list
$colors: red, green, blue, yellow, purple;

@each $color in $colors {
  .bg-#{$color} {
    background-color: $color;
    color: white;
  }
}
// Compiles to: .bg-red { background-color: red; color: white; } ...

// @each over map
$spacing: (
  'xs': 4px,
  'sm': 8px,
  'md': 16px,
  'lg': 24px,
  'xl': 32px,
  '2xl': 48px,
);

@each $name, $value in $spacing {
  .p-#{$name}  { padding: $value; }
  .pt-#{$name} { padding-top: $value; }
  .pb-#{$name} { padding-bottom: $value; }
  .px-#{$name} { padding-left: $value; padding-right: $value; }
  .py-#{$name} { padding-top: $value; padding-bottom: $value; }
  .m-#{$name}  { margin: $value; }
  .mt-#{$name} { margin-top: $value; }
  .mb-#{$name} { margin-bottom: $value; }
}

// @each with multiple values per item
$breakpoints: (
  ('sm', 576px),
  ('md', 768px),
  ('lg', 992px),
  ('xl', 1200px),
);

@each $name, $width in $breakpoints {
  .container-#{$name} {
    max-width: $width;
    margin: 0 auto;
    padding: 0 16px;
  }
}

3. @for — Numbered Loops

// @for from/through (inclusive end)
@for $i from 1 through 12 {
  .col-#{$i} {
    width: percentage($i / 12);
    float: left;
    padding: 0 8px;
  }
}
// .col-1 { width: 8.333%; }  .col-6 { width: 50%; }  .col-12 { width: 100%; }

// @for from/to (exclusive end — stops before 12)
@for $i from 1 to 6 {
  .order-#{$i} { order: $i; }
}

// Generate font sizes
$base-size: 16px;
@for $i from 1 through 6 {
  h#{$i} {
    font-size: $base-size * (2.5 - ($i * 0.25));
    line-height: 1.2;
    font-weight: bold;
    margin: 0 0 0.5em;
  }
}
// h1: 40px, h2: 36px, h3: 32px ...

// Generate opacity utilities
@for $i from 1 through 10 {
  .opacity-#{$i * 10} {
    opacity: $i * 0.1;
  }
}

// Generate z-index utilities
$z-levels: (10, 20, 30, 40, 50);
@each $z in $z-levels {
  .z-#{$z} { z-index: $z; }
}

4. @while — Conditional Loop

// @while (less common — prefer @for when you know count)
$i: 1;
$max: 8;

@while $i <= $max {
  .scale-#{$i} {
    transform: scale($i * 0.125);  // 0.125, 0.25, ... 1.0
  }
  $i: $i + 1;
}

// Golden ratio typography scale
$base: 16px;
$ratio: 1.618;
$steps: 6;
$current: $base;
$step: 1;

@while $step <= $steps {
  .text-#{$step} {
    font-size: $current;
  }
  $current: $current * $ratio;
  $step: $step + 1;
}
// .text-1: 16px, .text-2: 25.89px, .text-3: 41.88px ...

5. Built-in Sass Modules

@use 'sass:math';
@use 'sass:color';
@use 'sass:string';
@use 'sass:list';
@use 'sass:map';
@use 'sass:meta';

// sass:math
$pi: math.pi();                // 3.14159...
$sqrt2: math.sqrt(2);          // 1.41421...
$rem: math.div(16px, 1px);    // 16 (use math.div, not /)

@function rem($px) {
  @return math.div($px, 16px) * 1rem;
}

.box { padding: rem(24px); }  // 1.5rem

// sass:color
$primary: #3178c6;
$light:   color.adjust($primary, $lightness: 20%);   // lighter
$dark:    color.adjust($primary, $lightness: -20%);  // darker
$alpha:   color.adjust($primary, $alpha: -0.5);      // 50% transparent
$shifted: color.adjust($primary, $hue: 30deg);       // hue shift

// sass:map
$config: ('size': 16px, 'weight': bold, 'family': sans-serif);
map.get($config, 'size');    // 16px
map.has-key($config, 'color'); // false
map.keys($config);           // ('size', 'weight', 'family')

// sass:list
$list: (1, 2, 3, 4, 5);
list.length($list);          // 5
list.nth($list, 3);          // 3
list.join($list, (6, 7));    // (1, 2, 3, 4, 5, 6, 7)

🎉 SCSS Complete!

Variables → Nesting → Mixins → Functions → @extend → Partials → Control Flow

🏠 Hub 💅 SCSS Menu

← SCSS 06  |  🏠 Back to Hub

📌 Study Checklist