Sass and Compass Designer's Cookbook
上QQ阅读APP看书,第一时间看更新

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:

  1. Create your main project file called main.scss. This file should import the gradient partial file. So, the main.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; 
    }
  2. 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 
    } 
  3. Now, compile your project by running the following command in your console:
     sass sass/main.scss main.css
    
  4. Create a index.html file that will link the compiled main.css file from the previous step and will contain the HTML markup code like that shown here:
    <header>Background gradients with Sass</header> 
  5. Finally, open index.html in your browser and find that your background gradient will look as follows:
    How to do it...

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.