The most common use for Sass variables is to assign single values for easy implementation and updating of styles in a project. Instead of having multiple instances of color: #f00, changing $c-red: #f00 means all properties that reference that variable will be changed at once.

Sass variables can also do smore than help us easily change colors. They can hold strings of values as well. Whether that be a complex box-shadow value, a list of multiple values to use in a control directive, or a string of text.

For this particular post, I want to take a look at the idea of using variables to store strings of text to be used in the place of CSS selectors.

Strings as selectors

There are two pretty useful use cases for storing text strings as Sass variables, with the intent of using them as CSS selectors.

For our first example, let’s say you have to work with an existing CSS framework, or other 3rd-party code that is brought into your website. You know you have a series of overlapping classes that could lead to some late nights of sorting out specificity between your code and theirs.

One very useful way to help differentiate the overlapping classes is to add your own specific prefix to your style library, like so:

.mycss--btn {
  /* ... */
}

.mycss--input {
  /* ... */
}

.mycss--header {
  /* ... */
}

Where mycss-- is how you can easily distinguish your classes from the 3rd-party CSS.

To set this up, and to make updating this name a seamless process, we would use a variable to store our personal selector prefix.

$my-name: mycss--;

.#{$my-name}btn {
  /* ... */
}

.#{$my-name}input {
  /* ... */
}

.#{$my-name}header {
  /* ... */
}

Update: March 8, 2014

So the night after I published this article, Sass 3.3 was released and with it came a handy new feature that can be used with the above example.

With Sass 3.3 we can now create a partial parent selector (our prefix mycss in this case) and use nested & to attached additional partial selectors to the root selector.

Where each of the selectors were separated by type, now we could nest them like so:

.#{$my-name} {

  &btn {/* ... */}

  &input {/* ... */}

  &header {/* ... */}
}

It compiles exactly the same as the previous example, but allows for organized nesting of selectors.

To read more about this new method of writing selectors, be sure to check out Stuart Robson’s post on “Even Easier BEMing with Sass 3.3”

The original method is still useful if you have a one-off instance of needing to apply a prefix, or if it doesn’t make sense to reorganize your classes, or if you need to apply this prefix across multiple files.

In the end, it’s likely that using a combination of both methods is really the ideal solution.

A second example

Another example of making partial selectors with variables is in using a variable lists combined with control directives.

For this example, let’s create a family of HTML element and class styles for headings. The following will allow me to create selectors for HTML elements, as well as class names to mimic comparable heading styles.

$prefix: txt;


$font-list: (
  h1   $prefix    3em     100,
  h2   $prefix    2.5em   100,
  h3   $prefix    2em     300,
  h4   $prefix    1.75em  300,
  h5   $prefix    1.5em   400,
  h6   $prefix    1.25em  400
);


@each $value in $font-list {
  #{nth($value, 1)},
  .#{nth($value, 2)}-#{nth($value, 1)} {
      font-size: nth($value, 3);
      font-weight: nth($value, 4);
    }
}

And here’s the compiled CSS.

h1,
.txt-h1 {
  font-size: 3em;
  font-weight: 100;
}

h2,
.txt-h2 {
  font-size: 2.5em;
  font-weight: 100;
}

h3,
.txt-h3 {
  font-size: 2em;
  font-weight: 300;
}

h4,
.txt-h4 {
  font-size: 1.75em;
  font-weight: 300;
}

h5,
.txt-h5 {
  font-size: 1.5em;
  font-weight: 400;
}

h6,
.txt-h6 {
  font-size: 1.25em;
  font-weight: 400;
}

Here I’ve created a variable to hold the prefix of txt. I did this in the off-chance that someday I may want to change this to heading or something else that I haven’t thought of yet, and editing one value is much easier than six. The rest of the example is to showcase how it could then be incorporated into an additional variable list and control directive. If you’re not familiar with control directives, read my article about them.

So those were two moderately useful examples of how to use variables in selectors.

Now here’s what you shouldn’t do…

$a-base: 'a, a:visited';
$a-hovers: 'a:hover, a:active';


#{$a-base} {
  color: $c-link;
  font-size: 1em;
  text-decoration: none;
}

#{$a-hovers} {
  color: $c-link-hover;
  text-decoration: underline;
}

The idea here is that by storing a string of selectors in a variable, you can write some leaner looking code. And you can…sort of.

There are some minor to larger problems with this particular example that I would like to examine.

First of all, unless you know you’ll be using this exact selector setup in other parts of your Sass, this doesn’t really save us from having to write any code, as it merely just moves our selectors into some variables instead of being associated with the properties that define it.

Now, if you do plan on reusing these selectors, nested in other elements, this can come in handy… to a point.

For example:

#{$a-base} {
  /* ... */
}

#{$a-hovers} {
  /* ... */
}

.sidebar {
  #{$a-base} {
    /* ... */
  }

  #{$a-hovers} {
    /* ... */
  }
}

Being able to reuse our variables in this setup has decreased the amount of code that we need to write a bit, and that’s always handy.

However, this doesn’t really help us out if we need to change individual selectors.

Since they’re part of the single Sass variable, if I need to change the a:hoverstate within the .sidebar but I need to keep the :active or :focus state the same, then I need to do one of the following:

.sidebar {
  #{$a-base} {
    /* ... */
  }

  #{$a-hovers} {
    /* ... */
  }

  a:hover {
    /* (alternate styling) */
  }
}

or

.sidebar {
  #{$a-base} {
    /* ... */
  }

  a:hover {
    /* (alternate styling) */
  }

  a:focus {
    /* (alternate styling) */
  }

  a:active {
    /* (alternate styling) */
  }
}

In the second example, I’ve had to just forgo my variable selector and re-write the individual selectors to modify their styling. This isn’t a bad thing, as it’s what I would have had to do if I weren’t using the variable anyway. But, it’s an issue here because I’m not reusing my variable, which then makes the variable less useful in general.

Final Thoughts

Using variables to store strings of text and values is quite useful. However, while the idea of adding entire selectors to a variable may seem like a good idea at first, there can be issues is overused.

As long as you don’t over engineer your Sass variables, you should be good to go!