Tutorialsteacher

Follow Us

Articles
  • C#
  • C# OOP
  • ASP.NET Core
  • ASP.NET MVC
  • LINQ
  • Inversion of Control (IoC)
  • Web API
  • JavaScript
  • TypeScript
  • jQuery
  • Angular 11
  • Node.js
  • D3.js
  • Sass
  • Python
  • Go lang
  • HTTPS (SSL)
  • Regex
  • SQL
  • SQL Server
  • PostgreSQL
  • MongoDB
  • Sass - Get Started
  • What is Sass
  • Sass - Setup Environment
  • Sass - Syntax
  • Sass - Variable
  • Sass - Script
  • Sass - Data Types
  • Sass - Operators
  • Sass - Functions
  • String Functions
  • Numeric Functions
  • List Functions
  • Map Functions
  • Selector Functions
  • Introspection Functions
  • Color Functions
  • Control Directives
  • Import Files and Partials
  • Sass - Mixins
  • Sass - Inheritance
Entity Framework Extensions - Boost EF Core 9
  Bulk Insert
  Bulk Delete
  Bulk Update
  Bulk Merge

Sass - Mixins

In recent years HTML has made great strides towards become more semantic. Tags like <aside> and <article> enforce the meaning of the content rather than its layout. Unfortunately, the same isn't true of CSS. Defining classes like .float-left, .row and .col is better than re-defining float properties for every HTML tag, but they hardly adds to the meaning of the HTML.

There are CSS frameworks around they try to address the problem. (Semantic UI is a popular example; you'll find it at semantic-ui.com.) Sass provides another way, via the @mixin directive. Mixins are primarily used to provide non-semantic styling, but they can contain any valid CSS or Sass. The syntax is straight-forward:

Syntax:
 
@mixin &lt;name&gt;
{
    &lt;contents&gt;
}

Once you've created the mixin, simply use @include where you want the rules to be included in your file.

Syntax:

&lt;selector&gt;
{
    @include &lt;mixin-name&gt;

    [&lt;other rules&gt;]

}

Let's look at a simple example.

SCSS: Mixin
@mixin float-left {
   float: left;
}

.call-out {
  @include float-left;
  background-color: gray;
}

The resulting CSS will be:

CSS:
.call-out {
   float: left;
   background-color: gray;
}

The mixin in the above example is defined in the same file where it's used, but you can (and usually will) define mixins in a partial. Just @import the file itself before you use the @include directive.

A Sass mixin isn't restricted to just defining property rules; it can also include selectors, including parent selectors. Using this technique, you could, for example, define all the rules for a button-like link in a single mixin:

SCSS:
@mixin a-button {
   a {
      background-color: blue;
      color: white;
      radius: 3px;
      margin: 2px;
      
      &:hover {
         color: red;
      }

      &:visited {
         color: green;
      }
   }
}

Use the @include directive to include this mixin in a style, as shown below:

SCSS: @include Mixin
@include a-button.scss //assuming a-button.scss is the name of above mixin file

.menu-button {
   @include a-button;
}

and the output would be:

CSS:
.menu-button a {
   background-color: blue;
   color: white;
   radius: 3px;
   margin: 2px;
}
.menu-button a:hover {
   color: red;
}
.menu-button a:visited {
   color: green;
}

Mixin Variables

If you have more than one class that includes this functionality, it's clear that previous exmample will save a lot of typing and be more maintainable. But what if you have several classes that have the same basic functionality, but you need to pass different colors? Sass makes it easy: just pass the colors as variables, which are defined like function parameters:

SCSS: Mixin Variable
@mixin a-button($base, $hover, $link) {
   a {
      background-color: $base;
      color: white;
      radius: 3px;
      margin: 2px;
      
      &:hover {
         color: $hover;
      }

      &:visited {
         color: $link;
      }
   }
}

You pass the variable arguments to the mixin using the normal syntax:

SCSS:
.menu-button {
   @include a-button(blue, red, green);
}
.text-button {
   @include a-button(yellow, black, grey);
}

That example would result in the following CSS:

CSS:
.menu-button a {
   background-color: blue;
   color: white;
   radius: 3px;
   margin: 2px;
}
.menu-button a:hover {
   color: red;
}
.menu-button a:visited {
   color: green;
}
.text-button a {
   background-color: yellow;
   color: white;
   radius: 3px;
   margin: 2px;
}
.text-button a:hover {
   color: black;
}
.text-button a:visited {
   color: grey;
}

Sass even lets you provide default values for mixin variables:

SCSS:
@mixin a-button($base: red, $hover: green, $link: blue) {
   a {
      background-color: $base;
      color: white;
      radius: 3px;
      margin: 2px;

      &:hover {
         color: $hover;
      }

      &:visited {
         color: $link;
      }
   }
}

When you define a default variable in this way, you only need to provide values that change when you include the mixin:

SCSS:
.menu-button {
   @include a-button($link: orange);
}

This would result in the following CSS:

CSS:
.menu-button a {
   background-color: blue;
   color: white;
   radius: 3px;
   margin: 2px;
}
.menu-button a:hover {
   color: red;
}
.menu-button a:visited {
   color: orange;
}

As you can see, the a:visited rule is assigned color:orange, as provided, but the other two rules have the default values.

Just as when you call a Sass function, you only need to provide the parameter name if you're not including the arguments out of order or skipping some. This would work just fine (although the resulting button would be pretty ugly):

SCSS:
.menu-button {
    @include a-button(darkmagenta, darkolivegreen, skyblue);
}

Variable Variables

Some CSS properties can take different numbers of variables. An example is the margin property, which can take from 1 to 4 values. Sass supports this using variable arguments, which are declared with an ellipsis after their names:

SCSS: Mixin Variables
@mixin margin-mix($margin...) {
   margin: $margin;
}

Given this mixin definition, any of the following @include directives will transpile without error:

SCSS:
.narrow-border {
   @include margin-mix(1px);
}

.top-bottom-border {
  @include margin-mix(3px 2px);
}

.varied-border {
   @include margin-mix(1px 3px 6px 10px);
}

and with the expected results:

CSS:
.narrow-border {
  margin: 1px; 
}

.top-bottom-border {
  margin: 3px 2px;
}

.varied-border {
  margin: 1px 3px 6px 10px; 
}

Passing Content to Mixins

Most often you'll use mixins for standard bits of styling that you'll use in multiple places and expand with additional rules when you include them. But you can build mixins that work the other way by passing a block of rules to the mixin. You don't need a variable to do this; the content you pass will be available to the mixin via the @content directive:

SCSS:
@mixin has-content {
   html {
      @content;
   }
}

@include has-content {
   #logo {
       background-image: url(logo.svg);
   }
}

This will result in the following CSS output:

CSS:
html #logo {
   background-image: url(logo.svg);
}

Notice the syntax here uses braces, not parentheses, to distinguish the content from any variables the mixin might declare. You can use both;

SCSS:
@mixin test-content($color) {
   .test {
      color: $color;
      @content;
    }
}

@include test-content(blue) {
   background-color: red;
}

which will result in the following CSS:

CSS:
.test {
   color: blue;
   background-color: red;
}

Passing content into a mixin isn't something you'll need to do very often, but it can be useful, particularly when you're dealing with media queries or browser-specific property names.

TUTORIALSTEACHER.COM

TutorialsTeacher.com is your authoritative source for comprehensive technologies tutorials, tailored to guide you through mastering various web and other technologies through a step-by-step approach.

Our content helps you to learn technologies easily and quickly for learners of all levels. By accessing this platform, you acknowledge that you have reviewed and consented to abide by our Terms of Use and Privacy Policy, designed to safeguard your experience and privacy rights.

[email protected]

ABOUT USTERMS OF USEPRIVACY POLICY
copywrite-symbol

2024 TutorialsTeacher.com. (v 1.2) All Rights Reserved.