Skip to main content

Command Palette

Search for a command to run...

Create CSS classes dynamically

Published
โ€ข4 min readโ€ขView as Markdown
G

Front-end Developer. ๐Ÿ‘พ Media engineer. โšก Facing life one bug at a time. ๐Ÿ”ฅ Easily bribed with chocolate. ๐Ÿซ she/her - #BLM

SASS interpolation is an useful tool that comes in handy when we have to create CSS classes name dynamically from an array.

For the first version of this blog, I wanted different gradients based on post tag (git, vsc, nodejs...). Each tag is append to the main card class in order to create a modifier

// card.njk

<article class="c-card c-card--{{ tag }}"> ... </div>

and its CSS was this

// card.scss

$co_card-gradient-git: #eb3349, #f45c43;
$co_card-gradient-vsc: #1a2980, #26d0ce;
$co_card-gradient-nodejs: #36582f, #7ab659;

.c-card--git {
  background: linear-gradient(to right, $co_card-gradient-git);
}

.c-card--vsc {
  background: linear-gradient(to right, $co_card-gradient-vsc);
}

.c-card--nodejs {
  background: linear-gradient(to right, $co_card-gradient-nodejs);
}

In attempt to remove repetitions and have a DRY (Don't Repeat Yourself) code, I tried to loop through a SASS list and generate classes

$tags: git, vsc, nodejs;

@each $tag in $tags {
  .c-card--#{$tag} {
    background: linear-gradient(to right, $co_card-gradient-#{tag});
  }
}

but unfortunately SASS does not support variable name interpolation at the moment! ๐Ÿ’”

If you try to compile the snippet above, you will get

Sass Error: Undefined variable: "$co_card-gradient-"

Read more about sass interpolation

The workaround

  • create a mixin using SASS conditionals with all cases you need
@mixin card-gradient($tag) {
  @if $tag == 'git' {
    background: linear-gradient($co_card-gradient-git);
  }

  @else if $tag == 'vsc' {
    background: linear-gradient($co_card-gradient-vsc);
  }

  @else if $tag == 'nodejs' {
    background: linear-gradient($co_card-gradient-nodejs);
  }
}
  • use the tag list to dynamically generate classes names
$tags: git, vsc, nodejs;

@each $tag in $tags {
  .c-card--#{$tag} {
    @include card-gradient($tag);
  }
}

๐Ÿ–ฅ Codepen example

Dynamic classes using CSS vars

Note that if we use CSS vars instead of SASS vars we can interpolate the class name with #{} syntax.

  1. Declare the CSS var
:root {
  --co_palette-1: #ef476f;
  /* ... */
}
  1. Use the interpolation where it is called, for example in a @for loop
@for $i from 1 through 5 {
  .t-palette-color--#{$i} {
    background-color: var(--co_palette-#{$i});
  }
}

If we need to mantain SASS vars (in my code, I needed to use darken and lighten SASS function) we could interpolate classes name like this:

$co_palette-1: #ef476f;
$co_palette-2: #ffc233;
$co_palette-3: #06d6a0;
$co_palette-4: #1b98e0;
$co_palette-5: #ff9f1c;

:root {
  --co_palette-1: #{$co_palette-1};
  --co_palette-2: #{$co_palette-2};
  --co_palette-3: #{$co_palette-3};
  --co_palette-4: #{$co_palette-4};
  --co_palette-5: #{$co_palette-5};

  --co_palette-1--lighten: #{lighten($co_palette-1, 10%)};
  --co_palette-2--lighten: #{lighten($co_palette-2, 10%)};
  --co_palette-3--lighten: #{lighten($co_palette-3, 10%)};
  --co_palette-4--lighten: #{lighten($co_palette-4, 10%)};
  --co_palette-5--lighten: #{lighten($co_palette-5, 10%)};
}
@for $i from 1 through 5 {
  .t-palette-color--#{$i} .c-card::before {
    background-color: var(--co_palette-#{$i});
    color: var(--co_palette-#{$i}--lighten);
  }
}

Output:

.t-palette-color--1 .c-card::before {
  background-color: var(--co_palette-1);
  color: var(--co_palette-1--lighten);
}

.t-palette-color--2 .c-card::before {
  background-color: var(--co_palette-2);
  color: var(--co_palette-2--lighten);
}

.t-palette-color--3 .c-card::before {
  background-color: var(--co_palette-3);
  color: var(--co_palette-3--lighten);
}

.t-palette-color--4 .c-card::before {
  background-color: var(--co_palette-4);
  color: var(--co_palette-4--lighten);
}

.t-palette-color--5 .c-card::before {
  background-color: var(--co_palette-5);
  color: var(--co_palette-5--lighten);
}

More from this blog

Giulia Chiola's Blog

30 posts

Front-end Developer. ๐Ÿ‘พ Media engineer. โšก

Facing life one bug at a time. ๐Ÿ”ฅ Easily bribed with chocolate. ๐Ÿซ she/her