Even Better @each loops with Sass 3.3

In the not to distant future Sass 3.3 is going to land for the masses outside of it’s pre-release cycle. I’ve already discussed how they’ve now made things like BEM in your CSS even easier. So I’d thought I’d touch on something else that’s on it’s way that’s pretty Sass-y.

With Sass 3.2 you can easily generate some CSS based on a list of ‘things’. Perhaps you wanted to have some social links on a site and wanted to have the background of each relevant link the association colour of that social network.

You’d probably make some variables like this to start with:

$Twitter: #41b7d8;
$FB: #3b5997;
$GPlus: #d64937;
$LinkedIn: #0073b2;

You could then add these into a list ready to be pulled into the @each loop:

$social-colours: $Twitter, $FB, $GPlus, $LinkedIn;

You’d then write some Sass like this to get the @each to loop through the list and generate the relevant CSS:

li {
  float: left;
  height: 48px;
  list-style: none;
  width: 100%;    
}
@for $i from 1 through length($social-colours) {
  li:nth-of-type(#{$i}) {
    background: nth($social-colours, $i);
  } 
}

That in turn, when printed out would give a result like this:

ul li {
  float: left;
  height: 48px;
  list-style: none;
  width: 100%;
}
ul li:nth-of-type(1) {
  background: #41b7d8;
}
ul li:nth-of-type(2) {
  background: #3b5997;
}
ul li:nth-of-type(3) {
  background: #d64937;
}
ul li:nth-of-type(4) {
  background: #0073b2;
}

That in itself is pretty cool right? You may want to add another link at a later date. All you’ve gotta do is tap on another colour (or $variable) at the end and it’d get printed out in your CSS.

But we want more than one thing in the list

As you can see from the example above I’ve used nth-of-type to style each li differently. What if I wanted to give my li a class of the relevant social network? Perhaps I want to add an icon in each li too?

Well you could create more lists, but that can be a bit cumbersome and isn’t as tidy as answer.

With Sass 3.3 you have the ability to have can create a list of lists and then use the @each directive to make some Sass-y outputted CSS.

So going back to our crude example. Rather than use nth-of-type let’s give each printed li it’s own class name relevant to the social network.

Keeping our original set of variables above we could then make a new list like this:

$social: (twitter, $Twitter),
        (facebook, $FB),
        (googleplus, $GPlus),
        (linkedin, $LinkedIn);

So above you can see from a glance what’s going on, nice and simple. Now lets uses those lists in the list to create some CSS.

@each socialnetwork, color in $social { }

Here we’ve given the two lists in the list social their own variable to be called upon in the curly braces. Let’s add more code.

@each $socialnetwork, $color in $social {
  .social-link--#{$socialnetwork} {
    background-color: $color;
    &:focus, 
    &:hover {
      background-color: darken($color,5%);
    }    
  }
}

So here we’ve used the color as before but added the social network into the classname. This prints out some CSS like this:

.social-link--twitter {
  background-color: #41b7d8;
}
.social-link--twitter:focus,
.social-link--twitter:hover {
  background-color: #2cafd4;
}

.social-link--facebook {
  background-color: #3b5997;
}
.social-link--facebook:focus,
.social-link--facebook:hover {
  background-color: #344e85;
}

.social-link--googleplus {
  background-color: #d64937;
}
.social-link--googleplus:focus
.social-link--googleplus:hover {
  background-color: #ca3c29;
}

.social-link--linkedin {
  background-color: #0073b2;
}
.social-link--linkedin:focus
.social-link--linkedin:hover {
  background-color: #006399;
}

That’s pretty cool. Generating some tidy CSS through the new @each directive. You could then perhaps add a background icon if you wanted too. Just simply add another line of code to the example:

@each $socialnetwork, $color in $social {
  .social-link--#{$socialnetwork} {
    background-color: $color;
    &:focus,
    &:hover {
      background-color: darken($color,5%);
    }    
    &:before {
      background-image: url('/images/#{$socialnetwork}.png');
    }
  }
}

We’re getting somewhere nice and awesome here and this is just a quick example. I’m really looking forward to 3.3 dropping for real. I think it’s pretty stable at the moment to give it a whirl. Don’t forget it’s now available in CodePen and Sassmeister.

The example above is available here to peruse and pick apart

How do you think you can make use of the new lists within lists @each directive?


So you obviously love Sass. So how about signing up to a weekly newsletter of all things Sass direct to your inbox, curated by me?