Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sass referencing parent selectors using the ampersand character within nested selectors

Tags:

css

sass

Just when I thought Sass was the coolest thing since sliced bread, it had to go and let me down. I'm trying to use the ampersand to select a parent of a nested item. It's a complex selection and its returning some unexpected results...

My sass:

.page--about-us {
  a {
    text-decoration:none;
  }
  .fa-stack {
    .fa {
      color:pink;
    }
    a & {
      &:hover {
        .fa-circle-thin {
          color:red;
        }
        .fa-twitter {
          color:blue;
        }
      }
    }
  }
}

Outputted CSS:

.page--about-us a {
  text-decoration: none;
}
.page--about-us .fa-stack .fa {
  color: pink;
}
a .page--about-us .fa-stack:hover .fa-circle-thin {
  color: red;
}
a .page--about-us .fa-stack:hover .fa-twitter {
  color: blue;
}

Expected Output (Note the placement of the a tag):

.page--about-us a {
  text-decoration: none;
}
.page--about-us .fa-stack .fa {
  color: pink;
}
.page--about-us a .fa-stack:hover .fa-circle-thin {
  color: red;
}
.page--about-us a .fa-stack:hover .fa-twitter {
  color: blue;
}

Demo: http://sassmeister.com/gist/8ed68bbe811bc9526f15

like image 847
Adam Youngers Avatar asked Oct 23 '14 00:10

Adam Youngers


People also ask

What does the ampersand & symbol do in Sass SCSS?

Ampersand or “&” is a powerful feature of SASS. It enhances the readability of code by using nesting statements, which takes an edge over conventional CSS. We can nest the css class any number of times but most of the times it's not required.

Which symbol is used to refer parents selector in sass?

Sass lets you reference the parent selector of a nested rule using the ampersand (&) symbol –– it's one of Sass' most useful features!


2 Answers

You can store the parent selector in a variable!

Take the following BEM-like SASS:

.content-block {
    &__heading {
        font-size: 2em;
    }

    &__body {
        font-size: 1em;
    }

    &--featured {
        &__heading {
            font-size: 4em;
            font-weight: bold;
        }
    }
}

The selector inside of .content-block--featured is going to be .content-block--featured .content-block--featured__heading which might not be what you're after.

It's not as elegant as the single ampersand but you can stash the parent selector into a variable! So to get what you might be after from the above example without hard-coding the parent selector:

.content-block {
    $p: &; // store parent selector for nested use

    &__heading {
        font-size: 2em;
    }

    &__body {
        font-size: 1em;
    }

    &--featured {
        #{$p}__heading {
            font-size: 4em;
            font-weight: bold;
        }
    }
}

So, OP, in your case you might try something like this:

.page--about-us {
    $about: &; // store about us selector

    a {
        text-decoration:none;
    }

    .fa-stack {
        .fa {
            color:pink;
        }

        #{$about} a & {
            &:hover {
                .fa-circle-thin {
                    color:red;
                }
                .fa-twitter {
                    color:blue;
                }
            }
        }
    }
}
like image 116
Michael Thompson Avatar answered Nov 11 '22 07:11

Michael Thompson


This is the normal behavior, as described in Sass documentation (link):

& will be replaced with the parent selector as it appears in the CSS. This means that if you have a deeply nested rule, the parent selector will be fully resolved before the & is replaced.

Meaning:

.foo {
  .bar {
    .baz & {
      color: red;
    }
  }
}

Will render as:

.baz .foo .bar {
  color: red;
}

And not:

.baz .bar {
  color: red;
}

The right way to get your expected result is this one:

.page--about-us {
  a {
    text-decoration:none;

    .fa-stack:hover {
      .fa-circle-thin {
        color:red;
      }
      .fa-twitter {
        color:blue;
      }
    }
  }
  .fa-stack {
    .fa {
      color:pink;
    }
  }
}
like image 28
zessx Avatar answered Nov 11 '22 07:11

zessx