Skip to content

Sass: Referencing Parent Selectors

How to use the & character in Sass/SCSS to reference parent selectors and nest child selectors like hover states for cleaner, more maintainable CSS.

You can select the parent selector by using the & character. It tells where the parent selector should be inserted. The & is replaced at compile time by the full selector of the enclosing rule block, which lets you write pseudo-classes, compound selectors, and suffix-style modifiers without leaving the nesting context.

Example

Example of parent selectors in a SCSS file:

<html>
   <head>
      <title>Referencing Parent Selectors</title>
      <link rel="stylesheet" type="text/css" href="style.css" />
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
   </head>

   <body>
      <div class="container">
         <h1>Example using Parent Selector</h1>
         <a href="http://www.example.com/"> www.example.com </a>
      </div>
   </body>
</html>

and the style.scss file:

a {
   font-size: 20px;
   &:hover { background-color: yellow; }
}

Then you tell Sass to watch the file and update the CSS when the file changes:

sass --watch my\path\style.scss:style.css

The generated style.css files is as shown below:

a {
   font-size: 20px;
}

a:hover {
   background-color: yellow;
}

How & works

When Sass compiles a nested rule, it takes the selector of the outer rule and substitutes it wherever & appears in the inner rule. If you omit &, Sass simply concatenates the outer and inner selectors with a descendant combinator (a space). Using & changes where the parent selector is placed, which is what makes pseudo-classes and compound selectors possible.

Nesting style SCSS Compiled CSS
Descendant (no &) a { span { } } a span { }
Pseudo-class with & a { &:hover { } } a:hover { }
Compound selector with & a { &.active { } } a.active { }
Suffix with & .btn { &-primary { } } .btn-primary { }

Adding suffixes to the parent selector

& is not limited to pseudo-classes. Because it is literally replaced by the parent selector text, you can attach a suffix directly to it to build compound class names. This is the technique behind methodologies such as BEM:

.button {
   display: inline-block;
   padding: 10px 16px;

   &--primary  { background-color: blue;  color: white; }
   &--secondary { background-color: gray;  color: white; }
   &__icon     { margin-right: 6px; }
}

Compiles to:

.button {
   display: inline-block;
   padding: 10px 16px;
}
.button--primary {
   background-color: blue;
   color: white;
}
.button--secondary {
   background-color: gray;
   color: white;
}
.button__icon {
   margin-right: 6px;
}

Multiple parent references

You can use & more than once inside the same nested rule, for example to target a parent that is a descendant of another element:

.nav {
   .container & {
      color: navy;
   }
}

Compiles to:

.container .nav {
   color: navy;
}

Here & is .nav, so .container & becomes .container .nav instead of .nav .container.

Combining with pseudo-class arguments

& also works with pseudo-classes that take an argument, such as :not(), :nth-child(), or :is():

.list {
   &:not(:first-child) { margin-top: 8px; }
   &:nth-child(odd)    { background-color: #f7f7f7; }
}

Compiles to:

.list:not(:first-child) {
   margin-top: 8px;
}
.list:nth-child(odd) {
   background-color: #f7f7f7;
}

Interactive state example

A common real-world use is grouping all the interactive states of a link or button together inside the base rule:

.link {
   color: blue;
   text-decoration: none;

   &:visited  { color: purple; }
   &:hover    { color: darkblue; text-decoration: underline; }
   &:active   { color: red; }
   &:focus    { outline: 2px solid orange; }
}

Compiles to:

.link {
   color: blue;
   text-decoration: none;
}
.link:visited {
   color: purple;
}
.link:hover {
   color: darkblue;
   text-decoration: underline;
}
.link:active {
   color: red;
}
.link:focus {
   outline: 2px solid orange;
}

A note on the parent selector context

& always refers to the full parent selector chain, not just the nearest one. When nesting several levels deep, the entire chain up to that point is substituted:

.card {
   .title {
      &::after { content: ""; }
   }
}

Compiles to:

.card .title::after {
   content: "";
}

If you need the immediate parent only, restructure the nesting or use @at-root to lift a rule out of the nesting context.

Summary

  • & is replaced by the full enclosing selector at compile time.
  • Use &:hover, &:focus, etc. to keep pseudo-class states inside their base rule.
  • Use &.class for compound selectors and &-suffix / &__element for naming conventions like BEM.
  • & can appear more than once and can be placed anywhere in a nested selector to change where the parent is inserted.
  • For deeper control over the nesting context, combine & with @at-root.
Navigation