The ampersand (&) is a wonderful little character. It’s an ancient symbol, a ligature of the Latin “Et,” that connects words, phrases, and thoughts. Today, the use of & has become more varied, but & still maintains its original meaning of and, as well as, or this too. In Sass, & references the parent selector of a declaration block, allowing the selector to be referenced from within itself. This means things like pseudo selectors, sibling selectors, and so on can be referenced and grouped with that selector’s other declarations. & is a powerful tool to organize and extend your Sass.
Pseudo Class Selectors
One of the most common uses for & in my Sass is pseudo class selectors. These include the :hover
, :active
, and :focus
found accompanying selectors like <a>
and <input>
. When utilizing & in Sass, a single declaration block can be written for <a>
. Then from within the block, <a>
can be referenced with &:hover
, &:active
, and &:focus
.
Written in Sass
a {
color: #0090B2;
&:hover {
color: #FF7A00;
}
&:active {
color: #B25500;
}
}
Generated CSS
a {
color: #0090B2;
}
a:hover {
color: #FF7A00;
}
a:active {
color: #B25500;
}
See this example on Sassmeister
These pseudo selectors are just the beginning though, :nth-child
, :target
, :checked
, and many more await.
Add a Class or an ID
Since & references the top-most selector, it can be extended with additional classes and/or an id like the pseudo class selectors. So let’s say there is a selector of .feature-class
and we have an instance where it will be paired with .style-class
, which changes the look of it. From within the .feature-class
declaration block, we would have a child declaration that starts like this: &.style-class
with its own declaration block. Sass will replace &
with .feature-class
, which becomes .feature-class.style-class
in our generated CSS. So let’s update the example and replace the element selector <a>
with the class selector .feature-class
.
Written in Sass
.feature-class {
color: #0090B2;
&:hover {
color: #FF7A00;
}
&:active {
color: #B25500;
}
&.style-class {
color: #00CEFF;
&:hover {
color: #0090B2;
}
&:active {
color: #FF7A00;
}
}
}
Generated CSS
.feature-class {
color: #0090B2;
}
.feature-class:hover {
color: #FF7A00;
}
.feature-class:active {
color: #B25500;
}
.feature-class.style-class {
color: #00CEFF;
}
.feature-class.style-class:hover {
color: #0090B2;
}
.feature-class.style-class:active {
color: #FF7A00;
}
See this example on Sassmeister.
Notice, the &.style-class
declaration block had its own &:hover
and &:active
which allowed pseudo class selectors for just the instances of the combined classes. While it is possible to go deeper, much like Inception, beyond four levels becomes disorienting and difficult to manage.
Parent Selectors Within Child Selectors
The key to understanding the power of & in Sass is its placement in a declaration. In the first two examples, & was the first character, but there are cases where & can be used later in a declaration. In situations where the parent containing the selector causes the styles of the selector to change, we can reference the parent selector from within the selector’s declaration block. This is done by adding the parent selector before & in a new declaration block. So, if our class .feature-class
needs to change when a child of .parent-class
, we can make these changes from within the .feature-class
declaration block.
Written in Sass
.feature-class {
color: #0090B2;
.parent-class & {
color: #00CEFF;
}
}
Generated CSS
.feature-class {
color: #0090B2;
}
.parent-class .feature-class {
color: #00CEFF;
}
See this example on Sassmeister.
This feature comes in quite useful when targeting Internet Explorer with conditional classes on the <html>
tag. Simply add a .lt-ie9 &
within a declaration block to add any IE 8 or less styles to a selector.
Siblings
My absolute favorite way to utilize & is with adjacent sibling selectors. These types of selectors occur whenever you have a selector that needs to change when it is next to another selector. Most often, I use adjacent sibling selectors to modify layout when the same selector is side by side in HTML, like cases of paragraphs or list items that are commonly found in multiples next to one another. For a simple example, we’ll make <p>
have no margin, but when a <p>
is next to another <p>
we’ll add a margin between the two.
Written in Sass
p {
margin: 0;
line-height: 1.5em;
& + & {
margin-top: 1em;
}
}
Generated CSS
p {
margin: 0;
line-height: 1.5em;
}
p + p {
margin-top: 1em
}
See this example on Sassmeister.
Of course, when it comes to adjacent sibling selectors, you’re not limited to the same selector in each instance. Perhaps you don’t want a margin after an <h1>
unless it is followed by the appropriate sub heading.
Written in Sass
h1, h2, h3 {
margin: 0;
}
h1 {
& + h2 {
margin-top: 1em;
}
}
Generated CSS
h1, h2, h3 {
margin: 0;
}
h1 + h2 {
margin-top: 1em;
}
See this example on Sassmeister.
Similarly, both general siblings and child combinator selectors can utilize this method to write appropriate styles for a declaration block by replacing +
with ~
and >
respectively.
Conclusion
Clearly, we have only begun to broach the power of & in Sass. Much more can be done to utilize & by mixing a combination of the formats discussed. Maybe you’ll have circumstances where you need to target the selector’s sibling, but only when it has a particular parent (e.g. .parent-class & + .sibling-class
). At that point, you can take & to the next level by using it with mixins and extends to make wonderfully usable code—sky’s the limit. So dream big, but not too deep.
Sparkbox’s Development Capabilities Assessment
Struggle to deliver quality software sustainably for the business? Give your development organization research-backed direction on improving practices. Simply answer a few questions to generate a customized, confidential report addressing your challenges.