Web Development

SASS/SCSS: CSS Preprocessor untuk Styling Modern

Tutorial lengkap SASS/SCSS — variabel, mixins, nesting, functions, partials, inheritance, dan best practices untuk CSS yang maintainable

1. Pengenalan SASS/SCSS

SASS (Syntactically Awesome Style Sheets) adalah CSS preprocessor yang memperkaya CSS dengan fitur-fitur yang tidak tersedia di CSS biasa: variabel, nesting, mixins, functions, inheritance, dan banyak lagi. SASS ditulis dalam sintaks yang lebih powerful lalu dikompilasi menjadi CSS biasa yang bisa dibaca browser.

SASS vs SCSS

SASS memiliki dua sintaks:

Aspek SASS (Indented Syntax) SCSS (Sassy CSS)
Ekstensi .sass .scss
Kurung Tidak menggunakan {} Menggunakan {} seperti CSS
Titik koma Tidak perlu ; Perlu ;
Indentasi Indentasi menentukan blok Kurung menentukan blok
Popularitas Kurang populer ⭐ Sangat populer
SASS vs SCSS
// ===== SASS Syntax (.sass) =====
$primary: #3498db

.container
  max-width: 1200px
  margin: 0 auto

  h1
    color: $primary
    font-size: 2rem

// ===== SCSS Syntax (.scss) =====
$primary: #3498db;

.container {
  max-width: 1200px;
  margin: 0 auto;

  h1 {
    color: $primary;
    font-size: 2rem;
  }
}

Di tutorial ini kita akan fokus pada SCSS karena lebih populer dan lebih mudah dipelajari karena mirip dengan CSS biasa.

Mengapa Menggunakan SASS/SCSS?

2. Instalasi & Setup

Instalasi SASS

Bash
# Instal global
npm install -g sass

# Atau instal sebagai dev dependency
npm install -D sass

# Cek versi
sass --version

Kompilasi SCSS ke CSS

Bash
# Kompilasi satu file
sass src/scss/main.scss dist/css/style.css

# Watch mode: otomatis compile saat file berubah
sass --watch src/scss:dist/css

# Kompilasi dengan output compressed (production)
sass --style=compressed src/scss/main.scss dist/css/style.css

# Source map untuk debugging
sass --source-map src/scss/main.scss dist/css/style.css

Integrasi dengan Vite / Webpack

Bash
# Vite: SCSS langsung didukung, cukup instal sass
npm install -D sass

# Lalu import di file JS/TS:
# import './styles/main.scss';

# Webpack: gunakan sass-loader
npm install -D sass sass-loader css-loader style-loader
💡 Tips

Jika menggunakan Vite atau framework modern seperti Next.js, SASS sudah terintegrasi tinggal instal paket sass dan langsung bisa mengimpor file .scss.

3. Variabel

Variabel di SCSS menggunakan simbol $ untuk menyimpan nilai yang bisa digunakan ulang. Ini sangat berguna untuk menyimpan warna, ukuran font, breakpoint, dan nilai-nilai lain yang konsisten di seluruh stylesheet.

Definisi & Penggunaan Variabel

SCSS
// ===== Color Variables =====
$primary: #3498db;
$secondary: #2ecc71;
$danger: #e74c3c;
$warning: #f39c12;
$dark: #2c3e50;
$light: #ecf0f1;
$white: #ffffff;
$black: #000000;
$gray: #95a5a6;
$gray-light: #bdc3c7;
$gray-dark: #7f8c8d;

// ===== Typography Variables =====
$font-primary: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
$font-mono: 'JetBrains Mono', 'Fira Code', monospace;
$font-size-base: 16px;
$font-size-sm: 0.875rem;
$font-size-lg: 1.25rem;
$font-size-xl: 1.5rem;
$font-size-h1: 2.5rem;
$font-size-h2: 2rem;
$font-size-h3: 1.75rem;
$line-height-base: 1.6;
$font-weight-normal: 400;
$font-weight-bold: 700;

// ===== Spacing Variables =====
$spacing-xs: 4px;
$spacing-sm: 8px;
$spacing-md: 16px;
$spacing-lg: 24px;
$spacing-xl: 32px;
$spacing-xxl: 48px;

// ===== Breakpoints =====
$breakpoint-sm: 576px;
$breakpoint-md: 768px;
$breakpoint-lg: 1024px;
$breakpoint-xl: 1200px;

// ===== Border & Radius =====
$border-radius-sm: 4px;
$border-radius-md: 8px;
$border-radius-lg: 16px;
$border-radius-full: 9999px;
$border-color: #e0e0e0;
$border-width: 1px;

// ===== Shadows =====
$shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
$shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
$shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.15);
$shadow-xl: 0 20px 50px rgba(0, 0, 0, 0.2);

// ===== Transitions =====
$transition-fast: 150ms ease;
$transition-base: 300ms ease;
$transition-slow: 500ms ease;

Menggunakan Variabel

SCSS
// Menggunakan variabel di properties
body {
  font-family: $font-primary;
  font-size: $font-size-base;
  line-height: $line-height-base;
  color: $dark;
  background-color: $white;
}

.button {
  padding: $spacing-sm $spacing-md;
  border-radius: $border-radius-md;
  font-weight: $font-weight-bold;
  transition: all $transition-base;

  &-primary {
    background-color: $primary;
    color: $white;
  }

  &-danger {
    background-color: $danger;
    color: $white;
  }
}

.card {
  background: $white;
  border-radius: $border-radius-lg;
  box-shadow: $shadow-md;
  padding: $spacing-lg;
  border: $border-width solid $border-color;
}

Variable Scoping (Global vs Local)

SCSS
$color: blue; // Global

.container {
  $color: red; // Local: hanya berlaku di dalam blok ini
  color: $color; // Merah
}

.sidebar {
  color: $color; // Biru (menggunakan global)
}

// !global flag: membuat variabel local menjadi global
.container {
  $color: green !global;
  color: $color; // Hijau
}

.sidebar {
  color: $color; // Hijau (sekarang global)
}

// !default flag: hanya set jika belum didefinisikan
$color: blue;
$color: red !default; // Tetap blue karena sudah didefinisikan

$other: red !default; // Red, karena belum ada definisi sebelumnya

4. Nesting

Nesting memungkinkan kamu menulis CSS dengan struktur yang meniru hierarki HTML. Ini membuat kode lebih rapi dan mudah dibaca.

Basic Nesting

SCSS
// SCSS dengan nesting
.navbar {
  background-color: $dark;
  padding: $spacing-md;

  .logo {
    font-size: $font-size-xl;
    color: $white;
    text-decoration: none;

    &:hover {
      color: $primary;
    }
  }

  .nav-links {
    display: flex;
    gap: $spacing-md;
    list-style: none;
    margin: 0;
    padding: 0;

    li {
      a {
        color: $light;
        text-decoration: none;
        padding: $spacing-sm $spacing-md;
        border-radius: $border-radius-sm;
        transition: background $transition-fast;

        &:hover {
          background-color: rgba($white, 0.1);
          color: $white;
        }

        &.active {
          color: $primary;
          font-weight: $font-weight-bold;
        }
      }
    }
  }
}

Parent Selector (&) yang Powerful

SCSS
.button {
  padding: 10px 20px;
  border-radius: $border-radius-md;
  cursor: pointer;

  // & = parent selector → .button:hover
  &:hover {
    opacity: 0.9;
    transform: translateY(-1px);
  }

  // &:focus → .button:focus
  &:focus {
    outline: 2px solid $primary;
    outline-offset: 2px;
  }

  // &:disabled → .button:disabled
  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  // &-primary → .button-primary
  &-primary {
    background-color: $primary;
    color: $white;

    &:hover {
      background-color: darken($primary, 10%);
    }
  }

  // &-outline → .button-outline
  &-outline {
    background-color: transparent;
    border: 2px solid $primary;
    color: $primary;

    &:hover {
      background-color: $primary;
      color: $white;
    }
  }

  // .button.is-large (BEM modifier)
  &.is-large {
    padding: 14px 28px;
    font-size: $font-size-lg;
  }

  // button & → button .button (parent element)
  .form-group & {
    margin-top: $spacing-md;
  }
}

Nesting Properties

SCSS
// Nesting properties dengan namespace
.title {
  font: {
    family: $font-primary;
    size: $font-size-h1;
    weight: $font-weight-bold;
  }
  text: {
    align: center;
    transform: uppercase;
    decoration: none;
  }
  border: {
    top: 1px solid $border-color;
    bottom: 2px solid $primary;
    radius: $border-radius-md;
  }
  margin: {
    top: $spacing-lg;
    bottom: $spacing-lg;
    left: auto;
    right: auto;
  }
}

// Output CSS:
// .title {
//   font-family: 'Inter', sans-serif;
//   font-size: 2.5rem;
//   font-weight: 700;
//   text-align: center;
//   text-transform: uppercase;
//   ...
// }
⚠️ Peringatan

Hindari nesting terlalu dalam (maksimal 3-4 level). Nesting berlebihan menghasilkan CSS selector yang sangat spesifik dan sulit di-override. Gunakan BEM naming convention untuk membantu menjaga struktur tetap flat.

5. Mixins

Mixins adalah blok CSS reusable yang bisa dipanggil berkali-kali. Berbeda dari variabel yang hanya menyimpan satu nilai, mixins bisa menyimpan satu atau lebih properties CSS lengkap beserta logikanya. Mixins menggunakan @mixin untuk mendefinisikan dan @include untuk menggunakannya.

Basic Mixin

SCSS
// Definisi mixin
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

@mixin flex-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

@mixin absolute-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

@mixin reset-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

// Menggunakan mixin
.hero {
  @include flex-center;
  min-height: 100vh;
  background: linear-gradient(135deg, $primary, $secondary);
}

.navbar {
  @include flex-between;
  padding: $spacing-md $spacing-lg;
}

.dropdown-menu {
  ul {
    @include reset-list;
  }
}

.modal-overlay {
  @include flex-center;
  @include absolute-center; // Bisa include multiple mixins
  background: rgba(0, 0, 0, 0.5);
}

Mixin dengan Parameters

SCSS
// Mixin dengan parameter
@mixin responsive($breakpoint) {
  @if $breakpoint == sm {
    @media (min-width: $breakpoint-sm) { @content; }
  } @else if $breakpoint == md {
    @media (min-width: $breakpoint-md) { @content; }
  } @else if $breakpoint == lg {
    @media (min-width: $breakpoint-lg) { @content; }
  } @else if $breakpoint == xl {
    @media (min-width: $breakpoint-xl) { @content; }
  }
}

// Mixin dengan default parameter
@mixin padding($vertical: $spacing-md, $horizontal: $spacing-md) {
  padding: $vertical $horizontal;
}

@mixin button-variant($bg-color, $text-color: $white) {
  background-color: $bg-color;
  color: $text-color;
  border: none;
  padding: $spacing-sm $spacing-md;
  border-radius: $border-radius-md;
  cursor: pointer;
  transition: background $transition-fast;

  &:hover {
    background-color: darken($bg-color, 10%);
  }

  &:active {
    background-color: darken($bg-color, 15%);
  }
}

// Menggunakan mixin dengan parameter
.grid {
  display: grid;
  grid-template-columns: 1fr;

  @include responsive(md) {
    grid-template-columns: 1fr 1fr;
  }

  @include responsive(lg) {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

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

  &-success {
    @include button-variant($secondary);
  }

  &-danger {
    @include button-variant($danger);
  }

  &-outline {
    @include button-variant(transparent, $primary);
    border: 2px solid $primary;
  }
}

.card {
  @include padding($spacing-lg, $spacing-xl);
}

Mixin dengan @content

SCSS
// @content memungkinkan passing CSS blocks ke dalam mixin
@mixin hover-effect {
  transition: all $transition-base;

  &:hover {
    @content; // CSS yang di-pass masuk ke sini
  }
}

@mixin dark-mode {
  @media (prefers-color-scheme: dark) {
    @content;
  }
}

@mixin mobile-first {
  @media (max-width: #{$breakpoint-md - 1}) {
    @content;
  }
}

// Usage
.card {
  background: $white;
  box-shadow: $shadow-md;

  @include hover-effect {
    box-shadow: $shadow-lg;
    transform: translateY(-2px);
  }
}

.sidebar {
  background: $white;

  @include dark-mode {
    background: $dark;
    color: $light;
  }
}

.container {
  padding: 0 $spacing-lg;

  @include mobile-first {
    padding: 0 $spacing-md;
  }
}

Practical Mixins Collection

SCSS
// Text truncation
@mixin text-truncate($lines: 1) {
  @if $lines == 1 {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  } @else {
    display: -webkit-box;
    -webkit-line-clamp: $lines;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

// Scrollbar styling
@mixin custom-scrollbar($width: 6px, $color: $gray-light) {
  &::-webkit-scrollbar {
    width: $width;
  }
  &::-webkit-scrollbar-track {
    background: transparent;
  }
  &::-webkit-scrollbar-thumb {
    background: $color;
    border-radius: $width;
  }
}

// Glass effect
@mixin glass-effect($blur: 10px, $opacity: 0.8) {
  background: rgba($white, $opacity);
  backdrop-filter: blur($blur);
  -webkit-backdrop-filter: blur($blur);
  border: 1px solid rgba($white, 0.2);
}

// Responsive font size
@mixin fluid-font($min-size, $max-size, $min-width: 320, $max-width: 1200) {
  font-size: clamp(
    #{$min-size}px,
    calc(#{$min-size}px + (#{$max-size} - #{$min-size}) * ((100vw - #{$min-width}px) / (#{$max-width} - #{$min-width}))),
    #{$max-size}px
  );
}

// Usage
.title {
  @include fluid-font(18, 32);
}

.search-box {
  @include glass-effect;
  padding: $spacing-md;
  border-radius: $border-radius-lg;
}

.post-excerpt {
  @include text-truncate(3);
}

.chat-window {
  max-height: 400px;
  overflow-y: auto;
  @include custom-scrollbar;
}

6. Functions

SASS menyediakan banyak built-in functions dan juga memungkinkan kamu membuat custom functions menggunakan @function.

Built-in Color Functions

SCSS
$primary: #3498db;

// Lighten & Darken
.light-bg  { background: lighten($primary, 30%); }
.dark-bg   { background: darken($primary, 20%); }

// Saturate & Desaturate
.vivid     { color: saturate($primary, 20%); }
.muted     { color: desaturate($primary, 30%); }

// Opacity
.semi-transparent { background: rgba($primary, 0.5); }
// Atau gunakan transparentize / opacify
.faded    { background: transparentize($primary, 0.3); }
.opaque   { background: opacify(rgba($primary, 0.2), 0.5); }

// Mix / blend colors
.blended  { background: mix($primary, $danger, 70%); } // 70% primary + 30% danger

// Complementary
.complement { color: complement($primary); } // Warna yang berlawanan di color wheel

// Grayscale
.gray-version { filter: grayscale(100%); }

// Color adjustments
.adjusted {
  color: adjust-hue($primary, 30deg); // Putar hue
  background: scale-color($primary, $lightness: -20%); // Skala lightness
}

Built-in Math Functions

SCSS
// Math functions
$base-spacing: 16px;

.element-1 { margin: abs(-20px); }          // 20px
.element-2 { padding: ceil(15.3px); }       // 16px
.element-3 { width: floor(99.9px); }        // 99px
.element-4 { max-width: max(100px, 50vw); } // larger value
.element-5 { min-width: min(300px, 90vw); } // smaller value
.element-6 { z-index: round(4.6); }         // 5
.element-7 { width: percentage(3/4); }      // 75%

// Random
$lucky-number: random(100); // Random number 1-100
$random-unit: random() + 0px; // Random length

// Unit functions
$px-value: 16px;
.element { font-size: unitless($px-value); } // 16
.element { font: unit(20, px); }             // 20px
.element { width: comparable(10px, 20px); }  // true (sama unit-nya)

Custom Functions

SCSS
// Custom function: menghitung spacing berdasarkan multiplier
@function spacing($multiplier) {
  @return $spacing-md * $multiplier;
}

// Custom function: shade color
@function shade($color, $percentage) {
  @return mix(black, $color, $percentage);
}

// Custom function: tint color
@function tint($color, $percentage) {
  @return mix(white, $color, $percentage);
}

// Custom function: strip unit
@function strip-unit($value) {
  @return $value / ($value * 0 + 1);
}

// Custom function: menghitung rem dari pixel
@function to-rem($px, $base: 16) {
  @return ($px / $base) * 1rem;
}

// Custom function: responsive value
@function responsive-value($min, $max, $min-vw: 320px, $max-vw: 1200px) {
  @return calc(#{$min} + #{strip-unit($max) - strip-unit($min)} * (100vw - #{$min-vw}) / #{strip-unit($max-vw) - strip-unit($min-vw)});
}

// Usage
.section {
  padding: spacing(2);          // 32px
  margin: spacing(3) spacing(1); // 48px 16px
  font-size: to-rem(24);        // 1.5rem
  min-height: responsive-value(200px, 400px);
}

.alert {
  background: tint($danger, 90%);   // Light red
  border-left: 4px solid shade($danger, 20%); // Dark red
  color: shade($danger, 30%);
}

7. Partials & Import

Partials adalah file SCSS yang namanya dimulai dengan underscore (_). Partials tidak dikompilasi menjadi file CSS terpisah — mereka hanya di-import ke file utama. Ini memungkinkan kamu membagi CSS menjadi file-file kecil yang terorganisir.

Struktur Folder

Text
src/scss/
  main.scss              ← File utama (kompilasi dari sini)
  _variables.scss        ← Variabel global
  _mixins.scss           ← Mixins
  _functions.scss        ← Custom functions
  _reset.scss            ← CSS reset
  _typography.scss       ← Tipografi
  _base.scss             ← Base styles
  components/
    _button.scss         ← Komponen button
    _card.scss           ← Komponen card
    _form.scss           ← Komponen form
    _navbar.scss         ← Komponen navbar
    _modal.scss          ← Komponen modal
    _alert.scss          ← Komponen alert
  layout/
    _header.scss         ← Header
    _footer.scss         ← Footer
    _sidebar.scss        ← Sidebar
    _grid.scss           ← Grid system
    _container.scss      ← Container
  pages/
    _home.scss           ← Halaman home
    _about.scss          ← Halaman about
    _contact.scss        ← Halaman contact
  utils/
    _helpers.scss        ← Utility classes
    _animations.scss     ← Animations
    _responsive.scss     ← Responsive mixins

File Utama (main.scss)

SCSS
// main.scss — File utama yang mengimport semua partials

// 1. Utilities (paling dasar)
@import 'functions';
@import 'variables';
@import 'mixins';
@import 'utils/helpers';

// 2. Reset & Base
@import 'reset';
@import 'base';
@import 'typography';

// 3. Layout
@import 'layout/container';
@import 'layout/grid';
@import 'layout/header';
@import 'layout/footer';
@import 'layout/sidebar';

// 4. Components
@import 'components/button';
@import 'components/card';
@import 'components/form';
@import 'components/navbar';
@import 'components/modal';
@import 'components/alert';

// 5. Pages
@import 'pages/home';
@import 'pages/about';
@import 'pages/contact';

// 6. Animations & Responsive
@import 'utils/animations';
@import 'utils/responsive';
💡 Tips

Dengan SASS modern, @import sedang di-deprecate. Gunakan @use dan @forward sebagai penggantinya untuk menghindari masalah namespace dan scope.

@use dan @forward (Modern)

SCSS
// _variables.scss — dengan namespace
$primary: #3498db;
$danger: #e74c3c;
$spacing-md: 16px;

// _button.scss — menggunakan @use
@use 'variables' as vars;

.button {
  background: vars.$primary;
  padding: vars.$spacing-md;

  &-danger {
    background: vars.$danger;
  }
}

// _index.scss — menggunakan @forward untuk re-export
@forward 'variables';
@forward 'mixins';
@forward 'functions';

// main.scss — import dari index
@use 'utils';
@use 'components/button';
@use 'layout/grid';

8. Inheritance (@extend)

@extend memungkinkan sebuah selector mewarisi semua style dari selector lain. Berbeda dari mixin yang menyalin kode, @extend menggabungkan selector untuk menghasilkan CSS yang lebih efisien.

SCSS
// Base message style
.message {
  padding: $spacing-md;
  border-radius: $border-radius-md;
  font-size: $font-size-sm;
  border: 1px solid transparent;
}

// Mewarisi semua style dari .message
.success-message {
  @extend .message;
  background-color: lighten($secondary, 40%);
  border-color: $secondary;
  color: darken($secondary, 20%);
}

.error-message {
  @extend .message;
  background-color: lighten($danger, 35%);
  border-color: $danger;
  color: darken($danger, 20%);
}

.warning-message {
  @extend .message;
  background-color: lighten($warning, 35%);
  border-color: $warning;
  color: darken($warning, 25%);
}

// Placeholder selector (%) — tidak menghasilkan CSS sendiri
%dark-card {
  background: $dark;
  color: $light;
  padding: $spacing-lg;
  border-radius: $border-radius-lg;
  box-shadow: $shadow-lg;
}

.profile-card {
  @extend %dark-card;
  text-align: center;
}

.stats-card {
  @extend %dark-card;
  display: flex;
  justify-content: space-between;
}

// Output CSS yang dihasilkan:
// .message, .success-message, .error-message, .warning-message {
//   padding: 16px;
//   border-radius: 8px;
//   font-size: 0.875rem;
//   border: 1px solid transparent;
// }
// .success-message { background-color: ...; border-color: ...; }
// .error-message { background-color: ...; border-color: ...; }
// .profile-card, .stats-card { background: #2c3e50; color: #ecf0f1; ... }

@extend vs @mixin

Aspek @extend @mixin
Cara kerja Group selectors Copy-paste CSS
File size Lebih kecil Bisa lebih besar
Parameters Tidak bisa Bisa
@content Tidak bisa Bisa
Cross-scope Bisa bermasalah di @media Aman di @media

9. Control Flow

SASS mendukung kontrol alur (@if, @for, @each, @while) yang memungkinkan logika programming di dalam stylesheet.

@if / @else

SCSS
// Mixin dengan conditional
@mixin theme-color($theme: 'light') {
  @if $theme == 'light' {
    background-color: $white;
    color: $dark;
  } @else if $theme == 'dark' {
    background-color: $dark;
    color: $light;
  } @else {
    background-color: transparent;
    color: inherit;
  }
}

// Conditional sizing
@mixin size($width, $height: null) {
  width: $width;

  @if $height == null {
    height: $width; // Square
  } @else {
    height: $height;
  }
}

.avatar {
  @include size(48px);          // 48x48 square
}

.banner {
  @include size(100%, 200px);   // full width, 200px height
}

@for Loop

SCSS
// @for: 1 sampai 12 (inclusive)
@for $i from 1 through 12 {
  .col-#{$i} {
    width: percentage($i / 12);
    flex: 0 0 percentage($i / 12);
  }
}

// Output:
// .col-1  { width: 8.33%;  flex: 0 0 8.33%; }
// .col-2  { width: 16.66%; flex: 0 0 16.66%; }
// ...
// .col-12 { width: 100%;   flex: 0 0 100%; }

// @for: 1 sampai 5 (exclusive, berhenti di 4)
@for $i from 1 through 5 {
  .mt-#{$i} {
    margin-top: $i * $spacing-sm;
  }

  .mb-#{$i} {
    margin-bottom: $i * $spacing-sm;
  }

  .p-#{$i} {
    padding: $i * $spacing-sm;
  }
}

// Generate shadow levels
@for $i from 1 through 5 {
  .shadow-#{$i} {
    box-shadow: 0 #{$i}px #{$i * 3}px rgba(0, 0, 0, #{$i * 0.05});
  }
}

@each Loop

SCSS
// @each: iterate over list
$colors: primary, secondary, danger, warning, info;

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

  .bg-#{$color} {
    background-color: $#{color};
  }

  .border-#{$color} {
    border-color: $#{color};
  }
}

// @each dengan map
$social-colors: (
  'facebook': #1877f2,
  'twitter': #1da1f2,
  'instagram': #e4405f,
  'linkedin': #0a66c2,
  'github': #333333,
  'youtube': #ff0000,
);

@each $name, $color in $social-colors {
  .social-#{$name} {
    background-color: $color;
    color: white;

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

  .icon-#{$name} {
    color: $color;
  }
}

// @each dengan destructuring
$sizes: (sm: 0.875rem, md: 1rem, lg: 1.25rem, xl: 1.5rem);

@each $name, $size in $sizes {
  .text-#{$name} {
    font-size: $size;
  }
}

@while Loop

SCSS
// @while: loop sampai kondisi false
$z-index: 1;

@while $z-index <= 10 {
  .z-#{$z-index} {
    z-index: $z-index;
  }
  $z-index: $z-index + 1;
}

// Generate Fibonacci spacing
$a: 0;
$b: 1;
$n: 1;

@while $n <= 8 {
  $temp: $a + $b;
  .space-fib-#{$n} {
    margin: #{$temp}px;
  }
  $a: $b;
  $b: $temp;
  $n: $n + 1;
}

10. Quiz Pemahaman

Uji pemahamanmu tentang SASS/SCSS:

Pertanyaan 1: Apa perbedaan utama antara .sass dan .scss?

a) .sass lebih cepat dari .scss
b) .scss menggunakan kurung {} dan titik koma ; seperti CSS, .sass menggunakan indentasi
c) .sass hanya untuk mobile
d) Tidak ada perbedaan

Pertanyaan 2: Apa fungsi dari & (ampersand) di SCSS?

a) Mendefinisikan variabel
b) Merujuk ke parent selector
c) Mengimpor file
d) Membuat loop

Pertanyaan 3: Perbedaan antara @mixin dan @extend?

a) @mixin copy-paste CSS, @extend group selectors
b) @mixin lebih efisien dari @extend
c) Sama saja
d) @extend bisa menerima parameter

Pertanyaan 4: Apa fungsi dari partial (file dengan _ di depan)?

a) File yang otomatis dikompilasi ke CSS
b) File yang hanya di-import, tidak menghasilkan CSS file sendiri
c) File yang hanya berisi variabel
d) File yang tidak bisa di-import

Pertanyaan 5: Mana yang lebih disarankan untuk digunakan modern — @import, @use, atau @forward?

a) @import
b) @use dan @forward
c) Ketiganya sama
d) Tidak perlu import
🔍 Zoom
100%
🎨 Tema