Simple alert styling using SASS MAPS
Tags: tutorial, css
Published: 2020-08-04 14:06:15

Hi folks! 🖖

In this little tutorial, we'll learn how to use ***sass maps*** to create some simple variants to a custom alert component.

The idea is to use sass ***maps*** to define a complex set of CSS variables. These variables will be cycled using *@each* mixin to create the final set of classes for our alert.

> Note: I'll use SCSS syntax instead of pure SASS. I prefer this syntax, but you can use what you like.

## SASS MAPS?

According to the [official documentation](https://sass-lang.com/documentation/values/maps):

> Maps in Sass hold pairs of keys and values, and make it easy to look up a value by its corresponding key. They’re written (<expression>: <expression>, <expression>: <expression>). The expression before the : is the key, and the expression after is the value associated with that key. The keys must be unique, but the values may be duplicated. Unlike lists, maps must be written with parentheses around them. A map with no pairs is written ().

sass maps are complex variables (we can define them as an *object* variable).

We will use the following methods:

* map-**get**: returns an object value by key
* map-**keys**: returns a list of object keys

The final result will be something like that:

{% codepen https://codepen.io/NicolaCastellaniDev/pen/abNoWMx %}

> Note - this tutorial will cover only the map management and loop part, any other CSS styles and HTML / Javascript code is included in the pen, but not necessary.

## Defining the map

First of all, we need to define the map variable in our scss file:

```scss
// maps of maps, used to define different alert type properties
$alerts: (
  "default": (
    "backgroundColor": #12cbc4,
    "titleColor": #833471,
    "messageColor": #4a4a4a
  ),
  "info": (
    "backgroundColor": #7ed6df,
    "titleColor": #30336b,
    "messageColor": #4a4a4a
  ),
  "warning": (
    "backgroundColor": #f0932b,
    "titleColor": #2c2c54,
    "messageColor": #4a4a4a
  ),
  "error": (
    "backgroundColor": #ee5253,
    "titleColor": #ff9f43,
    "messageColor": #4a4a4a
  )
);
```

As you can see this map is an object composed by:

* ***key***: the name of the class modifier
* ***value***: a *scss map* used to define some properties like:
  * **backgroundColor**
  * **titleColor**
  * **messageColor**

## Creating the loop for the class definitions

We can now use the ***@each*** mixin to loop through our ***$alerts*** map keys. This will let us define the properties for each alert type:

```scss
.alert {
  @each $alertType in map-keys($alerts) {
     // define the props here     
  }
}
```

next we use ***$alertType*** var as a selector:

```scss
.alert {
  @each $alertType in map-keys($alerts) {
     &-#{$alertType} {
        // .alert-default compiled (for example)
     } 
  }
}
```

This mixin will generate the following css:

```css
.alert.alert-default { ... }
.alert.alert-info { ... }
.alert.alert-warning { ... }
.alert.alert-error { ... }
```

Next, we define the custom properties based on current class.

## Using ***map-get*** to retrieve class related properties

We can use the ***map-get*** method to get the *backgroundColor* property for a specific class:

```scss
.alert {
  @each $alertType in map-keys($alerts) {
     &-#{$alertType} {
        background-color: map-get(
          map-get($alerts, $alertType),
          backgroundColor
        );
     } 
  }
}
```

This will generate the following css:

```css
.alert.alert-default { 
  background-color: #12cbc4;
}
.alert.alert-info { 
  background-color: #7ed6df;
}
.alert.alert-warning { 
  background-color: #f0932b;
}
.alert.alert-error { 
  background-color: #ee5253;
}
```

## Nested classes properties

I don't want to go too far or bore you with unnecessary concepts, so I will give you the complete styling for nested classes as follow:

```scss
.alert {
  @each $alertType in map-keys($alerts) {
     &-#{$alertType} {
        background-color: map-get(
          map-get($alerts, $alertType),
          backgroundColor
        );

        .alert-title {
          color: map-get(map-get($alerts, $alertType), titleColor);
          font-weight: bold;
        }

        .alert-message {
          color: map-get(map-get($alerts, $alertType), messageColor);
          font-weight: light;
        }

        .alert-close {
          border-color: map-get(
            map-get($alerts, $alertType),
            backgroundColor
          );
        }
     } 
  }
}
```

Of course this is only an example, you can use your custom selectors and HTML structure.

## Conclusions

This little tutorial shows how you can handle different type of modifiers/classes with a little bit of scss code. Instead of defining the same properties N times (*with N = number of variations we want to handle*), we can use sass maps to handle them smartly.

What do you think? Do you agree with this method? Do you have any advice?

Thanks for reading and good coding 🐱‍👤