Variables, nesting, mixins, functions & modules
CSS// SCSS syntax (superset of CSS)
// File extension: .scss
// Compile: sass input.scss output.css
// Install
npm install -g sass
// or
brew install sass/sass/sass
// Watch mode
sass --watch input.scss:output.css
sass --watch src/scss:dist/css// Nesting selectors
.nav {
background: #333;
ul {
list-style: none;
}
li {
display: inline-block;
}
a {
color: white;
&:hover { // & = parent selector
color: #0af;
}
&.active {
font-weight: bold;
}
}
}
// Property nesting
.box {
border: {
width: 1px;
style: solid;
color: #ccc;
}
}// Variables with $
$primary: #3498db;
$font-stack: 'Inter', sans-serif;
$spacing: 16px;
$radius: 8px;
body {
font-family: $font-stack;
color: $primary;
}
.card {
padding: $spacing;
border-radius: $radius;
margin-bottom: $spacing * 2;
}
// Maps
$colors: (
primary: #3498db,
danger: #e74c3c,
success: #2ecc71,
);
.btn {
background: map-get($colors, primary);
}// Define mixin
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
// Use mixin
.hero {
@include flex-center;
height: 100vh;
}
// Mixin with parameters
@mixin button($bg, $color: white) {
background: $bg;
color: $color;
padding: 10px 20px;
border: none;
border-radius: 4px;
}
.btn-primary { @include button(#3498db); }
.btn-danger { @include button(#e74c3c); }
// Content block
@mixin responsive($bp) {
@media (min-width: $bp) { @content; }
}
.box { @include responsive(768px) { width: 50%; } }// Extend
.message {
padding: 10px;
border: 1px solid #ccc;
}
.success { @extend .message; color: green; }
.error { @extend .message; color: red; }
// Placeholder selector (not compiled on its own)
%btn-base {
padding: 10px 20px;
border: none;
cursor: pointer;
}
.btn { @extend %btn-base; }
.btn-lg { @extend %btn-base; font-size: 1.2rem; }// Custom function
@function rem($px) {
@return $px / 16 * 1rem;
}
h1 { font-size: rem(32); } // 2rem
// Built-in functions
darken($color, 10%)
lighten($color, 10%)
mix($c1, $c2, 50%)
rgba($color, 0.5)
complement($color)
percentage(0.5) // 50%
round(4.6) // 5
if($condition, $a, $b)// Conditionals
@if $theme == dark {
background: #111;
} @else if $theme == light {
background: #fff;
} @else {
background: #888;
}
// Each loop
$sizes: sm, md, lg;
@each $size in $sizes {
.text-#{$size} { font-size: #{$size}; }
}
// For loop
@for $i from 1 through 12 {
.col-#{$i} { width: 100% / 12 * $i; }
}
// While loop
$i: 1;
@while $i <= 5 {
.mt-#{$i} { margin-top: $i * 8px; }
$i: $i + 1;
}// @use (modern, recommended)
@use 'variables';
@use 'mixins';
.box {
color: variables.$primary;
@include mixins.flex-center;
}
// Namespace alias
@use 'variables' as v;
color: v.$primary;
// @forward (re-export)
@forward 'variables';
@forward 'mixins';
// Partial files (underscore prefix)
// _variables.scss — won't compile alone
// @use 'variables' — imports _variables.scss