Functions and Built-in Function Reference
1. Custom Function Definition with @function
| Feature |
Syntax |
Description |
Example |
| Function Definition |
@function name() { } |
Declares reusable function |
@function double($n) { @return $n * 2; } |
| @return Directive |
@return value; |
Returns computed value |
Must have at least one return |
| Parameters |
$param1, $param2 |
Function arguments |
Can have defaults like mixins |
| Function Call |
name($args) |
Invokes function |
width: double(10px); |
| Scope |
Variables local to function |
Isolated scope |
Local vars don't leak outside |
| Naming |
Kebab-case or camelCase |
Descriptive, verb-based |
calculate-rem(), lighten-color() |
Example: Custom function basics
// Simple calculation function
@function strip-unit($number) {
@if type-of($number) == 'number' and not unitless($number) {
@return $number / ($number * 0 + 1);
}
@return $number;
}
// Usage
$value: strip-unit(16px); // Returns: 16
// Function with multiple parameters
@function calculate-rem($size, $base: 16px) {
$rem: $size / $base;
@return #{$rem}rem;
}
// Usage
font-size: calculate-rem(24px); // 1.5rem
font-size: calculate-rem(20px, 10px); // 2rem
// Conditional return
@function contrast-color($color) {
@if (lightness($color) > 50%) {
@return #000;
} @else {
@return #fff;
}
}
.button {
background: #3498db;
color: contrast-color(#3498db); // Returns: #fff
}
2. Function Arguments and Return Values
| Feature |
Syntax |
Behavior |
Use Case |
| Required Arguments |
@function fn($arg) |
Must be provided |
Essential parameters |
| Default Arguments |
@function fn($arg: val) |
Optional with fallback |
Common use cases |
| Variadic Arguments |
@function fn($args...) |
Accept unlimited args |
Flexible parameters |
| Named Arguments |
fn($name: value) |
Explicit parameter naming |
Clarity, skip defaults |
| Return Type |
Any Sass data type |
Numbers, strings, colors, lists, maps, null |
Flexible output |
| Multiple Returns |
Conditional @return |
Branch-based returns |
Complex logic |
| Early Return |
@return exits function |
Stops execution |
Guard clauses |
Example: Advanced function arguments
// Variadic arguments
@function sum($numbers...) {
$total: 0;
@each $num in $numbers {
$total: $total + $num;
}
@return $total;
}
$result: sum(1, 2, 3, 4, 5); // 15
// Named arguments for clarity
@function responsive-size(
$min-size,
$max-size,
$min-viewport: 320px,
$max-viewport: 1200px
) {
$slope: ($max-size - $min-size) / ($max-viewport - $min-viewport);
$intercept: $min-size - $slope * $min-viewport;
@return calc(#{$intercept} + #{$slope * 100vw});
}
// Call with named args
font-size: responsive-size(
$min-size: 14px,
$max-size: 18px
);
// Guard clauses with early return
@function safe-divide($dividend, $divisor) {
@if $divisor == 0 {
@warn "Cannot divide by zero";
@return null;
}
@return $dividend / $divisor;
}
// Return different types
@function get-spacing($key) {
$spacing: (small: 8px, medium: 16px, large: 24px);
@if map-has-key($spacing, $key) {
@return map-get($spacing, $key); // Returns number
}
@return null; // Returns null if not found
}
3. Built-in Color Functions (lighten, darken, mix)
| Function |
Syntax |
Description |
Example |
| lighten() |
lighten($color, $amount) |
Increases lightness by % |
lighten(#3498db, 20%) |
| darken() |
darken($color, $amount) |
Decreases lightness by % |
darken(#3498db, 20%) |
| mix() |
mix($c1, $c2, $weight) |
Blends two colors |
mix(#f00, #00f, 50%) |
| saturate() |
saturate($color, $amount) |
Increases saturation |
saturate(#3498db, 20%) |
| desaturate() |
desaturate($color, $amount) |
Decreases saturation |
desaturate(#3498db, 20%) |
| grayscale() |
grayscale($color) |
Removes all saturation |
grayscale(#3498db) |
| complement() |
complement($color) |
Returns opposite hue |
complement(#3498db) |
| invert() |
invert($color) |
Inverts RGB values |
invert(#3498db) |
| adjust-hue() |
adjust-hue($color, $degrees) |
Rotates hue on color wheel |
adjust-hue(#3498db, 45deg) |
| opacity/alpha() |
opacity($color) |
Gets alpha channel value |
alpha(rgba(0,0,0,0.5)) |
| transparentize() |
transparentize($color, $amount) |
Decreases opacity |
transparentize(#000, 0.3) |
| opacify()/fade-in() |
opacify($color, $amount) |
Increases opacity |
opacify(rgba(0,0,0,.5), 0.2) |
Example: Color manipulation functions
$primary: #3498db;
// Lightness adjustments
.light-bg {
background: lighten($primary, 30%); // #a8d5f2
}
.dark-bg {
background: darken($primary, 20%); // #1f5d87
}
// Color mixing
$brand-gradient: mix(#3498db, #9b59b6, 50%);
.gradient {
background: linear-gradient(
to right,
#3498db,
$brand-gradient,
#9b59b6
);
}
// Saturation
.vibrant {
color: saturate($primary, 40%); // More vivid
}
.muted {
color: desaturate($primary, 40%); // Less vivid
}
// Complementary color scheme
$accent: complement($primary); // Opposite on color wheel
.scheme {
background: $primary;
color: $accent;
}
// Transparency
$overlay: transparentize(#000, 0.5); // rgba(0, 0, 0, 0.5)
.modal-backdrop {
background: $overlay;
}
// Advanced: Color palette generator
@function generate-palette($base-color) {
@return (
base: $base-color,
light: lighten($base-color, 15%),
lighter: lighten($base-color, 30%),
dark: darken($base-color, 15%),
darker: darken($base-color, 30%),
complement: complement($base-color)
);
}
$blue-palette: generate-palette(#3498db);
Note: Use mix() instead of lighten()/darken() for more
natural color variations. Mix with white/black produces better results.
4. Built-in Math Functions (abs, ceil, floor, round)
| Function |
Syntax |
Description |
Example |
| abs() |
abs($number) |
Absolute value |
abs(-15px) → 15px |
| ceil() |
ceil($number) |
Round up to nearest integer |
ceil(4.3) → 5 |
| floor() |
floor($number) |
Round down to nearest integer |
floor(4.8) → 4 |
| round() |
round($number) |
Round to nearest integer |
round(4.5) → 5 |
| max() |
max($numbers...) |
Returns largest value |
max(1, 5, 3) → 5 |
| min() |
min($numbers...) |
Returns smallest value |
min(1, 5, 3) → 1 |
| percentage() |
percentage($number) |
Converts to percentage |
percentage(0.5) → 50% |
| random() |
random($limit) |
Random integer 1 to $limit |
random(100) → 1-100 |
| comparable() |
comparable($n1, $n2) |
Check if units compatible |
comparable(1px, 1em) → false |
Example: Math function applications
// Responsive grid calculation
@function grid-width($cols, $total: 12) {
$percent: ($cols / $total) * 100%;
@return floor($percent * 100) / 100; // Round to 2 decimals
}
.col-4 {
width: grid-width(4); // 33.33%
}
// Clamp value between min and max
@function clamp($value, $min, $max) {
@return max($min, min($value, $max));
}
$size: clamp(20px, 10px, 30px); // Returns: 20px
// Aspect ratio calculation
@function aspect-ratio-padding($width, $height) {
@return percentage($height / $width);
}
.video-16-9 {
padding-bottom: aspect-ratio-padding(16, 9); // 56.25%
}
// Random color generator
@function random-color() {
@return rgb(random(255), random(255), random(255));
}
.random-bg {
background: random-color();
}
// Spacing scale with rounding
$base-spacing: 8px;
@function spacing($multiplier) {
@return round($base-spacing * $multiplier);
}
.mt-1 { margin-top: spacing(1); } // 8px
.mt-2 { margin-top: spacing(2); } // 16px
.mt-3 { margin-top: spacing(3); } // 24px
// Ensure non-negative values
@function positive($value) {
@return max(0, $value);
}
.safe-margin {
margin: positive(-10px); // 0px (prevents negative)
}
5. String Functions (quote, unquote, str-length)
| Function |
Syntax |
Description |
Example |
| quote() |
quote($string) |
Adds quotes to string |
quote(sans-serif) → "sans-serif" |
| unquote() |
unquote($string) |
Removes quotes from string |
unquote("Arial") → Arial |
| str-length() |
str-length($string) |
Returns character count |
str-length("hello") → 5 |
| str-index() |
str-index($string, $substring) |
Finds position of substring |
str-index("hello", "ll") → 3 |
| str-insert() |
str-insert($string, $insert, $index) |
Inserts string at position |
str-insert("hello", "X", 3) → "heXllo" |
| str-slice() |
str-slice($string, $start, $end) |
Extracts substring |
str-slice("hello", 2, 4) → "ell" |
| to-upper-case() |
to-upper-case($string) |
Converts to uppercase |
to-upper-case("hello") → "HELLO" |
| to-lower-case() |
to-lower-case($string) |
Converts to lowercase |
to-lower-case("HELLO") → "hello" |
| unique-id() |
unique-id() |
Generates unique string |
unique-id() → "u1a2b3c4" |
Example: String manipulation
// Font family management
$font-stack: (Helvetica, Arial, sans-serif);
@function get-font-stack($fonts) {
$stack: '';
@each $font in $fonts {
@if str-index($font, ' ') {
$stack: $stack + quote($font) + ', ';
} @else {
$stack: $stack + $font + ', ';
}
}
@return unquote(str-slice($stack, 1, -3));
}
.text {
font-family: get-font-stack($font-stack);
}
// String replacement function
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
$before: str-slice($string, 1, $index - 1);
$after: str-slice($string, $index + str-length($search));
@return $before + $replace + $after;
}
@return $string;
}
$url: "assets/images/icon.png";
$new-url: str-replace($url, "assets", "public");
// Result: "public/images/icon.png"
// Class name generator
@function bem-class($block, $element: null, $modifier: null) {
$class: $block;
@if $element {
$class: $class + '__' + $element;
}
@if $modifier {
$class: $class + '--' + $modifier;
}
@return unquote('.' + $class);
}
// Usage
#{bem-class('card', 'header', 'large')} {
font-size: 2rem;
}
// Generates: .card__header--large { }
// Unique ID for animations
@function unique-animation-name($base) {
@return unquote($base + '-' + unique-id());
}
$anim-name: unique-animation-name('slide');
@keyframes #{$anim-name} {
from { opacity: 0; }
to { opacity: 1; }
}
6. Type Checking Functions (type-of, unit, unitless)
| Function |
Syntax |
Returns |
Example |
| type-of() |
type-of($value) |
Data type as string |
type-of(10px) → "number" |
| unit() |
unit($number) |
Unit as string |
unit(10px) → "px" |
| unitless() |
unitless($number) |
Boolean (has no unit) |
unitless(10) → true |
| is-bracketed() |
is-bracketed($list) |
Boolean (list has [ ]) |
is-bracketed([a, b]) → true |
| is-superselector() |
is-superselector($s1, $s2) |
Boolean (s1 contains s2) |
is-superselector('.a .b', '.b') |
| variable-exists() |
variable-exists($name) |
Boolean (var defined) |
variable-exists(color) |
| global-variable-exists() |
global-variable-exists($name) |
Boolean (global var exists) |
Checks global scope only |
| function-exists() |
function-exists($name) |
Boolean (function defined) |
function-exists(lighten) |
| mixin-exists() |
mixin-exists($name) |
Boolean (mixin defined) |
mixin-exists(clearfix) |
Example: Type checking and validation
// Robust unit conversion
@function convert-to-rem($value, $base: 16px) {
// Type validation
@if type-of($value) != 'number' {
@warn "#{$value} is not a number";
@return $value;
}
// Check if already unitless or rem
@if unitless($value) {
@return #{$value}rem;
}
@if unit($value) == 'rem' {
@return $value;
}
@if unit($value) == 'px' {
@return $value / $base * 1rem;
}
@warn "Cannot convert #{unit($value)} to rem";
@return $value;
}
.text {
font-size: convert-to-rem(18px); // 1.125rem
padding: convert-to-rem(16); // 16rem
margin: convert-to-rem(1.5rem); // 1.5rem
}
// Polymorphic spacing function
@function spacing($value) {
@if type-of($value) == 'number' {
@return $value * 8px;
}
@if type-of($value) == 'string' {
$map: (xs: 4px, sm: 8px, md: 16px, lg: 24px, xl: 32px);
@if map-has-key($map, $value) {
@return map-get($map, $value);
}
}
@warn "Invalid spacing value: #{$value}";
@return 0;
}
.component {
margin: spacing(2); // 16px (number)
padding: spacing('lg'); // 24px (string)
}
// Conditional mixin application
@mixin apply-if-exists($mixin-name, $args...) {
@if mixin-exists($mixin-name) {
@include #{$mixin-name}($args...);
} @else {
@warn "Mixin #{$mixin-name} does not exist";
}
}
// Safe variable getter
@function get-var($name, $fallback: null) {
@if global-variable-exists($name) {
@return #{$name};
}
@return $fallback;
}
// Type guard for lists
@function safe-nth($list, $index, $default: null) {
@if type-of($list) != 'list' {
@return $default;
}
@if $index <= length($list) and $index > 0 {
@return nth($list, $index);
}
@return $default;
}
$colors: red, blue, green;
$color: safe-nth($colors, 5, black); // Returns: black (fallback)
Function Best Practices
- Use functions for calculations, mixins for styles
- Always validate input types and return appropriate values
- Provide meaningful @warn/@error messages for debugging
- Use @return early for guard clauses and error handling
- Document expected parameters and return types
- Keep functions pure (no side effects, same input = same output)
- Name functions with verbs (calculate-, get-, is-, has-)
- Combine type checking with default parameters for robustness
Note: Modern Sass (Dart Sass) uses sass:math, sass:color,
sass:string modules. Use @use "sass:math"; and math.floor() instead of
global functions.