Sass Multiple Arguments, Lists or Arglist

Kitty Giraudel

I do a lot of Sass code reviews. Along the same lines, I like to read frameworks’ code. Needless to say, I have seen a lot of things, both good and bad, when it comes to Sass.

If there is something that always make me grind my teeth when I read other people’s Sass, it’s seeing mixins and functions using lists instead of variable arguments, or using lists instead of multiple named arguments.

In this article I’d like to take a look at this issue and, hopefully, show when to use what more clearly.


Before going any further let’s have a quick look at the terminology. Both functions and mixins are able to accept arguments, from 0 to infinity. That means you can make an argument-less function/mixin or one with a multitude of arguments. Now let’s go deeper.

In Sass, a list is the equivalent to an array in other languages. A value that happens to have list as a type (checked with the type-of function) is a collection of several values that have a specific type (number, string, bool, color, list, map or null). For a deeper understanding of Sass lists, I suggest you read my article about this.

Last but not least, there is a variable argument. You may not have known that arglist is an actual Sass data type (it’s mentioned nowhere in the docs). The thing is, you cannot easily create an arglist (deliberately) because it is usually an internal mecanism from Sass which happens when you use the variable argument notation within a mixin/function signature.

For instance:

@mixin shadows($shadows...) {
  box-shadow: $shadows;

In this example, $shadows is an arglist. By using ... in the signature, we make it possible to pass any number of arguments, from none to a bazillon. It shares the exact same traits with a regular list, except that it is always comma-separated since several arguments are delimited by commas.

Now that we are okay with the terminology, it’s time to determine what to use when. Let’s start with the easy one.

The variable argument

If you don’t know how many arguments will be passed to the function/mixin because there could be none or as many as the number of stars in the universe, it means you whould be dealing with an unknown number of arguments, a.k.a. an arglist.

For instance, let’s consider a linear-gradient mixin:

@mixin linear-gradient($direction, $gradients...) {
  background-color: nth($gradients, 1);
  background-image: linear-gradient($direction, $gradients...);

.selector {
  @include linear-gradient(to right, magenta, red, orange, yellow, green, blue, purple);

This is the perfect case for a variable argument because there can be any number of color-stops passed to the mixin. Don’t use a list only to loop and create a comma separated list… It makes no sense.

Multiple arguments

Now let’s move on to multiple arguments. Multiple distinct named arguments are often used when dealing with unrelated arguments. Sticking to our gradient mixin, we wouldn’t package the direction in the gradients list. It serves a completely different purpose and thus should stand in its own argument.

In most cases, you will use multiple arguments rather than a list of an arglist. It is the common use case, a function/mixin needs a, b and c to work, so you make it accept three arguments: $a, $b and $c. If some of those arguments have a default value, you add this default value within the mixin signature, for instance $a, $b, $c: "default".

One thing very few people know about, is that setting multiple arguments within a function/mixin signature doesn’t necessarily mean you have to pass them one by one. Let’s put aside our gradient mixin and consider a dummy function for a minute:

@function dummy($a, $b, $c: "default") {
  // do stuff

Now, let’s say you have a list called $parameters with the 3 arguments ready.

$parameters: (true, 42, 'kittens');

There are two ways for you to call the function based on your list of parameters. Either like this, which is inelegant:

$value: dummy(nth($parameters, 1), nth($parameters, 2), nth($parameters, 3));

Or like this, instructing Sass to pass $parameters as a variable argument:

$value: dummy($parameters...);

While the second version is quite handy, it requires the $parameters to be correctly ordered. To work around this, there is a third way of doing so since Sass 3.3, using a map:

$parameters: (
  'c': 'kittens',
  'a': true,
  'b': 42

$value: dummy($parameters...);

By making map keys matching the arguments name, you can convert a map to a variable argument on the fly by appending ... to it. Sass will correctly grab values in the correct order.

Back to our initial topic. Using multiple distinct arguments is much more powerful than requiring the user to pass a list, because you give them the choice: either they can pass arguments one by one, or all at once with either a list or a map.

So think twice next time you want to replace a couple of arguments with a list with a function/mixin signature.

The list

From what I can tell, it is quite unusual to have a mixin or function expecting a list. Either you would use multiple arguments because they are all unrelated, or you would pass an arglist because your function/mixin needs to accept any number of related arguments.

List are often used as an internal tool to store several values within a unique variable. However, some functions/mixins might expect a list because they actually do some manipulation on this list. For instance a function testing whether a value is contained within a list obviously needs a list to work. Not named arguments since we don’t know the number. Not a variable argument since it is a single entity.

@function contains(/* List */ $haystack, /* Any */ $needle) {
  @return not not index($haystack, $needle);

Allow me to drift a little bit. The current version of Bourbon provides a mixin to help sizing elements. The idea is simple: you pass it one value, it assigns it to both width and height you pass it two values, it gives width the first and height the second.

Now, this is easily doable with something like this:

/// Helper mixin to size elements
/// @param {Number} $width - Width
/// @param {Number} $height ($width) - Height
@mixin size($width, $height: $width) {
  width: $width;
  height: $height;

If $height is not defined, it should fall back to its default value which happens to be the value of $width. It’s both elegant and concise. Now, I am not quite sure why Bourbon decided to go the other way and ask for a list instead.

/// Helper mixin to size elements
/// @param {List} $size - Width and possibly height (but not mandatory)
@mixin size($size) {
  $height: nth($size, 1);
  $width: $height;

  @if length($size) > 1 {
    $height: nth($size, 2);

  width: $width;
  height: $height;

I mean, why? In this case, it makes absolutely no sense to use a list. Both values are unrelated, so they should not be packaged within the same variable. Also, Sass comes with a built-in way to set default values directly from the signature.

The only gain from this version is not to have to type the comma when calling the mixin:

// Standard mixin
.selector {
  @include size(13px, 37px);

// Bourbon mixin
.selector {
  @include size(13px 37px);

It definitely does not seem worth it, if you ask me.


If you expect an unlimited number of arguments, don’t use a list, use an arglist. This data type has been designed for such a purpose.

If you expect a limited number of arguments, don’t use a list, use multiple named arguments. This will allow you to pass them one by one or all at once using a list or a map.

If you expect a list for your mixin/function, use a list. You could use an arglist but it would’nt make much sense.