Control Directives and Loops in Sass

Module 7: CSS Preprocessors & Frameworks - Advanced Sass

Introduction to Control Directives

Control directives are one of the most powerful features of Sass, bringing programming logic to your stylesheets. They allow you to make decisions, create repetitive structures, and iterate through collections—capabilities that simply don't exist in regular CSS.

Analogy: Control Directives as a Factory Assembly Line

Think of control directives as the decision-making systems in a factory assembly line. Conditionals (@if/@else) are like quality control checkpoints that direct products down different paths based on specific criteria. Loops (@for, @each, @while) are like automated machines that perform the same operation on a series of identical parts, but can adjust settings for each individual piece. Together, they transform your Sass from a static blueprint into a dynamic production system that can respond to different conditions and efficiently handle repetitive tasks.

The main control directives in Sass are:

flowchart TB A[Control Directives] --> B["@if/@else"] A --> C["@for"] A --> D["@each"] A --> E["@while"] B --> F["Conditional Logic"] C --> G["Numeric Iteration"] D --> H["Collection Iteration"] E --> I["Conditional Iteration"]

Conditional Directives: @if, @else if, and @else

The @if, @else if, and @else directives allow you to conditionally include CSS based on some condition. This is incredibly useful for creating flexible mixins, adaptive styles, and theme systems.

Basic Syntax

@mixin text-contrast($background) {
  @if (lightness($background) > 50%) {
    color: #000000; // Dark text for light backgrounds
  } @else {
    color: #ffffff; // Light text for dark backgrounds
  }
}

.button-primary {
  background-color: #007bff;
  @include text-contrast(#007bff);
}

.button-light {
  background-color: #e9ecef;
  @include text-contrast(#e9ecef);
}

Multiple Conditions with @else if

@mixin button-variant($color) {
  @if $color == 'primary' {
    background-color: #007bff;
    border-color: #007bff;
    color: white;
  } @else if $color == 'success' {
    background-color: #28a745;
    border-color: #28a745;
    color: white;
  } @else if $color == 'danger' {
    background-color: #dc3545;
    border-color: #dc3545;
    color: white;
  } @else {
    // Default/fallback styling
    background-color: #6c757d;
    border-color: #6c757d;
    color: white;
  }
}

.btn-primary {
  @include button-variant('primary');
}

.btn-success {
  @include button-variant('success');
}

.btn-danger {
  @include button-variant('danger');
}

.btn-default {
  @include button-variant('default');
}

Complex Conditions

Sass supports logical operators, allowing for complex conditions:

@mixin responsive-property($property, $value, $screen-size) {
  // Screen size presets
  $is-small: $screen-size == 'small' or $screen-size <= 576px;
  $is-medium: $screen-size == 'medium' or ($screen-size > 576px and $screen-size <= 992px);
  $is-large: $screen-size == 'large' or $screen-size > 992px;
  
  @if $is-small {
    #{$property}: $value * 0.8; // Smaller value for small screens
  } @else if $is-medium {
    #{$property}: $value; // Base value for medium screens
  } @else if $is-large {
    #{$property}: $value * 1.2; // Larger value for large screens
  } @else {
    // Fallback if no match
    #{$property}: $value;
  }
}

.hero-title {
  @include responsive-property('font-size', 2rem, 'small');
  
  @media (min-width: 576px) {
    @include responsive-property('font-size', 2rem, 'medium');
  }
  
  @media (min-width: 992px) {
    @include responsive-property('font-size', 2rem, 'large');
  }
}

Nesting Conditionals

You can nest conditional directives for more complex logic:

@mixin configure-card($variant, $is-dark-mode) {
  border-radius: 8px;
  
  @if $variant == 'elevated' {
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    
    @if $is-dark-mode {
      background-color: #2c2c2c;
      color: white;
    } @else {
      background-color: white;
      color: #333;
    }
  } @else if $variant == 'outlined' {
    border: 1px solid;
    
    @if $is-dark-mode {
      border-color: #666;
      background-color: transparent;
      color: #ddd;
    } @else {
      border-color: #ddd;
      background-color: transparent;
      color: #333;
    }
  }
}

// Light mode cards
.card-elevated {
  @include configure-card('elevated', false);
}

.card-outlined {
  @include configure-card('outlined', false);
}

// Dark mode theme
.dark-theme {
  .card-elevated {
    @include configure-card('elevated', true);
  }
  
  .card-outlined {
    @include configure-card('outlined', true);
  }
}

Conditional @content in Mixins

You can use conditionals to determine whether or not to include @content in a mixin:

@mixin when-dark-theme($enabled: true) {
  @if $enabled {
    @media (prefers-color-scheme: dark) {
      @content;
    }
  }
}

.button {
  background-color: #f0f0f0;
  color: #333;
  
  @include when-dark-theme {
    background-color: #333;
    color: #f0f0f0;
  }
}

The @for Loop

The @for directive allows you to generate repeated styles with variations. It iterates a counter variable over a range of values.

Basic @for Syntax

There are two forms of @for loops:

@for from ... through ...

Includes the final number

@for $i from 1 through 5 {
  .item-#{$i} {
    width: 20% * $i;
  }
}

/* Compiles to:
.item-1 { width: 20%; }
.item-2 { width: 40%; }
.item-3 { width: 60%; }
.item-4 { width: 80%; }
.item-5 { width: 100%; }
*/

@for from ... to ...

Excludes the final number

@for $i from 1 to 5 {
  .item-#{$i} {
    width: 20% * $i;
  }
}

/* Compiles to:
.item-1 { width: 20%; }
.item-2 { width: 40%; }
.item-3 { width: 60%; }
.item-4 { width: 80%; }
*/

Creating a Grid System

One common application of @for loops is creating a grid system:

$columns: 12;

// Generate column classes
@for $i from 1 through $columns {
  .col-#{$i} {
    width: percentage($i / $columns);
  }
}

// Generate offset classes
@for $i from 0 through ($columns - 1) {
  .offset-#{$i} {
    margin-left: percentage($i / $columns);
  }
}

Generating Utility Classes

@for loops are perfect for creating utility classes that follow a numerical pattern:

// Generate margin utilities
@for $i from 0 through 9 {
  .m-#{$i} {
    margin: $i * 0.25rem;
  }
  
  .mt-#{$i} {
    margin-top: $i * 0.25rem;
  }
  
  .mr-#{$i} {
    margin-right: $i * 0.25rem;
  }
  
  .mb-#{$i} {
    margin-bottom: $i * 0.25rem;
  }
  
  .ml-#{$i} {
    margin-left: $i * 0.25rem;
  }
}

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

Creating Visual Effects

@for loops can also create complex visual effects:

// Create a staggered animation delay for list items
@for $i from 1 through 10 {
  .animate-list li:nth-child(#{$i}) {
    animation-delay: 0.1s * $i;
  }
}

// Create a stepped gradient
.gradient-steps {
  background: linear-gradient(to right,
    @for $i from 0 through 10 {
      rgba(0, 0, 255, $i / 10) #{$i * 10}%#{if($i < 10, ',', '')}
    }
  );
}

The @each Loop

The @each directive allows you to iterate through a list or map, making it perfect for generating variations of a component using a set of predefined values.

Basic @each with Lists

$colors: 'red', 'green', 'blue', 'yellow';

@each $color in $colors {
  .text-#{$color} {
    color: #{$color};
  }
}

/* Compiles to:
.text-red { color: red; }
.text-green { color: green; }
.text-blue { color: blue; }
.text-yellow { color: yellow; }
*/

@each with Maps

Maps let you associate values with keys, making your loops more meaningful:

$theme-colors: (
  'primary': #007bff,
  'success': #28a745,
  'danger': #dc3545,
  'warning': #ffc107
);

@each $name, $color in $theme-colors {
  .btn-#{$name} {
    background-color: $color;
    border-color: darken($color, 10%);
    
    &:hover {
      background-color: darken($color, 7.5%);
      border-color: darken($color, 15%);
    }
  }
  
  .text-#{$name} {
    color: $color;
  }
  
  .bg-#{$name} {
    background-color: $color;
  }
}

Nested Maps for Component Variations

For more complex components, you can use nested maps:

$alert-variants: (
  'info': (
    'background': #e6f7ff,
    'border': #91d5ff,
    'text': #0066cc
  ),
  'success': (
    'background': #e6ffee,
    'border': #8eedac,
    'text': #00a854
  ),
  'warning': (
    'background': #fffbe6,
    'border': #ffe58f,
    'text': #d48806
  ),
  'danger': (
    'background': #fff1f0,
    'border': #ffa39e,
    'text': #cf1322
  )
);

@each $variant, $properties in $alert-variants {
  .alert-#{$variant} {
    padding: 15px;
    border-radius: 4px;
    background-color: map-get($properties, 'background');
    border: 1px solid map-get($properties, 'border');
    color: map-get($properties, 'text');
  }
}

Multiple Variables in @each

@each can also work with lists of lists, allowing you to assign multiple variables at once:

$button-styles: (
  'primary' #007bff white,
  'success' #28a745 white,
  'danger' #dc3545 white,
  'light' #f8f9fa #212529
);

@each $name, $background, $text in $button-styles {
  .btn-#{$name} {
    background-color: $background;
    color: $text;
    
    &:hover {
      background-color: darken($background, 7.5%);
    }
  }
}

This is conceptually similar to destructuring in JavaScript or other languages.

@each for Managing Assets

@each is useful for managing asset paths and creating icon systems:

$social-icons: 'facebook', 'twitter', 'instagram', 'linkedin', 'youtube';

@each $platform in $social-icons {
  .icon-#{$platform} {
    background-image: url('/assets/icons/#{$platform}.svg');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
  }
}

The @while Loop

The @while directive creates a loop that repeats until a condition becomes false. It's less commonly used than @for and @each, but can be powerful for situations where you need more complex stopping conditions.

Basic @while Syntax

$i: 1;

@while $i <= 5 {
  .item-#{$i} {
    width: 20% * $i;
  }
  
  $i: $i + 1;
}

This example produces the same output as the @for example we saw earlier, but with a different control structure.

Creating a Fibonacci Sequence

@while is useful for more complex series where the next value depends on previous values:

// Generate a Fibonacci sequence for spacing
$fib1: 1;
$fib2: 1;
$count: 1;

@while $count <= 10 {
  .space-#{$count} {
    margin-bottom: $fib1 + rem;
  }
  
  $fib3: $fib1 + $fib2;
  $fib1: $fib2;
  $fib2: $fib3;
  $count: $count + 1;
}

/* Compiles to:
.space-1 { margin-bottom: 1rem; }
.space-2 { margin-bottom: 1rem; }
.space-3 { margin-bottom: 2rem; }
.space-4 { margin-bottom: 3rem; }
.space-5 { margin-bottom: 5rem; }
.space-6 { margin-bottom: 8rem; }
.space-7 { margin-bottom: 13rem; }
.space-8 { margin-bottom: 21rem; }
.space-9 { margin-bottom: 34rem; }
.space-10 { margin-bottom: 55rem; }
*/

Creating Color Variations

@while can generate color variations until a threshold is reached:

// Generate progressively darker variations of a color
$base-color: #3498db;
$variation: 1;
$darkness: 0;

@while $darkness < 50 {
  .color-variation-#{$variation} {
    background-color: darken($base-color, $darkness);
  }
  
  $darkness: $darkness + 10;
  $variation: $variation + 1;
}

/* Compiles to:
.color-variation-1 { background-color: #3498db; } /* 0% darker */
.color-variation-2 { background-color: #2589ce; } /* 10% darker */
.color-variation-3 { background-color: #1a7ab9; } /* 20% darker */
.color-variation-4 { background-color: #166aa3; } /* 30% darker */
.color-variation-5 { background-color: #125a8d; } /* 40% darker */
.color-variation-6 { background-color: #0e4b76; } /* 50% darker */
*/

Real-World Applications

Creating a Complete Utility Class System

Popular frameworks like Tailwind CSS use control directives to generate thousands of utility classes:

// _utilities.scss

// Configuration
$spacer: 0.25rem;
$spacings: (0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64);
$sides: ('t': 'top', 'r': 'right', 'b': 'bottom', 'l': 'left');
$breakpoints: (
  'sm': 640px,
  'md': 768px,
  'lg': 1024px,
  'xl': 1280px,
  '2xl': 1536px
);
$colors: (
  'blue': #3498db,
  'green': #2ecc71,
  'red': #e74c3c,
  'yellow': #f1c40f,
  'purple': #9b59b6,
  'gray': #95a5a6,
  'black': #000,
  'white': #fff
);

// Generate responsive utilities
@mixin responsive-variants {
  @content;
  
  @each $breakpoint, $value in $breakpoints {
    @media (min-width: $value) {
      .#{$breakpoint}\: {
        @content;
      }
    }
  }
}

// Spacing utilities (margin and padding)
@include responsive-variants {
  // All sides
  @each $space in $spacings {
    .m-#{$space} {
      margin: $spacer * $space;
    }
    
    .p-#{$space} {
      padding: $spacer * $space;
    }
  }
  
  // Individual sides
  @each $abbr, $side in $sides {
    @each $space in $spacings {
      .m#{$abbr}-#{$space} {
        margin-#{$side}: $spacer * $space;
      }
      
      .p#{$abbr}-#{$space} {
        padding-#{$side}: $spacer * $space;
      }
    }
  }
  
  // X and Y sides
  @each $space in $spacings {
    .mx-#{$space} {
      margin-left: $spacer * $space;
      margin-right: $spacer * $space;
    }
    
    .my-#{$space} {
      margin-top: $spacer * $space;
      margin-bottom: $spacer * $space;
    }
    
    .px-#{$space} {
      padding-left: $spacer * $space;
      padding-right: $spacer * $space;
    }
    
    .py-#{$space} {
      padding-top: $spacer * $space;
      padding-bottom: $spacer * $space;
    }
  }
}

// Width and height utilities
@include responsive-variants {
  @for $i from 1 through 6 {
    .w-#{$i*10} {
      width: $i * 10%;
    }
    
    .h-#{$i*10} {
      height: $i * 10%;
    }
  }
  
  .w-full {
    width: 100%;
  }
  
  .h-full {
    height: 100%;
  }
  
  .w-screen {
    width: 100vw;
  }
  
  .h-screen {
    height: 100vh;
  }
}

// Color utilities
@include responsive-variants {
  @each $name, $value in $colors {
    .text-#{$name} {
      color: $value;
    }
    
    .bg-#{$name} {
      background-color: $value;
    }
    
    .border-#{$name} {
      border-color: $value;
    }
  }
}

Theme System with Material Design Color Palette

Control directives can create a sophisticated theme system:

// _theme.scss

// Material Design color palette
$material-colors: (
  'red': (
    50: #ffebee,
    100: #ffcdd2,
    200: #ef9a9a,
    300: #e57373,
    400: #ef5350,
    500: #f44336,
    600: #e53935,
    700: #d32f2f,
    800: #c62828,
    900: #b71c1c,
    'accent': #ff8a80
  ),
  'blue': (
    50: #e3f2fd,
    100: #bbdefb,
    200: #90caf9,
    300: #64b5f6,
    400: #42a5f5,
    500: #2196f3,
    600: #1e88e5,
    700: #1976d2,
    800: #1565c0,
    900: #0d47a1,
    'accent': #82b1ff
  ),
  'green': (
    50: #e8f5e9,
    100: #c8e6c9,
    200: #a5d6a7,
    300: #81c784,
    400: #66bb6a,
    500: #4caf50,
    600: #43a047,
    700: #388e3c,
    800: #2e7d32,
    900: #1b5e20,
    'accent': #b9f6ca
  )
);

// Theme configuration
$themes: (
  'light': (
    'background': white,
    'surface': #f5f5f5,
    'text-primary': rgba(0, 0, 0, 0.87),
    'text-secondary': rgba(0, 0, 0, 0.6),
    'primary-color': map-get(map-get($material-colors, 'blue'), 500),
    'secondary-color': map-get(map-get($material-colors, 'green'), 500),
    'error-color': map-get(map-get($material-colors, 'red'), 500)
  ),
  'dark': (
    'background': #121212,
    'surface': #1e1e1e,
    'text-primary': rgba(255, 255, 255, 0.87),
    'text-secondary': rgba(255, 255, 255, 0.6),
    'primary-color': map-get(map-get($material-colors, 'blue'), 300),
    'secondary-color': map-get(map-get($material-colors, 'green'), 300),
    'error-color': map-get(map-get($material-colors, 'red'), 300)
  )
);

// Material color palette generation
@each $color-name, $color-variants in $material-colors {
  @each $variant, $value in $color-variants {
    .#{$color-name}-#{$variant} {
      background-color: $value;
    }
    
    .text-#{$color-name}-#{$variant} {
      color: $value;
    }
  }
}

// Theme generation
@each $theme-name, $theme-vars in $themes {
  .theme-#{$theme-name} {
    // Theme variables for the entire app
    --background: #{map-get($theme-vars, 'background')};
    --surface: #{map-get($theme-vars, 'surface')};
    --text-primary: #{map-get($theme-vars, 'text-primary')};
    --text-secondary: #{map-get($theme-vars, 'text-secondary')};
    --primary-color: #{map-get($theme-vars, 'primary-color')};
    --secondary-color: #{map-get($theme-vars, 'secondary-color')};
    --error-color: #{map-get($theme-vars, 'error-color')};
    
    // Apply base theme styles
    background-color: var(--background);
    color: var(--text-primary);
    
    // Component theming examples
    .app-bar {
      background-color: var(--primary-color);
      color: white;
    }
    
    .card {
      background-color: var(--surface);
      color: var(--text-primary);
    }
    
    .button-primary {
      background-color: var(--primary-color);
      color: white;
    }
    
    .button-secondary {
      background-color: var(--secondary-color);
      color: white;
    }
    
    .error-message {
      color: var(--error-color);
    }
  }
}

Responsive Typography System

Create a complete responsive typography system with a few directives:

// _typography.scss

// Type scale base sizes for different breakpoints
$type-scales: (
  'base': (
    'xs': 0.75rem,   // 12px
    'sm': 0.875rem,  // 14px
    'base': 1rem,    // 16px
    'lg': 1.125rem,  // 18px
    'xl': 1.25rem,   // 20px
    '2xl': 1.5rem,   // 24px
    '3xl': 1.875rem, // 30px
    '4xl': 2.25rem,  // 36px
    '5xl': 3rem,     // 48px
    '6xl': 4rem      // 64px
  ),
  'md': (
    'xs': 0.75rem,
    'sm': 0.875rem,
    'base': 1rem,
    'lg': 1.125rem,
    'xl': 1.25rem,
    '2xl': 1.5rem,
    '3xl': 2rem,     // Slightly larger
    '4xl': 2.5rem,   // Slightly larger
    '5xl': 3.25rem,  // Slightly larger
    '6xl': 4.5rem    // Slightly larger
  ),
  'lg': (
    'xs': 0.75rem,
    'sm': 0.875rem,
    'base': 1rem,
    'lg': 1.125rem,
    'xl': 1.25rem,
    '2xl': 1.5rem,
    '3xl': 2.25rem,  // Even larger
    '4xl': 2.75rem,  // Even larger
    '5xl': 3.5rem,   // Even larger
    '6xl': 5rem      // Even larger
  )
);

// Line heights for different text sizes
$line-heights: (
  'xs': 1.5,
  'sm': 1.5,
  'base': 1.5,
  'lg': 1.5,
  'xl': 1.4,
  '2xl': 1.35,
  '3xl': 1.3,
  '4xl': 1.25,
  '5xl': 1.2,
  '6xl': 1.1
);

// Font weights
$font-weights: (
  'thin': 100,
  'extralight': 200,
  'light': 300,
  'normal': 400,
  'medium': 500,
  'semibold': 600,
  'bold': 700,
  'extrabold': 800,
  'black': 900
);

// Generate base typography styles
@each $size, $value in map-get($type-scales, 'base') {
  .text-#{$size} {
    font-size: $value;
    line-height: map-get($line-heights, $size);
  }
}

// Generate font weight utilities
@each $weight-name, $weight-value in $font-weights {
  .font-#{$weight-name} {
    font-weight: $weight-value;
  }
}

// Generate responsive typography
@each $breakpoint-name, $scale in $type-scales {
  @if $breakpoint-name == 'base' {
    // Base styles already generated
  } @else if $breakpoint-name == 'md' {
    @media (min-width: 768px) {
      @each $size, $value in $scale {
        .text-#{$size} {
          font-size: $value;
        }
      }
    }
  } @else if $breakpoint-name == 'lg' {
    @media (min-width: 1024px) {
      @each $size, $value in $scale {
        .text-#{$size} {
          font-size: $value;
        }
      }
    }
  }
}

// Generate responsive alignment utilities
@each $alignment in (left, center, right, justify) {
  .text-#{$alignment} {
    text-align: $alignment;
  }
  
  @media (min-width: 768px) {
    .md\:text-#{$alignment} {
      text-align: $alignment;
    }
  }
  
  @media (min-width: 1024px) {
    .lg\:text-#{$alignment} {
      text-align: $alignment;
    }
  }
}

Best Practices for Control Directives

Keep Logic Simple

While Sass control directives give you programming power, complex logic can become difficult to maintain:

// Avoid overly complex conditional logic
@mixin complex-component($type, $size, $theme, $state) {
  @if $type == 'button' {
    @if $theme == 'light' {
      @if $state == 'active' {
        // Deeply nested conditions become hard to follow
      } @else {
        // ...
      }
    } @else if $theme == 'dark' {
      // ...
    }
  } @else if $type == 'card' {
    // ...
  }
}

// Instead, break logic into smaller, focused mixins
@mixin button-base {
  // Common button styles
}

@mixin button-theme($theme) {
  @if $theme == 'light' {
    // Light theme styles
  } @else if $theme == 'dark' {
    // Dark theme styles
  }
}

@mixin button-state($state) {
  @if $state == 'active' {
    // Active state styles
  } @else if $state == 'disabled' {
    // Disabled state styles
  }
}

Use Maps for Complex Data

Maps are more maintainable than hard-coded values in loops:

// Less maintainable approach
@for $i from 1 through 6 {
  .h#{$i} {
    @if $i == 1 {
      font-size: 2.5rem;
    } @else if $i == 2 {
      font-size: 2rem;
    } @else if $i == 3 {
      font-size: 1.75rem;
    } @else if $i == 4 {
      font-size: 1.5rem;
    } @else if $i == 5 {
      font-size: 1.25rem;
    } @else if $i == 6 {
      font-size: 1rem;
    }
  }
}

// More maintainable with maps
$heading-sizes: (
  1: 2.5rem,
  2: 2rem,
  3: 1.75rem,
  4: 1.5rem,
  5: 1.25rem,
  6: 1rem
);

@each $level, $size in $heading-sizes {
  .h#{$level} {
    font-size: $size;
  }
}

Avoid Too Many Generated Variations

Be strategic about which variations to generate to avoid CSS bloat:

// This could generate thousands of classes - too many!
@for $r from 0 through 255 {
  @for $g from 0 through 255 {
    @for $b from 0 through 255 {
      .color-#{$r}-#{$g}-#{$b} {
        color: rgb($r, $g, $b);
      }
    }
  }
}

// Better approach: generate only the ones you'll actually use
$color-values: (0, 51, 102, 153, 204, 255);

@each $r in $color-values {
  @each $g in $color-values {
    @each $b in $color-values {
      .color-#{$r}-#{$g}-#{$b} {
        color: rgb($r, $g, $b);
      }
    }
  }
}

Document Complex Control Flow

Add comments to explain what your control directives are doing, especially for complex logic:

// Generate a stepped color progression from one color to another
// $steps: Number of color variations to create
// $start: Starting color (hex)
// $end: Ending color (hex)
@mixin color-progression($prefix, $start, $end, $steps) {
  // Store the red, green, and blue components of each color
  $start-red: red($start);
  $start-green: green($start);
  $start-blue: blue($start);
  
  $end-red: red($end);
  $end-green: green($end);
  $end-blue: blue($end);
  
  // Calculate the amount to change each component per step
  $step-red: ($end-red - $start-red) / ($steps - 1);
  $step-green: ($end-green - $start-green) / ($steps - 1);
  $step-blue: ($end-blue - $start-blue) / ($steps - 1);
  
  // Generate each step
  @for $i from 0 through ($steps - 1) {
    $current-red: round($start-red + ($step-red * $i));
    $current-green: round($start-green + ($step-green * $i));
    $current-blue: round($start-blue + ($step-blue * $i));
    
    .#{$prefix}-#{$i + 1} {
      background-color: rgb($current-red, $current-green, $current-blue);
    }
  }
}

Practice Activities

  1. Responsive Grid System: Create a responsive grid system with 12 columns using @for loops. Include classes for different breakpoints (e.g., .col-sm-6, .col-md-4).
  2. Dynamic Theme Builder: Build a theme system that generates light and dark themes for a UI component library. Use @each to iterate through components and @if to handle theme-specific variations.
  3. Utility Class Generator: Create a set of utility classes for spacing (margin and padding) using @for loops. Include variations for different sides (top, right, bottom, left) and sizes.
  4. Social Media Icon System: Build a social media icon system using @each to iterate through a list of platforms, generating classes with appropriate colors and background images.
  5. Advanced Typography Scale: Create a responsive typography system with a modular scale. Use @each and @if directives to handle different breakpoints and ensure text remains readable at all screen sizes.

Additional Resources

Key Takeaways

Next Lecture

In our next session, we'll explore Sass Architecture and Organization, focusing on how to structure large-scale Sass projects for maintainability and scalability.