What are SCSS Functions?
Functions in SCSS take input, perform calculations, and return a value. Unlike mixins which output CSS code, functions return values you can use in your properties. Think of them as math helpers for your grids!
💡 Functions vs Mixins:
Mixins output CSS code.
Functions return values (numbers, colors, strings).
Creating Your First Function
Let's create a function to calculate grid column width:
// Define the function
@function grid-width($columns, $gap, $total-columns: 12) {
$gap-total: $gap * ($total-columns - 1);
@return calc((100% - #{$gap-total}) / $total-columns * $columns);
}
// Use it
.sidebar {
width: grid-width(3, 20px); // 3 columns wide
}
.main {
width: grid-width(9, 20px); // 9 columns wide
}
Built-in SCSS Functions
SCSS comes with useful built-in functions:
Math Functions:
// Calculate responsive gap
@function responsive-gap($base-gap) {
@return clamp(#{$base-gap * 0.5}, 2vw, #{$base-gap * 1.5});
}
.grid {
gap: responsive-gap(20px); // Scales between 10px and 30px
}
Percentage Calculations:
@function columns-to-percent($columns, $total: 12) {
@return percentage($columns / $total);
}
.col-4 {
width: columns-to-percent(4); // Returns 33.33333%
}
.col-8 {
width: columns-to-percent(8); // Returns 66.66667%
}
Dynamic Grid Functions
Create smart functions for common grid calculations:
// Calculate optimal column count based on container width
@function auto-columns($min-width, $container-width: 1200px, $gap: 20px) {
$columns: floor(($container-width + $gap) / ($min-width + $gap));
@return max(1, $columns); // At least 1 column
}
// Calculate fr values
@function fr-value($ratio) {
@return $ratio + fr;
}
// Use them
.auto-grid {
grid-template-columns: repeat(auto-columns(250px), 1fr);
}
.asymmetric-grid {
grid-template-columns: fr-value(2) fr-value(1); // 2fr 1fr
}
Spacing Scale Function
Create a spacing system with a function:
// Base spacing unit
$base-spacing: 8px;
// Spacing scale function
@function spacing($multiplier) {
@return $base-spacing * $multiplier;
}
.grid-tight {
gap: spacing(1); // 8px
}
.grid-normal {
gap: spacing(2); // 16px
}
.grid-loose {
gap: spacing(4); // 32px
}
.grid-xl {
gap: spacing(8); // 64px
}
✅ Design System Tip:
Use a spacing scale function to ensure all gaps in your project use consistent values. This creates visual harmony and makes your design feel professional.
Combining Functions and Mixins
Functions and mixins work great together:
// Function to calculate columns
@function calculate-columns($screen-width) {
@if $screen-width < 768px {
@return 1;
} @else if $screen-width < 1024px {
@return 2;
} @else {
@return 4;
}
}
// Mixin that uses the function
@mixin responsive-grid($gap: 20px) {
display: grid;
gap: $gap;
grid-template-columns: repeat(calculate-columns(320px), 1fr);
@media (min-width: 768px) {
grid-template-columns: repeat(calculate-columns(768px), 1fr);
}
@media (min-width: 1024px) {
grid-template-columns: repeat(calculate-columns(1024px), 1fr);
}
}
.products {
@include responsive-grid(24px);
}
Grid Track Sizing Function
Calculate the perfect minmax values:
@function track-size($min, $max: 1fr) {
@return minmax($min, $max);
}
.flexible-grid {
grid-template-columns: repeat(auto-fit, track-size(200px));
}
.controlled-grid {
grid-template-columns:
track-size(150px, 200px)
track-size(250px)
track-size(100px, 300px);
}
Real-World Example: Complete Grid System
// Configuration
$base-spacing: 8px;
$grid-columns: 12;
$breakpoints: (
sm: 640px,
md: 768px,
lg: 1024px,
xl: 1280px
);
// Spacing function
@function space($multiplier) {
@return $base-spacing * $multiplier;
}
// Column width function
@function col-width($span) {
@return calc(#{percentage($span / $grid-columns)} - #{space(2)});
}
// Breakpoint function
@function bp($name) {
@return map-get($breakpoints, $name);
}
// Responsive grid mixin using functions
@mixin container-grid {
display: grid;
grid-template-columns: repeat($grid-columns, 1fr);
gap: space(2);
@media (min-width: bp(md)) {
gap: space(3);
}
@media (min-width: bp(lg)) {
gap: space(4);
}
}
// Use it
.page-layout {
@include container-grid;
.header {
grid-column: span $grid-columns;
}
.sidebar {
grid-column: span 3;
@media (min-width: bp(md)) {
grid-column: span 4;
}
}
.content {
grid-column: span 9;
@media (min-width: bp(md)) {
grid-column: span 8;
}
}
}
Advanced: Map Functions for Grids
Store grid configurations in maps and access them with functions:
// Grid presets map
$grid-presets: (
compact: (columns: 2, gap: 12px),
normal: (columns: 3, gap: 20px),
spacious: (columns: 4, gap: 32px)
);
// Function to get preset values
@function grid-preset($name, $property) {
@return map-get(map-get($grid-presets, $name), $property);
}
// Use presets
.grid-compact {
display: grid;
grid-template-columns: repeat(grid-preset(compact, columns), 1fr);
gap: grid-preset(compact, gap);
}
.grid-normal {
display: grid;
grid-template-columns: repeat(grid-preset(normal, columns), 1fr);
gap: grid-preset(normal, gap);
}
📚 Learning Path:
Functions might seem complex at first, but they're incredibly powerful for maintaining consistent grids. Start simple with spacing functions, then gradually add more advanced calculations as you need them.