SASS Functions
This article explains SASS functions.
We will thoroughly explain SASS functions from basics to advanced topics, including practical samples useful in real-world work.
YouTube Video
SASS Functions
SASS functions are powerful tools that encapsulate reusable logic in stylesheets, enabling calculations, formatting, and conditional branching.
Basic Structure and Usage of Functions
SASS functions are defined with @function and return a value using @return. Functions are called in the same way as built-in functions.
1// Example: Define a simple function that doubles a value
2@function double($n) {
3 @return $n * 2;
4}
5
6// Use the function
7.example {
8 width: double(10px); // -> 20px
9}- This code defines a function that doubles a number and applies it to the width. As a result,
.example { width: 20px; }will be generated.
Arguments, Default Values, and Type Handling
Functions can accept multiple arguments and set default values. SASS does not enforce static typing, but paying attention to argument formats makes your functions more robust.
1// Example: Function with default parameters
2@function responsive-font($base-size, $scale: 1.2, $unit: px) {
3 @return $base-size * $scale + $unit;
4}
5
6.title {
7 font-size: responsive-font(16, 1.25); // -> 20px
8}responsive-fonthas default values forscaleandunit, and some arguments can be omitted when calling it. In this example, a value likefont-size: 20px;will be output.
Using Variadic Arguments (...)
Use variadic arguments if you want to pass multiple values. This is useful for handling lists or multiple colors.
1// Example: Sum any number of numbers passed in
2@function sum-all($numbers...) {
3 $total: 0;
4 @each $n in $numbers {
5 $total: $total + $n;
6 }
7 @return $total;
8}
9
10.box {
11 padding: sum-all(4px, 6px, 10px); // -> 20px
12}- A variadic argument like
$numbers...is treated as a list and can be processed using@each. In this example,padding: 20px;will be output.
Returning and Manipulating Lists or Maps
Functions can also return lists (space or comma separated) and maps. This is useful for returning complex values.
1@use "sass:map";
2
3// Example: Return a map of spacing scale
4@function spacing-scale($base) {
5 @return (
6 'small': $base * 0.5,
7 'medium': $base,
8 'large': $base * 2
9 );
10}
11
12$scale: spacing-scale(8px);
13
14.card {
15 margin-bottom: map.get($scale, 'medium');
16}- A map is returned by the function, and then values are retrieved with
map.get. This allows you to maintain a consistent spacing system.
Functions with Conditionals and Loops
@if, @else if, @else, @for, @each, and @while can all be used inside functions. You can create calculation logic with conditionals and loops.
1// Example: Generate modular scale value using loop
2@function modular-scale($step, $base: 1rem, $ratio: 1.25) {
3 $result: $base;
4 @if $step == 0 {
5 @return $result;
6 }
7 @if $step > 0 {
8 @for $i from 1 through $step {
9 $result: $result * $ratio;
10 }
11 } @else {
12 @for $i from 1 through abs($step) {
13 $result: $result / $ratio;
14 }
15 }
16 @return $result;
17}
18
19.h1 {
20 font-size: modular-scale(3, 1rem, 1.333);
21}- This function calculates a modular scale and multiplies or divides depending on positive or negative steps.
modular-scale(3, 1rem, 1.333)returns a font size three steps above the base.
Error Handling and Warnings (@error, @warn)
You can abort with @error on invalid arguments or unexpected operations, and issue warnings with @warn. The purpose is to alert users to problems early.
1@use "sass:math";
2@use "sass:meta";
3
4// Example: Validate input and throw an error for invalid units
5@function ensure-length($value) {
6 @if meta.type-of($value) != 'number' or math.is-unitless($value) {
7 @error "Expected a length with units, got #{$value}.";
8 }
9 @return $value;
10}
11
12// Valid input (should pass)
13.test-valid {
14 width: ensure-length(10px); // expect: 10px
15}
16
17// Invalid input (should throw error during compilation)
18// Uncomment the following to test error handling:
19//
20// .test-invalid {
21// // expect error: "Expected a length with units, got 10."
22// width: ensure-length(10);
23// }- If you pass invalid values, an error will be output at build time, making it easier to identify the cause. Checks within functions are useful for early bug detection.
Creating Color-Specific Functions
In SASS, you can combine various functions that manipulate colors to create your own color palette. This is useful for managing a consistent color scheme throughout your project.
1@use "sass:color";
2@use "sass:list";
3
4// Example: Generate a color palette (tints and shades) from a base color
5@function palette($color, $steps: 5, $strength: 10%) {
6 $colors: ();
7 @for $i from 0 through $steps {
8 $amount: $i * $strength;
9 $shade: if($i == 0, $color, color.mix(black, $color, $amount));
10 $tint: color.mix(white, $color, $amount);
11 $colors: list.append($colors, $shade);
12 $colors: list.append($colors, $tint);
13 }
14 @return $colors;
15}
16
17$palette: palette(#3498db, 3, 15%);
18
19.btn {
20 background-color: list.nth($palette, 1);
21}- In this example,
color.mixis used to create shades by mixing with black and tints by mixing with white. The values are returned in a list, and can be accessed usinglist.nth.
Notes on Performance and Compile Time
SASS functions are evaluated at compile time. Heavy loops, deep recursion, or extensive map operations will increase compile times. Keep functions small and simple; consider handling complex processing outside SASS, in build tools or preprocessors, if necessary.
Practical Utility Function Collection
Here are some commonly used utility functions. The code is designed to be immediately usable in real projects.
1@use "sass:math";
2
3// Example: Clamp a value between min and max
4@function clamp-value($value, $min, $max) {
5 @if $value < $min {
6 @return $min;
7 } @else if $value > $max {
8 @return $max;
9 }
10 @return $value;
11}
12
13// Example: Convert px to rem (with optional root size)
14@function px-to-rem($px, $root: 16px) {
15 @if math.unit($px) != "px" {
16 @error "px-to-rem requires a px value.";
17 }
18 @return ($px / $root) * 1rem;
19}clamp-valueenforces upper and lower limits on a value, andpx-to-remconverts pixel values to rem. Both of these simplify processes that frequently arise in responsive design.
Selecting Between @function and Mixins (@mixin)
Functions specialize in returning values, while mixins output CSS blocks. If the result of the logic is a single property value, use a function; if it's an entire style block, use a mixin.
1// Example: Function returns a value
2@function border-radius-value($size) {
3 @return $size * 1px;
4}
5
6// Example: Mixin outputs properties
7@mixin rounded($size) {
8 border-radius: border-radius-value($size);
9 -webkit-border-radius: border-radius-value($size);
10}
11.card {
12 @include rounded(8);
13}- Functions return values such as numbers or colors for use in other properties, while mixins directly insert groups of properties. Strict separation in design increases maintainability.
String Manipulation and Output Format Considerations
Be careful when handling numbers with units and strings in SASS. Concatenating a string to a number with a unit may produce unintended output. Use unquote() or string interpolation (#{}) as needed.
1@use "sass:math";
2
3// Example: Safely create a CSS value string
4@function px-percentage($px, $total) {
5 $percent: math.div($px, $total) * 100;
6 @return "#{$percent}%";
7}
8
9// Safer with interpolation and math module
10@function px-percentage-safe($px, $total) {
11 $percent: math.div($px, $total) * 100;
12 // Round to 2 decimal places safely
13 $rounded: math.div(math.round($percent * 100), 100);
14 @return "#{$rounded}%";
15}- When returning percentages as strings, manage precision using interpolation or
roundfor better clarity. To avoid bugs, always handle data types clearly when concatenating calculation results with strings.
Best Practices for Testing and Documentation
After writing a function, create small SCSS files with usage examples as tests, which makes maintenance easier. You can document for each function the input type/unit, return type, failure behavior, and usage examples.
1@use "sass:math";
2
3// Example: Inline "tests" (partial usage examples)
4// These can be compiled separately during development
5
6@function double($n) {
7 @return $n * 2;
8}
9
10@function px-to-rem($px, $root: 16px) {
11 @if math.unit($px) != "px" {
12 @error "px-to-rem requires a px value.";
13 }
14 @return math.div($px, $root) * 1rem;
15}
16
17// Test double()
18.test-double {
19 width: double(12px); // expect 24px
20}
21
22// Test px-to-rem()
23.test-rem {
24 font-size: px-to-rem(18px, 18px); // expect 1rem
25}
26
27// --- Inline debug tests ---
28@debug "double(12px) => #{double(12px)} (expect 24px)";
29@debug "px-to-rem(18px, 18px) => #{px-to-rem(18px, 18px)} (expect 1rem)";- Leaving comments with small examples of 'expected output' makes it easier to spot regressions during future refactoring. Automatically compiling in a CI environment and visually checking the output is effective.
Summary
SASS functions are a powerful way to enhance reusability and consistency in styles. Design them to be small and simple, and ensure safety using @error and @warn. Utility functions for color, spacing, and unit conversion are convenient to consolidate into a shared library. To avoid compile overhead, consider separating complex processing into other build steps when necessary.
You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.