SCSS Variables and Data Types
1. Variable Declaration ($variable: value) Syntax
| Concept | Syntax | Example | Notes |
|---|---|---|---|
| Basic Declaration | $variable-name: value; |
$primary-color: #3498db; |
Use hyphen or underscore naming |
| Variable Usage | property: $variable-name; |
color: $primary-color; |
Reference declared variable |
| Naming Convention | $kebab-case |
$btn-primary-bg |
Recommended: lowercase with hyphens |
| Underscore Equivalence | $var-name === $var_name |
$main-color = $main_color |
Hyphens and underscores are interchangeable |
| Reassignment | $var: new-value; |
$size: 20px; |
Variables can be reassigned |
| Required Prefix | Must start with $ |
$font-size ✓ |
font-size ✗ (invalid variable) |
Example: Variable declaration and usage
// Color variables
$primary-color: #3498db;
$secondary-color: #2ecc71;
$text-color: #333;
// Spacing variables
$spacing-unit: 8px;
$margin-base: $spacing-unit * 2;
// Typography
$font-primary: 'Helvetica', sans-serif;
$font-size-base: 16px;
// Usage
.button {
background: $primary-color;
color: white;
font-family: $font-primary;
margin: $margin-base;
&:hover {
background: $secondary-color;
}
}
2. Variable Scope (global, local, !global flag)
| Scope Type | Definition Location | Accessibility | Example |
|---|---|---|---|
| Global Scope | Top-level (outside blocks) | Accessible everywhere | $global-var: value; |
| Local Scope | Inside { } blocks |
Only within that block | .class { $local: value; } |
| !global Flag | Inside block with flag | Creates/modifies global variable | $var: value !global; |
| Shadowing | Local var with same name | Local overrides in scope | Global $x shadowed by local $x |
| Function Scope | Inside @function | Isolated to function | @function { $local: 1; } |
| Mixin Scope | Inside @mixin | Isolated to mixin | @mixin { $local: 1; } |
Example: Variable scope demonstration
// Global variable
$color: red;
.component {
// Local variable (only in this block)
$local-color: blue;
color: $local-color; // blue
background: $color; // red (global)
}
.another {
color: $color; // red (global accessible)
// color: $local-color; // ERROR: undefined
}
// Modifying global from local scope
.modifier {
$color: green !global; // Changes global $color
}
.test {
color: $color; // green (global was modified)
}
// Shadowing example
$size: 10px;
.shadow {
$size: 20px; // Local, shadows global
font-size: $size; // 20px (local)
.nested {
font-size: $size; // 20px (parent local)
}
}
.no-shadow {
font-size: $size; // 10px (global)
}
Warning: Use
!global sparingly. It can lead to unexpected side effects and makes
code harder to maintain.
3. Variable Interpolation #{ } Syntax
| Use Case | Syntax | Example | Output |
|---|---|---|---|
| Selector Interpolation | .#{$var} { } |
$name: 'header';.#{$name} { } |
.header { } |
| Property Interpolation | #{$var}: value; |
#{$prop}: 10px; |
margin: 10px; |
| String Interpolation | "text #{$var}" |
"font-#{$weight}" |
"font-bold" |
| URL Interpolation | url(#{$var}) |
url(#{$path}/img.png) |
url(/assets/img.png) |
| Media Query | @media #{$query} |
@media #{$mobile} |
@media (max-width: 768px) |
| At-rule Names | @#{$rule} |
@#{$directive} |
Dynamic directive names |
| Comment Interpolation | /* #{$var} */ |
/* v#{$version} */ |
/* v2.1.0 */ |
Example: Variable interpolation patterns
$theme: 'dark';
$side: 'left';
$size: 'large';
// Selector interpolation
.button-#{$theme} {
background: black;
}
// Output: .button-dark { background: black; }
// Property interpolation
.box {
margin-#{$side}: 20px;
}
// Output: .box { margin-left: 20px; }
// String interpolation
$base-path: '/assets/images';
.icon {
background: url('#{$base-path}/icon.svg');
}
// Dynamic class generation
@each $sz in small, medium, large {
.btn-#{$sz} {
padding: #{$sz};
}
}
// Media query interpolation
$breakpoint: '(min-width: 768px)';
@media #{$breakpoint} {
.container { width: 750px; }
}
// Combining variables
$prefix: 'app';
$component: 'header';
.#{$prefix}-#{$component} {
// .app-header
}
Note: Interpolation with
#{} is required for
selectors and property names, but optional for values.
4. Default Values (!default flag) and Overrides
| Concept | Syntax | Behavior | Use Case |
|---|---|---|---|
| Default Assignment | $var: value !default; |
Only assigns if variable is undefined or null | Library/framework configuration |
| Already Defined | $var: 10px; $var: 20px !default; |
$var remains 10px |
User overrides preserved |
| Undefined Variable | $new: 5px !default; |
$new is set to 5px |
Provides fallback value |
| Null Override | $var: null; $var: 5px !default; |
$var becomes 5px |
Null is treated as undefined |
| Import Order | User vars → Library defaults | User configuration takes priority | Configurable frameworks |
| Module Config | With @use...with |
Configure module variables | Modern module system NEW |
Example: !default flag usage
// _library.scss (component library)
$primary-color: blue !default;
$spacing: 8px !default;
$border-radius: 4px !default;
.button {
background: $primary-color;
padding: $spacing;
border-radius: $border-radius;
}
// user-config.scss (user customization)
// Set BEFORE importing library
$primary-color: red;
$spacing: 12px;
// $border-radius not set, will use default
@import 'library';
// Result: red background, 12px padding, 4px radius
// ===================================
// Pattern: Configurable mixin
@mixin button($bg: null, $padding: null) {
$bg: $bg or $primary-color !default;
$padding: $padding or $spacing !default;
background: $bg;
padding: $padding;
}
// Modern module system
// _theme.scss
$color: blue !default;
// main.scss
@use 'theme' with (
$color: red // Override default
);
Note:
!default is essential for creating configurable
libraries and themeable components.
5. Data Types (numbers, strings, colors, booleans, lists, maps, null)
| Data Type | Examples | Operations | Notes |
|---|---|---|---|
| Number | 42, 3.14, 10px, 2em |
+, -, *, /, %, <, >, comparisons | Can have units or be unitless |
| String | "text", 'text', unquoted |
Concatenation (+), interpolation | Quoted or unquoted |
| Color | #fff, rgb(), hsl(), red |
Color functions (lighten, darken, mix) | Multiple format support |
| Boolean | true, false |
and, or, not, if/else | Conditional logic |
| Null | null |
Represents absence of value | Omits property in output |
| List | 1px 2px 3px, (a, b, c) |
List functions (nth, join, append) | Space or comma separated |
| Map | (key: value, key2: value2) |
Map functions (get, merge, keys) | Key-value pairs |
| Function Reference | get-function('name') |
First-class functions | Advanced meta-programming |
Example: Variable data types
// Numbers
$width: 100; // Unitless
$height: 50px; // With unit
$opacity: 0.75; // Decimal
$duration: 2s; // Time unit
// Strings
$font-quoted: "Helvetica"; // Quoted
$font-unquoted: Arial; // Unquoted
$path: '/assets/images'; // Path string
// Colors
$color-hex: #3498db;
$color-rgb: rgb(52, 152, 219);
$color-rgba: rgba(52, 152, 219, 0.8);
$color-hsl: hsl(204, 70%, 53%);
$color-name: blue;
// Booleans
$is-dark-mode: true;
$is-mobile: false;
// Null
$optional-border: null; // Won't output
// Lists
$margins: 10px 20px 10px 20px;
$colors: red, green, blue;
$mixed: (1px solid black);
// Maps
$theme: (
primary: #3498db,
secondary: #2ecc71,
text: #333
);
// Usage examples
.box {
width: $width + px; // 100px
border: $optional-border; // Omitted (null)
@if $is-dark-mode {
background: black;
}
}
6. CSS Custom Properties (--var) vs SCSS Variables ($var)
| Feature | SCSS Variables ($var) | CSS Custom Properties (--var) |
|---|---|---|
| Compilation | Compiled away (preprocessor) | Present in final CSS (runtime) |
| Syntax | $variable: value; |
--variable: value; |
| Usage | color: $variable; |
color: var(--variable); |
| Scope | Static, compile-time | Dynamic, cascade and inherit |
| Browser Support | All (compiled to CSS) | Modern browsers (IE11- not supported) |
| JavaScript Access | Not accessible | Can read/modify via JS NEW |
| Media Query Context | Can use different values | Inherits from cascade |
| Calculations | Compile-time only | Can use calc() at runtime |
| Fallback | N/A (value required) | var(--x, fallback) |
| Performance | No runtime cost | Slight runtime overhead |
Example: SCSS variables vs CSS custom properties
// SCSS Variables (compile-time)
$primary: #3498db;
$spacing: 16px;
.button {
background: $primary; // Compiled to: background: #3498db;
padding: $spacing; // Compiled to: padding: 16px;
}
// CSS Custom Properties (runtime)
:root {
--primary: #3498db;
--spacing: 16px;
}
.button {
background: var(--primary); // Stays in CSS
padding: var(--spacing); // Can change at runtime
}
// ===================================
// Combining Both (Best Practice)
$default-primary: #3498db;
:root {
--primary: #{$default-primary}; // SCSS sets initial value
--spacing: 16px;
}
.button {
background: var(--primary);
// JavaScript can change:
// element.style.setProperty('--primary', 'red');
}
// ===================================
// Theme switching with CSS variables
.theme-light {
--bg: white;
--text: black;
}
.theme-dark {
--bg: black;
--text: white;
}
.component {
background: var(--bg);
color: var(--text);
// Theme switches without recompiling!
}
// SCSS variables for theme
$themes: (
light: (bg: white, text: black),
dark: (bg: black, text: white)
);
@each $theme, $colors in $themes {
.theme-#{$theme} {
--bg: #{map-get($colors, bg)};
--text: #{map-get($colors, text)};
}
}
When to Use Which?
| Use SCSS Variables | Use CSS Custom Properties |
|---|---|
| Build-time configuration | Runtime theming |
| Calculations during compilation | Dynamic value changes |
| Internal component logic | JavaScript interaction |
| Mixin/function parameters | User customization |
| Older browser support needed | Modern cascade features |
Note: Best practice: Use SCSS variables for compile-time values
and CSS custom properties for runtime theming. Combine both for maximum flexibility.