CSS preprocessors extend CSS with variables, nesting, mixins, functions, and more. They compile into standard CSS that browsers can understand. SASS (Syntactically Awesome Style Sheets) is the most popular preprocessor.
SASS is a CSS preprocessor that adds programming-like features to CSS. It helps you write cleaner, more maintainable, and reusable stylesheets. SASS files end in .scss (modern syntax) or .sass (indented syntax).
Uses braces and semicolons — just like regular CSS. Any valid CSS is valid SCSS.
.card {
background: #fff;
border-radius: 8px;
padding: 16px;
}
Uses indentation instead of braces and semicolons.
.card
background: #fff
border-radius: 8px
padding: 16px
.scss. It's closer to regular CSS and has better tooling support. You can always try the indented syntax later.
Store values like colors, fonts, and sizes in variables and reuse them throughout your stylesheet.
$primary: #3b82f6;
$secondary: #8b5cf6;
$font-stack: 'Segoe UI', sans-serif;
$padding-base: 16px;
.button {
background: $primary;
font-family: $font-stack;
padding: $padding-base $padding-base * 2;
}
.button--secondary {
background: $secondary;
}
Nest selectors inside one another to mirror the HTML structure.
.card {
background: #fff;
border-radius: 8px;
padding: 16px;
.card__title {
font-size: 1.25rem;
font-weight: 700;
}
.card__body {
color: #64748b;
line-height: 1.6;
}
/* Use & to reference the parent */
&:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
}
Split your styles into partial files (starting with _) and import them.
// _variables.scss
$primary: #3b82f6;
$secondary: #8b5cf6;
// _buttons.scss
.button { background: $primary; }
// main.scss (@use is the modern replacement for @import)
@use 'variables';
@use 'buttons';
// @import still works but is deprecated
// @import 'variables';
Mixins let you define reusable blocks of styles. They can accept arguments.
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
@mixin respond-to($breakpoint) {
@if $breakpoint == tablet {
@media (min-width: 768px) { @content; }
} @else if $breakpoint == desktop {
@media (min-width: 1024px) { @content; }
}
}
.navbar {
@include flex-center;
}
.sidebar {
@include respond-to(tablet) {
width: 250px;
}
}
$base-size: 16px;
@function rem($px) {
@return $px / $base-size * 1rem;
}
.heading {
font-size: rem(32); /* outputs 2rem */
}
// Built-in color functions
.notification {
background: $primary;
border: 1px solid darken($primary, 10%);
color: lighten($primary, 60%);
}
Share styles between selectors to avoid duplication.
%message-shared {
padding: 12px;
border-radius: 4px;
font-weight: 500;
}
.success { @extend %message-shared; background: #22c55e; }
.error { @extend %message-shared; background: #ef4444; }
.warning { @extend %message-shared; background: #eab308; }
// Arithmetic
$width: 200px;
.half { width: $width / 2; }
.double { width: $width * 2; }
// Color operations
$brand: #3b82f6;
.darker { color: $brand - #222; }
.lighter { color: $brand + #444; }
npm install -g sass, then run sass input.scss output.css or use a build tool like Vite or Webpack that handles it automatically.
_variables.scss partial for colors and fonts, a _mixins.scss partial with a responsive mixin, and a main.scss that uses both. Compile it to CSS and verify the output.