Generating css classes the lazy way with sass

Sometime you have to create a lot of css classes which are basically the same, except for one property (color, size, content, ...). This is an annoying task, but luckily, it can be done with some scss/sass magic.

I use the following technique to generate modifier classes, often used for products, iconfonts, etc.

Imagine, you're creating a website for a company who sells t-shirts, these t-shirts come in all kinds of colors. Now If you want to change the text-color to match the color of the current t-shirt's color, you could start to create a bunch of classes.

.shirt {
    /* Basic styles */
}

.shirt--green {
    color: green;
}

.shirt--red {
    color: red;
}

.shirt--blue {
    color: blue;
}

...

This is a repetitive task which we can simply automate a bit by using an each function.

$colors: (
    green #00FF00,
    red #FF0000,
    blue #0000FF
);

@each $color in $colors {
    .shirt--#{nth($color,1)} {
        color: nth($color,2);
    }
}

The code above will simply generate the classes from the first example. If you want to add a new color, you can just add it to the colors list. If you want to a property to the class, you can just add it in one place, and done.

You can even create a lot of different classes based on the colors we've specified.

$colors: (
    green #00FF00,
    red #FF0000,
    blue #0000FF
);

@each $color in $colors {
    .shirt__title--#{nth($color,1)} {
        color: nth($color,2);
    }

    .shirt__background--#{nth($color,1)} {
        background-color: nth($color,2);
    }
}

One of the situations in which I like to use this technique is with an iconfont. When you add new icons to the iconfont, all it takes is to add the new icon to the icons list.

$icons: (
    caret--top "\e600",
    caret--right "\e601",
    caret--bottom "\e602",
    caret--left "\e603"
);

@each $icon in $icons {
    .icon--#{nth($icon,1)}:before {
        content: quote(nth($icon,2));
    }
}
Sam Bellen
Sam Bellen

I'm a software engineer at @madewithlove. I like playing around with the web-audio-api, and all things front-end related.