⏳
Loading cheatsheet...
Variables, nesting, mixins, functions, extends, control directives, modules, and responsive patterns.
// ── Variables ──
// Global variables (snake_case convention)
$primary-color: #3b82f6;
$primary-dark: #2563eb;
$secondary-color: #10b981;
$text-color: #1f2937;
$text-muted: #6b7280;
$bg-color: #ffffff;
$bg-dark: #111827;
$border-radius: 8px;
$font-family: 'Inter', system-ui, sans-serif;
$font-size-base: 16px;
$spacing-unit: 8px;
$max-width: 1200px;
$breakpoint-sm: 640px;
$breakpoint-md: 768px;
$breakpoint-lg: 1024px;
$breakpoint-xl: 1280px;
// ── Maps (key-value pairs) ──
$colors: (
'primary': #3b82f6,
'secondary': #10b981,
'success': #22c55e,
'warning': #f59e0b,
'danger': #ef4444,
'info': #06b6d4,
);
$font-sizes: (
'xs': 12px,
'sm': 14px,
'base': 16px,
'lg': 18px,
'xl': 20px,
'2xl': 24px,
'3xl': 30px,
);
$shadows: (
'sm': 0 1px 2px rgba(0, 0, 0, 0.05),
'md': 0 4px 6px rgba(0, 0, 0, 0.1),
'lg': 0 10px 15px rgba(0, 0, 0, 0.1),
'xl': 0 20px 25px rgba(0, 0, 0, 0.15),
);
// ── Nesting ──
.card {
background: $bg-color;
border-radius: $border-radius;
box-shadow: map-get($shadows, 'md');
padding: $spacing-unit * 3;
&__title {
font-size: map-get($font-sizes, 'xl');
color: $text-color;
margin-bottom: $spacing-unit;
}
&__body {
color: $text-muted;
line-height: 1.6;
}
&__footer {
margin-top: $spacing-unit * 2;
padding-top: $spacing-unit * 2;
border-top: 1px solid #e5e7eb;
}
// BEM variant modifier
&--large {
padding: $spacing-unit * 5;
}
&--highlighted {
border: 2px solid map-get($colors, 'primary');
}
// Pseudo-classes
&:hover {
box-shadow: map-get($shadows, 'lg');
transform: translateY(-2px);
}
&:active {
transform: translateY(0);
}
// Parent selector with modifier
&.is-active {
border-color: map-get($colors, 'success');
background: #f0fdf4;
}
}
// ── Nested Properties ──
.nav-link {
font: {
family: $font-family;
size: map-get($font-sizes, 'sm');
weight: 500;
}
text: {
decoration: none;
transform: uppercase;
}
}| Type | Example | Description |
|---|---|---|
| Numbers | $count: 10 | Integers and floats |
| Strings | $name: "value" or $name: value | With or without quotes |
| Colors | $c: #fff, rgb(), hsl() | Any CSS color value |
| Booleans | $is-active: true | true / false |
| Null | $val: null | Uninitialized variable |
| Lists | $sizes: 10px, 20px, 30px | Comma/space separated |
| Maps | $theme: (key: val) | Key-value pairs |
| Scope | Visibility |
|---|---|
| !default | Set only if not already defined |
| Global | Defined outside any {} block |
| Local | Defined inside {} block |
| !global | Override global from local scope |
// ── Mixins (include styles) ──
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
@mixin flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
@mixin responsive($breakpoint) {
@media (min-width: $breakpoint) {
@content;
}
}
@mixin 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;
}
}
@mixin button-variant($bg, $color: white) {
background-color: $bg;
color: $color;
border: none;
padding: 10px 20px;
border-radius: 6px;
font-weight: 500;
cursor: pointer;
transition: background-color 0.2s;
&:hover {
background-color: darken($bg, 10%);
}
&:active {
background-color: darken($bg, 15%);
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
// Usage
.btn {
@include button-variant(map-get($colors, 'primary'));
&--danger {
@include button-variant(map-get($colors, 'danger'));
}
}
.container {
max-width: $max-width;
margin: 0 auto;
padding: 0 $spacing-unit * 2;
@include responsive($breakpoint-md) {
padding: 0 $spacing-unit * 3;
}
}
.title {
@include truncate(2);
}
// ── Functions (return values) ──
@function px-to-rem($px) {
@return ($px / $font-size-base) * 1rem;
}
@function get-color($key) {
@return map-get($colors, $key);
}
@function strip-unit($value) {
@return ($value / ($value * 0 + 1));
}
// Built-in Functions
// darken(), lighten(), saturate(), desaturate(), adjust-hue()
// opacify(), transparentize(), mix(), complement(), invert()
// percentage(), round(), ceil(), floor(), abs()
// map-get(), map-keys(), map-values(), map-has-key(), map-merge()
// length(), nth(), append(), join(), index(), zip()
// type-of(), unit(), unitless(), comparable()// ── Partials (files starting with _ are not compiled to CSS) ──
// _variables.scss → partial, imported
// _mixins.scss → partial, imported
// _base.scss → partial, imported
// _buttons.scss → partial, imported
// ── Import Partials ──
// @use is the modern way (replaces @import)
@use 'variables' as *;
@use 'mixins' as *;
@use 'base';
@use 'components/buttons';
@use 'components/card';
@use 'layout/header';
@use 'layout/footer';
@use 'utilities/responsive';
// ── @use with namespace ──
@use 'colors' as palette;
.button {
background: palette.$primary;
color: palette.$text-light;
}
// ── @use with specific members ──
@use 'sizes' as s with ($sm, $md, $lg);
.container {
padding: s.$md;
font-size: s.$lg;
}
// ── @forward (re-export) ──
// _index.scss (barrel file)
@forward 'variables';
@forward 'mixins';
@forward 'functions';
@forward 'components';
// ── Placeholders (extend only, no output) ──
%visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
%sr-only {
@extend %visually-hidden;
}
.sr-text {
@extend %sr-only;
}
// ── Placeholder example ──
%btn-base {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 10px 20px;
border-radius: 6px;
font-weight: 500;
transition: all 0.2s;
cursor: pointer;
}
.btn-primary {
@extend %btn-base;
background: map-get($colors, 'primary');
color: white;
}
.btn-outline {
@extend %btn-base;
background: transparent;
border: 1px solid map-get($colors, 'primary');
color: map-get($colors, 'primary');
}| Feature | @use | @import (deprecated) |
|---|---|---|
| Namespace | Yes (as *) | No namespace |
| Variables | Available via namespace | Global leak |
| Members only | with () | Not supported |
| Deduplication | Once per file | Multiple times |
| Recommendation | Use @use | Avoid @import |
| Folder | Contents |
|---|---|
| abstracts/ | _variables, _mixins, _functions |
| base/ | _reset, _typography, _animations |
| components/ | _buttons, _card, _modal |
| layout/ | _header, _footer, _sidebar |
| pages/ | _home, _about, _contact |
| themes/ | _dark, _light |
| utilities/ | _responsive, _spacing |
@mixin includes the full CSS block wherever it is called, resulting in duplicated CSS rules.@extend groups selectors that share the same styles under one rule, reducing CSS output. Use @extend with placeholders (%) for style inheritance. Use @mixin when you need to pass arguments or include dynamic content.
@import makes all variables global, polluting the namespace and causing naming conflicts. It also re-imports the same file multiple times, increasing CSS size. @use loads each file only once, provides namespacing, and allows importing specific members. @forward is used to re-export members from barrel files for clean API surfaces.