Making Use of Sass’ Zip() Function
Sass alleviates the need to write repetitive code when it comes to our stylesheets, but you knew that already or else you wouldn’t be reading this far. I want to show you a nice, savvy way to write shorthand properties without the need to remember the order of values for CSS like animation
and font
.
Before You Begin : Since I’m using Sass maps it might be a good idea to get comfortable with them. It just so happens there are at least two great articles.
Never Memorize What You Can Look Up In A Book
The title you just read is a famous quote from Albert Einstein -and a good one at that. My best guess is that I’m not the only developer in the world asking themselves “Now…does direction
come after fill-mode
? or is it the other way around?”
The setup that follows might not be for everyone, but I want you to take note of the approach. You could change this to work any way you want. Remember … the sky’s the limit.
Sass
@function sh-setup($config) {
@return zip(map-values($config)...);
}
$animation_config: (
name: none,
duration: 0s,
timing: ease,
delay: 0s,
iteration: 1, // infinite
direction: normal, // reverse, alternate, alternate-reverse
fill-mode: none, // forwards, backwards, both
play-state: running
);
.object {
animation: sh-setup($animation_config);
}
CSS
.object {
animation: none 0s ease 0s 1 normal none running;
}
What Happened?
Our sh-setup()
function takes an argument called config
that passes it’s value to map-values()
and the result is finally passed to the zip()
function. This function takes a comma separated list returned by map-values()
and converts that list into a space separated string! Whoa! Daaaaaannnnnggggg!!!
So…that’s cool and all, but why the three full stops (or ellipsis) at the end of map-values()
? Well, the ellipsis says to map-values()
“allow multiple values that are comma separated to be passed.” For example, when we strip away zip()
from the equation we’ll end up with the following string returned.
none, 0s, ease, 0s, 1, normal, none, running
If we didn’t add ...
Sass would output our shorthand incorrectly because zip()
can’t accept our multiple comma separated values. It sees the output above as one single string. The ...
helps tell Sass to accept an unknown number of arguments in order to strip away the commas. We the developers have to tell Sass it’s alright to split the string into separate cases so we end up with:
none 0s ease 0s 1 normal none running
Going Further
Now that we’ve done it with animation
let’s try that same approach with the font
shorthand. The font
property takes values for it’s shorthand in a very specific order otherwise the entire statement fails. If you don’t recall the order (ha-ha, who does) then let me refresh your memory:
font-style
font-variant
font-weight
font-size
line-height
font-family
Now let’s set this up to work the way we want. Take note we’re not touching our sh-setup()
function one bit and instead we’re working around it.
@function sh-setup($config) {
@return zip(map-values($config)...);
}
$fonts: "'Proxima Nova', Arial, sans-serif";
$font_config: (
font-style: normal,
font-variant: normal,
font-weight: normal,
font-measurements: 100%/1.5,
font-family: unquote($fonts)
);
body {
font: sh-setup($font_config);
}
CSS
font: normal normal normal 100%/1.5 'Proxima Nova', Arial, sans-serif;
I placed font-size
and line-height
into one variable in order to avoid over complication since we need the /
to come in-between the font-size
and line height
value. The unquote()
function is the magic that allows us to output multiple fonts for the font-family
property. This function helps preserve the single quotes recommended by the W3C for font family names containing whitespace to avoid mistakes in escaping. We also maintain commas for multiple font-family
names.
Another way we could do the previous approach is defining another map to hold our font-families, and still use the same function we’ve been using all along.
@function sh-setup($config) {
@return zip(map-values($config)...);
}
$fonts: (
primary-font: "'Proxima Nova'", // font family names containing whitespace write like this"'Font Name'"
font-fallback1: Helvetica,
font-fallback2: Arial,
font-failure: sans-serif
);
$font_config: (
font-style: normal,
font-variant: normal,
font-weight: normal,
font-measurements: 100%/1.5,
font-family: unquote(#{map-values($fonts)})
);
body {
font: sh-setup($font_config);
}
I like the readability in this case and I know exactly what font is intended for display in terms of priorities. The downside is that I had to interpolate map-values()
within unquote()
making this a bit more complicated for the sake of readability.
Parting Thoughts
Now that we’ve seen these use cases with the animation
and font
shorthand, where else do you think we could use something like zip()
? Could it be used for the background
shorthand? How about the grid
syntax? It’s really up to you to decide the approach. I hope I’ve inspired you at the very least to investigate other helper functions like zip()
available to front-end developers that want to use Sass. As you venture into the unknown keep in mind “A person who never made a mistake never tried anything new.” ~Einstein