← Back to Sass Mastery
Advanced14 min read

Migration & Modern CSS

Navigate the transition from Sass to modern CSS — migrate variables to custom properties, evaluate PostCSS alternatives, and decide when Sass still adds value.

Sass Variables to CSS Custom Properties

CSS custom properties are runtime values that cascade — Sass variables are compile-time only. Migrate theme values, dynamic properties, and anything JavaScript needs to read into custom properties.

Keep Sass variables for compile-time logic: breakpoint maps, spacing calculations, and loop-generated utilities. Use a hybrid approach where Sass generates custom property declarations.

  • CSS variables support runtime theme switching; Sass variables do not
  • Sass still adds value for loops, mixins, and compile-time math
  • Migrate incrementally — one component at a time
// Before: Sass only
$primary: #2563eb;
.btn { background: $primary; }

// After: hybrid
$colors: ('primary': #2563eb);
:root {
  @each $name, $val in $colors {
    --color-#{$name}: #{$val};
  }
}
.btn { background: var(--color-primary); }

PostCSS as an Alternative

PostCSS transforms CSS with JavaScript plugins — autoprefixer, nesting, custom media, and postcss-preset-env polyfill future CSS. It is not a preprocessor but achieves similar goals with standard CSS syntax.

Native CSS nesting (2023+) reduces the need for Sass nesting. CSS @layer manages cascade. Evaluate whether your Sass usage is truly needed or habit.

/* Native CSS nesting (modern browsers) */
.card {
  padding: 1rem;
  & .title { font-size: 1.25rem; }
  &:hover { box-shadow: var(--shadow-md); }
}

/* PostCSS autoprefixer adds vendor prefixes automatically */

From @import to @use

The Sass module system is mandatory for new projects. Migrate @import to @use/@forward incrementally. The sass migrator tool automates much of this conversion.

Run npx sass-migrator module --migrate-deps your-entry.scss to convert an entire project. Review output carefully — namespacing changes may break references.

# Automated migration
npx sass-migrator module --migrate-deps src/scss/main.scss

# Before
@import 'variables';
@import 'mixins';

# After
@use 'variables';
@use 'mixins';

Comparing Preprocessors

Less uses similar syntax but lacks Sass module system and has a smaller ecosystem. Stylus offers optional syntax but minimal industry adoption. PostCSS is plugin-based, not a full preprocessor.

Sass remains the industry standard for CSS preprocessing in 2024+. Its module system, Dart Sass performance, and framework integration (Bootstrap, Foundation) keep it relevant.

// Sass — industry standard, full-featured
@use 'sass:color';
$adjusted: color.adjust(#2563eb, $lightness: 10%);

// Less — simpler, declining adoption
@primary: #2563eb;
.adjusted { color: lighten(@primary, 10%); }

When to Keep Sass

Keep Sass when you rely on: map-driven token generation, complex mixin libraries, framework customization (Bootstrap), or team workflows built around SCSS partials.

Drop Sass when your project only uses variables and nesting — native CSS covers both now. The migration cost should be weighed against maintenance savings. Small projects benefit most from dropping Sass; large design systems often keep it.

  • Audit your Sass usage — many projects use less than 20% of features
  • CSS nesting, @layer, and custom properties cover 80% of Sass use cases
  • Migration tools reduce manual effort but require testing
// Sass still valuable for:
// 1. Generating utility classes from maps
// 2. Bootstrap/framework variable overrides
// 3. Complex responsive mixins
// 4. Design token compilation pipelines

// Native CSS sufficient for:
// 1. Simple variable theming
// 2. Basic nesting
// 3. Component-scoped styles (CSS Modules)

Get In Touch


Ready to discuss your next project? Drop me a message.