🎨 SCSS Basics

SCSS (Sassy CSS) is a preprocessor that extends CSS with powerful features like variables, nesting, mixins, and functions. It makes CSS more maintainable and easier to write.

What is SCSS?

SCSS is part of Sass (Syntactically Awesome StyleSheets). It's a superset of CSS, meaning all valid CSS is also valid SCSS.

SCSS Compilation
style.scss  →  [Compiler]  →  style.css  →  Browser
(You write)    (Processes)     (Output)      (Reads)
📝 SCSS vs Sass

SCSS uses CSS-like syntax with curly braces {}

Sass uses indentation (older syntax)

Most developers prefer SCSS because it's closer to regular CSS.

Setup

Installation

Using npm
# Install Sass globally
npm install -g sass

# Watch and compile SCSS to CSS
sass --watch style.scss:style.css

# Watch entire folder
sass --watch scss:css
VS Code Extension

Install "Live Sass Compiler" extension - compiles automatically on save.

Variables

Store reusable values (colors, fonts, sizes) in variables.

SCSS
// Define variables with $
$primary-color: #4a90e2;
$secondary-color: #50c878;
$font-stack: Arial, sans-serif;
$base-padding: 20px;

// Use variables
body {
  font-family: $font-stack;
  color: $primary-color;
  padding: $base-padding;
}

.button {
  background-color: $primary-color;
  padding: $base-padding / 2; // Math operations!
}
Compiled CSS
body {
  font-family: Arial, sans-serif;
  color: #4a90e2;
  padding: 20px;
}

.button {
  background-color: #4a90e2;
  padding: 10px;
}
💡 Variable Benefits
  • Change one value, update everywhere
  • Maintain consistent design system
  • Self-documenting code
  • Easy theme switching

Nesting

Nest selectors inside one another to mirror HTML structure.

SCSS (Nested)
.nav {
  background: #333;
  padding: 10px;

  // Nested selector
  ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  li {
    display: inline-block;
  }

  a {
    color: white;
    text-decoration: none;

    // & refers to parent selector (.nav a)
    &:hover {
      color: #4a90e2;
    }
  }
}
Compiled CSS
.nav {
  background: #333;
  padding: 10px;
}

.nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav li {
  display: inline-block;
}

.nav a {
  color: white;
  text-decoration: none;
}

.nav a:hover {
  color: #4a90e2;
}

Parent Selector (&)

.button {
  background: blue;

  // Pseudo-classes
  &:hover {
    background: darkblue;
  }

  &:active {
    transform: scale(0.95);
  }

  // Modifier classes
  &--large {
    padding: 20px 40px;
  }

  &--small {
    padding: 5px 10px;
  }
}
⚠️ Don't Over-Nest

Avoid nesting more than 3-4 levels deep. It makes CSS too specific and hard to override.

Partials and @import

Split CSS into smaller, modular files (partials) and import them.

File Structure
scss/
├── _variables.scss    (starts with _)
├── _mixins.scss
├── _buttons.scss
├── _navigation.scss
└── main.scss          (imports all partials)
_variables.scss
$primary-color: #4a90e2;
$font-stack: Arial, sans-serif;
main.scss
// Import partials (no _ or .scss needed)
@import 'variables';
@import 'mixins';
@import 'buttons';
@import 'navigation';
📝 Note

Files starting with _ are partials and won't be compiled to separate CSS files. Only the main file that imports them will be compiled.

Mixins

Reusable chunks of CSS that can accept parameters.

Define Mixin
// Mixin without parameters
@mixin reset-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

// Mixin with parameters
@mixin button-style($bg-color, $text-color) {
  background-color: $bg-color;
  color: $text-color;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;

  &:hover {
    opacity: 0.8;
  }
}

// Use mixin with @include
ul {
  @include reset-list;
}

.btn-primary {
  @include button-style(#4a90e2, white);
}

.btn-danger {
  @include button-style(#e74c3c, white);
}

Common Mixin Examples

// Flexbox centering
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

// Responsive breakpoint
@mixin tablet {
  @media (min-width: 768px) {
    @content; // Insert content here
  }
}

// Usage
.container {
  padding: 10px;

  @include tablet {
    padding: 20px;
  }
}

Functions

Functions return values (unlike mixins which output CSS).

// Define function
@function calculate-rem($size) {
  @return $size / 16px * 1rem;
}

// Built-in color functions
$base-color: #4a90e2;

.box {
  background: $base-color;
  border: 1px solid darken($base-color, 10%);

  &:hover {
    background: lighten($base-color, 10%);
  }
}

// Usage
h1 {
  font-size: calculate-rem(32px); // 2rem
}

Useful Built-in Functions

Function Purpose
darken($color, $amount) Makes color darker
lighten($color, $amount) Makes color lighter
mix($color1, $color2) Mixes two colors
rgba($color, $alpha) Adds transparency
percentage($number) Converts to percentage
round($number) Rounds number

Operators

SCSS supports mathematical operations.

$base-size: 16px;

.container {
  width: 100% / 3;           // 33.333%
  padding: $base-size * 2;     // 32px
  margin: $base-size / 2;      // 8px
  font-size: $base-size + 4px; // 20px
}

@extend

Share styles between selectors.

// Base button styles
.button {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

// Extend base styles
.button-primary {
  @extend .button;
  background: blue;
  color: white;
}

.button-danger {
  @extend .button;
  background: red;
  color: white;
}
💡 Mixin vs Extend

Mixins: Copy code to each selector (more CSS, more flexible)

@extend: Groups selectors (less CSS, less flexible)

Generally prefer mixins for clarity and control.

Practical Example

_variables.scss
// Colors
$primary: #4a90e2;
$secondary: #50c878;
$danger: #e74c3c;
$text-color: #333;

// Spacing
$spacing-unit: 8px;

// Breakpoints
$tablet: 768px;
$desktop: 1200px;
_mixins.scss
@mixin respond-to($breakpoint) {
  @media (min-width: $breakpoint) {
    @content;
  }
}

@mixin button($bg, $color: white) {
  background-color: $bg;
  color: $color;
  padding: $spacing-unit $spacing-unit * 2;
  border: none;
  border-radius: 4px;

  &:hover {
    background-color: darken($bg, 10%);
  }
}
main.scss
@import 'variables';
@import 'mixins';

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

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

.container {
  padding: $spacing-unit * 2;

  @include respond-to($tablet) {
    padding: $spacing-unit * 4;
  }
}

Best Practices

💡 SCSS Best Practices
  • ✅ Use variables for colors, sizes, and reusable values
  • ✅ Keep nesting shallow (max 3-4 levels)
  • ✅ Organize with partials (_variables, _mixins, etc.)
  • ✅ Use mixins for repeated patterns
  • ✅ Prefer mixins over @extend
  • ✅ Use meaningful variable names ($primary-color, not $blue)
  • ✅ Comment complex logic
  • ❌ Don't nest media queries too deep
  • ❌ Don't over-use @extend (can bloat CSS)

Summary

📚 What you learned
  • SCSS is a CSS preprocessor with extra features
  • Variables store reusable values
  • Nesting mirrors HTML structure
  • Partials organize code into modules
  • Mixins create reusable code blocks
  • Functions return calculated values
  • Built-in functions manipulate colors and numbers
  • @extend shares styles between selectors