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 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?
- 🎨 Variabel — Simpan warna, ukuran, dan nilai yang sering digunakan
- 📦 Nesting — Struktur CSS yang lebih rapi dan terorganisir
- 🔧 Mixins — Reusable code blocks untuk pola CSS yang sering dipakai
- 📐 Functions — Buat fungsi untuk menghitung nilai CSS
- 📂 Partials — Pisahkan CSS ke file-file kecil yang modular
- 🧬 Inheritance — Bagikan style antar selector dengan @extend
- 🔄 Control Flow — Logika @if, @else, @for, @each, @while
2. Instalasi & Setup
Instalasi SASS
# Instal global npm install -g sass # Atau instal sebagai dev dependency npm install -D sass # Cek versi sass --version
Kompilasi SCSS ke CSS
# 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
# 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
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
// ===== 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
// 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)
$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 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
.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
// 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;
// ...
// }
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
// 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
// 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
// @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
// 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
$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
// 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
// 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
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)
// 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';
Dengan SASS modern, @import sedang di-deprecate. Gunakan @use dan @forward sebagai penggantinya untuk menghindari masalah namespace dan scope.
@use dan @forward (Modern)
// _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.
// 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
// 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
// @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
// @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
// @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: