SCSS and the sassy ampersand.

By Bill Searle — Front-end Developer

What is SCSS?

Sass is an extension of CSS that adds power and elegance to the basic language. It allows you to use variables, nested rules, mixins,inline imports, and more, all with a fully CSS-compatible syntax. Sass helps keep large stylesheets well-organized, and get small stylesheets up and running quickly…

If you’re new to SCSS check out What’s so sassy about SCSS?, otherwise carry on and in this article we’re going to take a look at the SCSS reference selector: &.

& allows you to build more powerful nested selectors but with great power comes, a great chance of messing up…

In the intro we were nesting children elements or classes which generates hierarchical CSS.

// SCSS
.navigation {
ul {
background-color: #eee;
}
}
// Compiled CSS
.navigation ul {
background-color: #eee;
}

Using &

But what if we wanted to reference the parent, in this case .navigation?
Lets say we want to change the nav’s background colour by adding a new class, we can employ the & to chain the selectors.

// SCSS
.navigation {
// styles
&.nav-black { // <-- notice the &
// styles
}
}
// Compiled CSS
.navigation { }
.navigation.nav-black { }

& is really useful when using pseudo selectors:

// SCSS
a {
&:hover { }
&:visited { }
&:focus { }
}
// Compiled CSS
a:hover { }
a:visited { }
a:focus { }

You’re essentially copying the parent to where ever you place an &.

Seems pretty straightforward.

However…

The & selector doesn’t have to come first and now you can do some 🤔 things.

Remember you’re copying the parent to where ever you place an &, like this:

// SCSS
.some-fancy-effect {
// cool stuff IE doesn't support
body.ie & {
// ie fixes
}
}
// Compiled CSS
.some-fancy-effect { }
body.ie .some-fancy-effect { }

What we’re doing here is adding our parent to the end of a selector so now we can target it if our HTML body tag has a class of .ie. 
Even though we’re nested inside .some-fancy-effect the compiler escapes it.
It’s not quite traversing up the DOM, still need JS for that but this is still super handy!

Where you can fall down with using the & is in the detail, white space here makes a big difference, just as it does in CSS. 
One missing space and your generated code produces something completely different, perfectly valid but not what you were aiming for:

// SCSS
.some-fancy-effect {
// cool stuff IE doesn't support
body.ie& { // <-- missed a space here
// ie fixes
}
}
// Compiled CSS
.some-fancy-effect { }
body.ie.some-fancy-effect { } // <-- not what we wanted

What else?

Well you could build modifier classes like this:

//SCSS
.some-fancy-effect {
&-large { }
&-small { }
}
// Compiled CSS
.some-fancy-effect-large { }
.some-fancy-effect-small { }

But don’t.

You’ll never be able to search the project for ‘.some-fancy-effect-large’ for one example.

Use the @extend directive instead, which is a nice segue into the topic I’ll write about next time.

Here’s some “weird and wacky” examples of what you can but shouldn’t do with &.
Full docs are here.

Enjoy!

Show your support

Clapping shows how much you appreciated Mentally Friendly’s story.