Writing mixins with arguments
As already mentioned in the Leveraging mixins recipe of the chapter, mixins enable you to define styles, which can be reused everywhere in your code. Mixins can also have arguments. Mixins with arguments enable you to create different types of the same pattern based on the parameters set by your mixins' call. In this recipe, you will create cross-browser background gradients with Sass.
Getting ready
You can test the mixins in this recipe with the Ruby Sass compiler. The Installing Sass for command line usage recipe of Chapter 1, Getting Started with Sass, describes how to install Ruby Sass on your system. You also will need a text editor and a browser to inspect the compiled CSS code.
How to do it...
Perform the following step to get grips on using mixins with arguments:
- Create your main project file called
main.scss
. This file should import the gradient partial file. So, themain.scss
file should contain the SCSS code like that shown here:// scss-lint:disable ColorKeyword, ColorVariable @import 'components/gradients'; header { @include gradient-horizontal(yellow, green); color: white; padding: 20px; }
- The gradient partial, the
components/_gradients.scss
file, should contain the mixin that creates your background gradient. The SCSS code in this file will look as follows:// scss-lint:disable ColorKeyword, ColorVariable @mixin gradient-horizontal($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) { background: $start-color; // Old browsers background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down }
- Now, compile your project by running the following command in your console:
sass sass/main.scss main.css
- Create a
index.html
file that will link the compiledmain.css
file from the previous step and will contain the HTML markup code like that shown here:<header>Background gradients with Sass</header>
- Finally, open
index.html
in your browser and find that your background gradient will look as follows:
How it works...
In the Leveraging mixins recipe of this chapter, you can read about how to use mixins without parameters. The gradient-horizontal()
mixin used in this recipe accepts four arguments. Mixin's arguments are set SassScript values, such as variables. Inside the mixin, you can use the parameters that are assigned to local variables with the name of the parameter.
Inspect the declaration of the mixin used in this recipe again for better understanding. This mixin's definition looks as follows:
@mixin gradient-horizontal($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {}
The gradient-horizontal()
mixin accepts four arguments. These arguments are separated by commas and written within parentheses after the mixin's name. The first $start-color
argument has a default value of #555
, followed by the $end-color
argument with a default value of #333
, the $start-percentage
argument with a default value of 0%
, and finally, the fourth $end-percentage
argument with a default value of 100%
. As you can see, default values are set with a semicolon between the name and the value.
You can include the mixin without any parameter. Without parameters, the default values are used by the mixin. Notice that parameters are only optional if the default values are set. Consider the following SCSS code that throws a Mixin bar is missing argument $height
error because the bar()
mixin is included without the required height parameter:
@mixin bar($height) { height: $height; } .bar { @include bar; }
Now turn back to the example code of the recipe. You can include the gradient-horizontal()
mixin with one, two, three, or four parameters, because all the parameters of this mixin have a default value. The following SCSS code will show you how to set a background gradient from red to blue:
@include gradient-horizontal(blue, red);
For a different start and end percentage, you will have to set the third and fourth parameters too, as it can be seen in the following SCSS code:
@include gradient-horizontal(blue, red, 50%, 75%);
Finally, you can also include mixins using explicit keyword arguments. For the example gradient-horizontal()
mixin can look like that shown here:
@include gradient-horizontal($end-color: red);
Named arguments, as used here, can be passed in any order, and the arguments with default values can be omitted.
There's more...
Sass supports variable arguments also known as variadic arguments. Variable arguments are available as a list inside the mixin. Variable arguments can be useful to set CSS properties, which accept a list of values. For instance, the background-image
CSS property accepts a list of images separated by commas.
A mixin can only accept a single variable argument; the variable argument should be at the end of the arguments' list. The variable arguments look just like normal arguments, but are followed by the ...
, syntax.
The following SCSS code shows you how a mixin that accepts an unknown number of arguments can look:
@mixin background($background-color: black, $background-images...) { background-color: $background-color; background-image: $background-images; }
The preceding mixin can now be called with an unknown number of arguments, as follows:
$background-color: red; .single-background-image { @include background($background-color, url('../image1.png')); } .multiple-background-image { @include background($background-color, url('../image1.png'), url('../image2.png'), url('../image3.png')); }
Notice that you can also include a mixin with a parameter being a list. Consider the following SCSS code:
// scss-lint:disable ColorKeyword @mixin background($color, $image-list) { background-color: $color; background-image: $image-list; } $background-color: red; .background { @include background($background-color, (url(2), url(3))); }
This SCSS code compiles into CSS code like that shown here:
.background { background-color: red; background-image: url(2), url(3); }
Because the variable argument becomes available as a list inside the mixins, you can also use the built-in list function to build more dynamic mixins. You can read more about built-in list functions in the List functions recipe of Chapter 5, Built-in Functions. Also, the @each
directive, as described in the Using the @each directive recipe of Chapter 8, Advanced Sass Coding, can be used with lists.
A block of styles can be passed to a mixin. Inside the mixins, the @content
directives hold the styles. An example of passing blocks of styles can be found here:
@mixin small-screens { @media (max-width: 767px) { @content; } } test { color: black; @include small-screens { color: red; } } @include small-screens { h1 { font-size: 2em; } }
The preceding SCSS code compiles into CSS code like that shown here:
test { color: black; } @media (max-width: 767px) { test { color: red; } } @media (max-width: 767px) { h1 { font-size: 2em; } }
Finally, you should pay some attention to the background gradient CSS code itself. In the past, browsers have used different syntaxes with different browser prefixes to support gradient backgrounds. You can read more about browser prefixes in the Using vendor prefixes recipe of Chapter 7, Cross-Browser CSS3 Mixins. This recipe discusses gradient backgrounds too. If you have to support older browsers, the background gradient code will become more complex.
See also
More information about the CSS background-image property can be found at https://developer.mozilla.org/en/docs/Web/CSS/background-image.