• 15 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 3/13/23

Integrate advanced Sass data types

List-making and cartography

Remember way back when you were learning about variables? We briefly covered the data types available within Sass, and I told you not to worry too much about lists and maps because we’d be covering them in depth in just a bit? Well, it’s been a bit, so that must mean it’s list and map time!

The Sass variables we've covered so far only store single values: a color, a size, etc. That's fine for a lot of uses, but what about something like padding? You can assign four different values in a single rule:

.block {
    padding: 1rem 2rem 3rem 4rem;
}

Creating a variable for each side's padding size would be way more work than it's worth. But, what about a variable that stored all four dimensions in a single variable?

$padding-dimensions: 1rem 2rem 3rem 4rem;

.block {
    padding: $padding-dimensions;
}

Wait! Does that actually work?! Let's check out the compiled CSS:

.block {
  padding: 1rem 2rem 3rem 4rem;
}

What devilry is this?!

$padding-dimensionsis what Sass calls a list, which is a list of values. They allow you to group values together in a single variable. In this case, we've made a list of dimensions to use as values for a padding property.

To make a list, you just need to define a variable and fill it with values. The syntax for writing them is extremely flexible. You can separate list items with spaces, like we've done with  $padding-dimesions, or use commas to separate them:

$syntax-01: 1rem 2rem 3rem 4rem;

$syntax-02: 1rem, 2rem, 3rem, 4rem;

And you can write them with or without parentheses:

$syntax-01: 1rem 2rem 3rem 4rem;

$syntax-02: 1rem, 2rem, 3rem, 4rem;

$syntax-03: (1rem 2rem 3rem 4rem);

$syntax-04: (1rem, 2rem, 3rem, 4rem);

All of them will compile identically:

$syntax-01: 1rem 2rem 3rem 4rem;

$syntax-02: 1rem, 2rem, 3rem, 4rem;

$syntax-03: (1rem 2rem 3rem 4rem);

$syntax-04: (1rem, 2rem, 3rem, 4rem);

.syntax-01 {
    padding: $syntax-01;
}
.syntax-02 {
    padding: $syntax-02;
}
.syntax-03 {
    padding: $syntax-03;
}
.syntax-04 {
    padding: $syntax-04;
}
.syntax-01 {
  padding: 1rem 2rem 3rem 4rem;
}

.syntax-02 {
  padding: 1rem, 2rem, 3rem, 4rem;
}

.syntax-03 {
  padding: 1rem, 2rem, 3rem, 4rem;
}

.syntax-04 {
  padding: 1rem 2rem 3rem 4rem;
}

Just because you choose to store a group of values in a list, doesn't mean that you want to use them all in the same instance. You can also use the values from list items individually. Let's make a list of the various font sizes we are using throughout the site:

$font-size: 7rem 5rem 4rem 2rem;

Now let's use the 2rem value from $font-size to populate the value of our labels' font size. To access individual values from a list, call the nth() function with the name of the list and the index of list item:

$font-size: 7rem 5rem 4rem 2rem;

.form{
    &__field {
        & label {
            font-size: nth($font-size, 4);
        }
    }
}

We want to use the 2rem value from$font-size on our form's label's font-size,  so call  nth($font-size, 4), since 2rem is the fourth value in  $font-size.

Lists make more maintainable code by allowing you to group associated values together. But they can be a bit tough to read, especially coming back after being away for a while. Looking at a list and trying to remember the uses of its items can take some head-scratching and scrolling. In a few months or even a few minutes, you will probably forget the indices of the different values in  $font-size.

Map making

Lists can be difficult to read and remember because there’s no real context to list contents; just values grouped together. That's why you have Sass maps! They are a lot like lists, but give each value a name in the form of key/value pairs:

$font-size: (logo:7rem, heading:5rem, project-heading:4rem, label:2rem);

By giving each value a key, or name, it makes figuring out and remembering its purpose a lot clearer. And clearer is easier. And easier is good. 👍

The rules for writing maps are much stricter than those for writing lists. With lists, just about everything is optional. But maps must be surrounded by a set of parentheses, and must use commas to separate the key/value pairs:

$map: (
    key-01: value-01,
    key-02: value-02,
    key-03: value-03
);

Accessing the value of a map is a bit different than the nth() function for lists. With maps, you need to call the map-get() function:

$font-size: (logo:7rem, heading:5rem, project-heading:4rem, label:2rem);

.form{
    &__field {
        & label {
            font-size: map-get($font-size, label);
        }
    }
}

map-get() requires two arguments: the first is the name of the map, and the second is the name of the key. The end result will still be 2rem compiled as the font size in the CSS:

.form__field label {
  font-size: 2rem;
}

 Let’s put our newly found map-making skills to the test and create a map named   $input-txt-palettes, which contains the color palettes for our text inputs. Group the palettes by their state, and create a key for each pseudo-class:  active,  focus, and  invalid:

$colour-primary: #15DEA5;
$colour-secondary: #001534;
$colour-accent: #D6FFF5;
$colour-white: #fff;
$colour-invalid: #DB464B;

$txt-input-palette: (
    active: ,
    focus: ,
    invalid:
);

Now you have keys, but they’re empty; they need values assigned. Fill the keys with your color palettes, which will require nesting another map for the colors within each of the keys.

That’s right, maps inside of maps! 🗺🗺🗺

The values in maps (and lists) can be any valid Sass data type, maps included.  Your text input states need to store three separate colors, so each key will contain a map with three values: the state’s border, background, and text colors:

$colour-primary: #15DEA5;
$colour-secondary: #001534;
$colour-accent: #D6FFF5;
$colour-white: #fff;
$colour-invalid: #DB464B;

$txt-input-palette: (
    active: (
        bg: $colour-primary,
        border: $colour-primary,
        txt: $colour-white,
    ),
    focus: (
        bg: $colour-primary,
        border: $colour-primary,
        txt: $colour-white,
    ),
    invalid: (
        bg: $colour-invalid,
        border: $colour-white,
        txt: $colour-white,
    )
);

Now you have a variable that contains all of the color information for the various states of your text inputs, in a format that is easily read and remembered. And should you need to update any of the schemes or values, they're all centralized in a single, easy-to-locate block.

Mix'n'map

You have all of the palette info stored waiting to be used. To make things a bit easier on you, let’s make a mixin to deploy the palettes. You need to assign rules for theborder,  background-color, and text color properties, with the appropriate values from$txt-input-palette.

@mixin txt-input-palette {
    border: .1rem solid $border;
    background-color: $bg;
    color: $txt;
}

To declare which state (hover, etc.) to pull the map from, you need to assign an argument for the state that you can pass into the mixin:

@mixin txt-input-palette($state) {
    border: .1rem solid $border;
    background-color: $bg;
    color: $txt;
}

 With the name of the state, you can store its palette map in a variable name $palette :

@mixin txt-input-palette($state) {
    $palette: map-get($txt-input-palette, $state);
    border: .1rem solid $border;
    background-color: $bg;
    color: $txt;
}

Now $palette contains a map of the bg,  border, and  txt  color values of the assigned state. You can use it with the map-get() function to populate the color values of your ruleset:

@mixin txt-input-palette($state) {
    $palette: map-get($txt-input-palette, $state);
    border: .1rem solid map-get($palette, border);
    background-color: map-get($palette, bg);
    color: map-get($palette, txt);
}

Now you have a mixin that you can use to style all of the text input elements and pseudo-selectors by simply passing the state when you apply the mixin! This helps keep your code maintainable and easily modifiable in the future.

Let’s apply the mixin to your default, inactive form__txt input selector:

@mixin txt-input-palette($state) {
    $palette: map-get($txt-input-palette, $state);
    border: .1rem solid map-get($palette, border);
    background-color: map-get($palette, bg);
    color: map-get($palette, txt);
}

.form {
    &__field {
        & input {
            @include txt-input-palette(focus);
        }
    }
}

Now you should see the selector  .form__field input, populated with rules for the border,  background-color and textcolor in the compiled CSS:

.form__field input {
  border: 0.1rem solid #15DEA5;
  background-color: #001534;
  color: #15DEA5;
}

Perfect!

Try it out for yourself!

In this interactive exercise, let's give our CSS some structure by using maps! Currently, you have a .btn selector and three buttons in different colors.

Generate our buttons' selectors with a map!

  • Declare a new variable with the name of $btn-mods and place a set of parentheses after the colon to contain the map keys and values.

  • Create a key for the modified pink button called “pink” and give it a value of $color-secondary

  • Create a key for the modified blue button called “blue” and give it a value of $color-tertiary

  • Replace the uses of $color-secondary and $color-tertiary with the values from the map, using the map-get() function

Review the rendered page to ensure the buttons still appear as they should - you can check my solution as well using this CodePen.

Now you have a mixin that you can use to create the properties for all the different states of your text inputs; or, you could automate it. Because that’d be a lot less tedious - and a whole lot cooler.

And that’s just what we’ll be doing next chapter!

Let's recap!

  • Lists and maps are collections of values.

  • Lists have a really flexible syntax: use commas, or skip them. Same with parentheses!

  • List values are accessed by calling their index within the  nth() function:  nth($list, index)

  • Lists indexes start at 1.

  • Maps are similar to lists, but each value is given a name, called a key:  $map(key: value)

  • Maps have a much more rigid syntax compared to lists. Maps must use parentheses and commas.

  • Map values are accessed via the map-get() function:  map-get($map, key)

  • Maps and lists can contain any valid Sass data type, including other lists and maps.

Example of certificate of achievement
Example of certificate of achievement