Thoughts on Managing Colors in Sass Projects

While working on building out a site from PSD comps, it is common to want to extract colors into a single location and name them to facilitate reuse and bring some consistency to the final pages. However, depending on how many colors are at play in the site, this can be a non-trivial activity.

I’m going to take this post to just walk through some of the things that I’ve tried and where I’m currently at in my thinking. I don’t have a solution but I’m hoping that just documenting my ideas and thought processes can help create new ideas or initiate a dialog with other people who are struggling with the same thing.

I started out trying to create a bunch of named variables in a _variables.scss file with a $color- prefix. This sort of worked but it became a bit unwieldy over time. Especially because I would frequently be getting comps and building pages over a period of days or weeks and a particular color variable name wouldn’t necessarily be appropriate for later usage.

A colleague of mine suggested using a map to keep track of colors. This was a little better in that it made for shorter names (since the prefix was in the variable name) but I still had to come up with appropriate names (one of the only 2 hard things in computer science).

In my current project, I’m trying a different tact. I’m using a map for colors but I’m only putting in colors that have very easy to determine names. Any other color I’m putting in the SCSS source as an actual hex or rgb value – but I’m also flagging it with a comment:

.module__title {
  @include font-light(40px);
  padding-bottom: 24px;
  border-bottom: 1px solid #ced8e1; // TODO color
  color: project-color(text);
  text-align: center;
}

This way I can go back towards the end of the project and pull out all of the colors that have been used and decide on appropriate names. (Thinking about it now, I probably should not use // TODO color, but something like // [COLOR].) This approach of “mark and sweep” won’t help much during the development of a project, but will hopefully help while maintaining because.

Another thing that I’ve added this time is a helper function to get a color from the $project-colors map when I am re-using a named color. Typing out map-get($project-colors, accent) started getting annoying and I didn’t like how it spread implementation details throughout the code. A better solution was to create the project-color() function:

@function project-color($name) {
  $_return: #fff;

  @if map-has-key($project-colors, $name) {
    $_return: map-get($project-colors, $name);
  } @else {
    @error "The color named #{$name} is not defined in $project-colors";
  }

  @return $_return;
}

This lets me gracefully handle colors that don’t exist and keep all of the implementation details of how I’m actually storing the named colors in one place.

Closing

As I said before, I don’t have a solution, but I’ve got a process that feels like it’s working. If you have ideas on how to make the system better or a different approach, I’d love to hear them.