How does the ampersand work in styled-components?

One of the features of styled-components was the SCSS-like syntax it supports. This is achieved thanks to the use of stylis - a lightweight CSS preprocessor. In this article, I'll explain what the ampersand does.

How it works

The & syntax isn't specific to styled-components and comes from SASS, where it means "current selector". In other words & always refers to the parent selector when nesting. Think of the & as being removed and replaced with the parent selector. This is why in SASS this:

.some-class {
  &.another-class {}
}

Equals this:

.some-class.another-class { }

The syntax in styled-components is a bit different though, we don't have a parent selector per se. The & in the case below refers to the styled-component itself Thing.

const Thing = styled.div`
  color: blue;
  &:hover {
    color: red; // <Thing> when hovered
  }
  & ~ & {
    background: tomato; // <Thing> as a sibling of <Thing>, but maybe not directly next to it
  }
  & + & {
    background: lime; // <Thing> next to <Thing>
  }
  &.something {
    background: orange; // <Thing> tagged with an additional CSS class ".something"
  }
  .something-else & {
    border: 1px solid; // <Thing> inside another element labeled ".something-else"
  }
`

Increasing specificity

In styled-components's documentation it's mentioned that you can use a && to increase specificity. Using more than one & at the same time doesn't work any differently than using a single one - it just multiplies the effect. So a style like this:

.some-class {
  &&.another-class {}
}

Would equal this:

.some-class.some-class.another-class { }

Adding the same class more than once is allowed in the class attribute. Both instances will be recognized for the same element, but will be treated as one class with higher specificity.

Yes, if && isn't able to override your CSS you can use a triple &&& or quadruple ampersand, however, if your CSS is that specific, you may want to refactor how it's being used in the DOM.