1.7 — Working With SASS: Quick Revision
Compact cheat sheet. Print-friendly.
How to use this material (instructions)
- Skim top-to-bottom in one pass before interviews or exams.
- If a row feels fuzzy — reopen the matching lesson:
README.md → 1.7.a…1.7.i.
- Drills —
1.7-Exercise-Questions.md.
- Polished answers —
1.7-Interview-Questions.md.
1.7.a What Is SASS
Core Concept
You write SCSS ──► Compiler (Dart Sass) ──► Plain CSS ──► Browser
(build time) (zero runtime cost)
Key Features
| Feature | One-liner |
|---|
| Variables | $name: value; — single source of truth for colors, spacing, fonts |
| Nesting | Write child selectors inside parent blocks; & for pseudo-classes |
| Mixins | Reusable declaration blocks — @mixin / @include |
| Functions | Compute and @return values — used inline in properties |
| Partials | _file.scss — split code into small files, combine at build |
| Operators | Math, comparison, logical operators inside stylesheets |
| Control flow | @if, @for, @each, @while — generate CSS programmatically |
| Inheritance | @extend / %placeholder — group selectors sharing rules |
Compiler Timeline
| Year | Event |
|---|
| 2006 | SASS created (Ruby, indented syntax) |
| 2009 | SCSS syntax introduced |
| 2016 | Dart Sass becomes reference implementation |
| 2019 | @use / @forward module system |
| 2022 | LibSass and Node Sass deprecated |
1.7.b SCSS vs SASS Syntax & Setup
Syntax Comparison
| SCSS | Indented SASS |
|---|
| Braces | { } required | None — indentation |
| Semicolons | Required | None — newlines |
| CSS superset | Yes | No |
| File extension | .scss | .sass |
| Usage | ~95% of projects | Legacy only |
Setup Commands
npm install --save-dev sass
npx sass src/scss:dist/css --watch
npx sass src/scss:dist/css --style=compressed
Folder Structure (Simplified)
src/scss/
abstracts/ ← variables, mixins, functions
base/ ← reset, typography
components/ ← buttons, cards, modals
layout/ ← header, footer, grid
pages/ ← page-specific styles
main.scss ← entry point
1.7.c Variables & Nesting
Variables
$primary: #3b82f6;
$spacing: 1rem;
$font: 'Inter', sans;
$debug: false;
$nothing: null;
Data Types
Numbers · Strings · Colors · Booleans · Null · Lists · Maps
Variable Flags
| Flag | Effect |
|---|
!default | Use value only if not already defined |
!global | Force local variable to global scope (avoid) |
Nesting & &
.btn {
background: $primary;
&:hover { background: darken($primary, 10%); }
&--large { padding: 1rem 2rem; }
&__icon { margin-right: 0.5rem; }
}
Rule: Max 3 levels deep.
SCSS Variables vs CSS Custom Properties
| Dimension | $var | --var |
|---|
| Resolved | Compile time | Runtime |
| Cascade | No | Yes |
| JS access | No | Yes |
| Dynamic | No (recompile) | Yes |
1.7.d Partials & Imports
Partials
- File name starts with
_: _variables.scss
- Never compiled alone — pulled in by entry file
@use (Modern)
@use 'abstracts/variables';
@use 'abstracts/variables' as vars;
@use 'abstracts/variables' as *;
@forward (Re-export)
@forward 'variables';
@forward 'mixins';
@forward 'functions' hide _private;
@import (Deprecated)
@import problem | @use fix |
|---|
| Global scope pollution | Namespacing |
| Duplicate output | Single-load guarantee |
| No visibility control | @forward show/hide |
7-1 Pattern
abstracts/ · base/ · components/ · layout/ · pages/ · themes/ · vendors/ + main.scss
1.7.e Mixins
Syntax
@mixin name($arg1, $arg2: default) {
property: $arg1;
other: $arg2;
}
.element { @include name(value1); }
@content Blocks
@mixin breakpoint($bp) {
@media (min-width: $bp) { @content; }
}
.sidebar {
width: 100%;
@include breakpoint(768px) { width: 250px; }
}
Common Mixins
| Mixin | Purpose |
|---|
flex-center | Flexbox centering (3 properties) |
breakpoint($name) | Responsive media query wrapper |
truncate($lines) | Text overflow ellipsis |
visually-hidden | Accessible screen-reader-only hide |
Mixin vs Function vs Extend
| Mixin | Function | Extend |
|---|
| Produces | Declarations | Value | Grouped selectors |
| Arguments | Yes | Yes | No |
@content | Yes | No | No |
| Media queries | Works | N/A | Fails |
1.7.f Inheritance & Extends
Placeholder Selectors
%btn-base {
padding: 0.5rem 1rem;
border: none;
cursor: pointer;
}
.btn-primary { @extend %btn-base; background: blue; }
.btn-danger { @extend %btn-base; background: red; }
Pitfalls
| Pitfall | Cause |
|---|
| Unexpected selectors | Extending a class extends it in all compound selectors |
| Media query error | Cannot extend across @media boundaries |
| Selector bloat | Many extends → enormous comma-separated selectors |
Default choice: Mixins. Use extend with %placeholder only for small, static shared bases.
1.7.g Functions & Operators
Custom Function
@use 'sass:math';
@function rem($px, $base: 16) {
@return math.div($px, $base) * 1rem;
}
h1 { font-size: rem(32); }
Operators
| Type | Operators |
|---|
| Arithmetic | +, -, *, math.div(), % |
| Comparison | ==, !=, <, >, <=, >= |
| Logical | and, or, not |
| String | + (concatenation), #{} (interpolation) |
Built-in Modules
| Module | Key functions |
|---|
sass:math | math.div(), math.round(), math.ceil(), math.clamp(), math.abs() |
sass:color | color.adjust(), color.scale(), color.change(), color.mix() |
sass:list | list.append(), list.nth(), list.length(), list.join() |
sass:map | map.get(), map.merge(), map.keys(), map.values(), map.has-key() |
sass:string | string.to-upper-case(), string.slice(), string.index() |
sass:meta | meta.type-of(), meta.inspect() |
1.7.h Control Directives
@if / @else
@if $theme == 'dark' {
background: #1e293b;
} @else {
background: #fff;
}
@for
@for $i from 1 through 8 {
.mt-#{$i} { margin-top: $i * 0.25rem; }
}
@each (Lists & Maps)
$colors: ('primary': #3b82f6, 'danger': #ef4444);
@each $name, $color in $colors {
.bg-#{$name} { background: $color; }
}
@while (Rare)
$i: 6;
@while $i > 0 {
.w-#{$i} { width: $i * 100px; }
$i: $i - 1;
}
Best Practices
- Prefer
@each for named items, @for for numeric sequences
- Always check compiled CSS size — loops can explode
- Use maps as configuration data for
@each generation
1.7.i Color Functions
Legacy (Global)
| Function | Effect |
|---|
lighten($c, %) | Increase lightness |
darken($c, %) | Decrease lightness |
saturate($c, %) | Increase saturation |
desaturate($c, %) | Decrease saturation |
complement($c) | 180° hue rotation |
mix($a, $b, %) | Blend two colors |
rgba($c, alpha) | Set transparency |
Modern (sass:color)
| Function | Behavior |
|---|
color.adjust($c, $lightness: 20%) | Shift by fixed amount |
color.scale($c, $lightness: 20%) | Shift proportionally (toward max/min) |
color.change($c, $lightness: 90%) | Set absolute value |
color.mix($a, $b, 50%) | Blend (weight = % of first color) |
Palette Generation
@use 'sass:color';
$base: #3b82f6;
:root {
--blue-100: #{color.scale($base, $lightness: 80%)};
--blue-300: #{color.scale($base, $lightness: 40%)};
--blue-500: #{$base};
--blue-700: #{color.scale($base, $lightness: -40%)};
--blue-900: #{color.scale($base, $lightness: -70%)};
}
Accessibility
- Generated colors may fail WCAG contrast — always verify with a contrast checker
color.scale() is safer than color.adjust() for avoiding extreme results
- Define text colors explicitly for each shade — do not assume white/black will contrast
One-liner definitions (25+ terms)
| Term | One-liner |
|---|
| SASS | CSS preprocessor — adds variables, nesting, mixins, functions, logic; compiles to CSS. |
| SCSS | CSS-compatible SASS syntax using curly braces and semicolons. |
| Dart Sass | The only actively maintained SASS compiler (npm package: sass). |
| Partial | SCSS file starting with _ — not compiled alone, imported by entry file. |
@use | Modern import — loads file once, creates namespace, declares dependency. |
@forward | Re-exports members from one file through another (folder API). |
@import | Deprecated import — global scope, duplicate output, no namespacing. |
$variable | Compile-time value — resolved before CSS reaches the browser. |
!default | Set value only if not already defined — lets consumers override library defaults. |
| Nesting | Writing child selectors inside parent blocks to mirror HTML structure. |
& | Parent selector reference — used for pseudo-classes, BEM, modifiers. |
@mixin | Defines a reusable block of CSS declarations. |
@include | Stamps a mixin's declarations into a rule set. |
@content | Placeholder inside a mixin for injected CSS blocks. |
@extend | Shares rules by grouping selectors in compiled CSS. |
%placeholder | Abstract selector — exists only to be extended, no standalone output. |
@function | Computes and returns a value via @return. |
@return | Sends a value back from a function — required in every code path. |
math.div() | Division function replacing deprecated / operator. |
#{} | String interpolation — embeds variables in selectors, properties, media queries. |
@if | Conditional — emit CSS only when condition is true. |
@for | Numeric loop — through is inclusive, to is exclusive. |
@each | Iterate lists or maps — most versatile loop for named data. |
| 7-1 pattern | SCSS architecture: 7 folders + 1 entry file. |
| Source map | .css.map file linking compiled CSS back to original SCSS lines in DevTools. |
color.scale() | Proportional color adjustment — safer than fixed-amount color.adjust(). |
color.mix() | Blend two colors by weight — useful for tints and shades. |
Master workflow — The SASS Development Stack
- Install Dart Sass:
npm install --save-dev sass.
- Organize files: abstracts (variables, mixins, functions) → base → components → layout → pages.
- Wire files with
@use and @forward; create _index.scss per folder.
- Write SCSS:
$variables for values, @mixin for reusable blocks, @function for computed values.
- Nest sparingly (max 3 levels); use
& for pseudo-classes and BEM.
- Generate utilities with
@each / @for loops from maps.
- Manipulate colors with
color.scale() / color.mix() — verify contrast.
- Compile with
--watch in development, --style=compressed --no-source-map for production.
- Post-process with Autoprefixer, PurgeCSS, and cssnano in the build pipeline.
- Verify — diff compiled CSS, check file size, test accessibility.
End of 1.7 quick revision.