Skip to content

Extending Sass

While Sass provides a rich set of built-in features, you can extend its capabilities in several ways, primarily through custom functions and integration with build environments.

The most common way to extend Sass logic is by defining your own functions directly within your Sass files using the @function rule. These functions can encapsulate complex calculations, logic, or transformations, making your stylesheets more powerful and maintainable.

Syntax:

@function function-name($arg1, $arg2: default-value) {
// SassScript logic
$result: ...;
@return $result;
}

Example: A function to calculate REM values from pixels.

_functions.scss
@use 'sass:math'; // Import built-in math module
$base-font-size: 16px; // Base font size for REM calculation
@function rem($pixels) {
@if type-of($pixels) != 'number' or not unitless($pixels) {
@error "#{$pixels} is not a unitless number for rem() function.";
}
@return math.div($pixels, $base-font-size / 1px) * 1rem; // Use math.div for safe division
}
// Usage in another file
@use 'functions';
.element {
padding: functions.rem(20);
margin-bottom: functions.rem(40);
}

Key points about custom functions:

  • They must return a value using @return.
  • They can accept arguments, including default values.
  • They should ideally be placed in dedicated partials (e.g., _functions.scss) and loaded using @use.
  • They can leverage built-in Sass modules (like sass:math, sass:color, sass:string) for advanced operations.
  • Use clear naming conventions, possibly prefixed (e.g., my-prefix-function-name) to avoid conflicts.

When using Dart Sass in a Node.js environment (e.g., via npm), you can interact with it programmatically using its JavaScript API. This allows for more advanced integrations:

  • Custom Importers: Define logic to resolve @use or @import paths from sources other than the filesystem (e.g., databases, remote URLs).
  • Custom Functions in JavaScript: Define complex functions in JavaScript that can be called from within your Sass code. This is useful when the logic is too complex for SassScript or requires accessing Node.js APIs.
  • Build Tool Integration: Fine-tune how Sass compilation works within tools like Webpack, Gulp, or custom build scripts.

Example (Conceptual JS API usage for custom function):

const sass = require('sass');
const result = sass.compile( 'styles.scss', {
functions: {
// Define a function callable as 'fetch-data()' in Sass
'fetch-data()': () => {
// Perform some complex JS logic, e.g., read a file
const data = require('./data.json');
return new sass.SassString(data.someValue);
}
}
});
console.log(result.css);

Refer to the official Dart Sass JavaScript API documentation for detailed usage: https://sass-lang.com/documentation/js-api

Sass automatically caches parsed files (partials, modules) to speed up recompilation. When you run Sass (especially in --watch mode), it only reparses files that have changed since the last compilation. This caching mechanism is generally handled internally and doesn’t require explicit configuration unless you have very specific needs addressed by the JS API’s caching options.

Extending Sass primarily involves writing custom @function directives for reusable logic within Sass itself. For more advanced scenarios involving integration with the surrounding environment (like Node.js), the JavaScript API provides powerful tools for custom importers and functions.