Sass and Compass Designer's Cookbook
上QQ阅读APP看书,第一时间看更新

Referencing parent selectors with the & sign

In Sass, you can use the ampersand (&) sign to reference the parent selector in the nested code. Referencing the parent can be useful to create constituted selectors from your nested code.

Getting ready...

In this recipe, you will have to compile your SCSS into CSS code. You can use the Ruby Sass compiler to do this. More information on the Ruby Sass compiler can be found in the Installing Sass for command line usage recipe of Chapter 1, Getting Started with Sass. Alternatively, you can also use SassMeister to compile your code. SassMeister is an online compiler for Sass, Compass, and LibSass. You can read more about SassMeister in the Playing on SassMeister recipe of Chapter 2, Debugging Your Code.

How to do it...

Learn how to use parent selectors in your Sass code to create maintainable code:

  1. Create a Sass template called main.scss that will contain the following SCSS code:
    // scss-lint:disable ColorKeyword
    
    $link-color: black;
    $hover-color: red;
    
    .link {
      color: $link-color;
    
      &:hover {
        color: $hover-color;
      }
  2. Compile the main.scss file from the previous step into CSS code by running the following command in your console:
    sass main.scss
    
  3. You will find that the CSS code outputted to your console will look as follows:
    .link {
      color: black; }
      .link:hover {
        color: red; }

How it works...

A CSS pseudo-class is a keyword added to selectors that specifies a special state of the element to be selected. The most well-known pseudo-class is the :hover pseudo-class that describes the mouse hover state of an element. In contrast to pseudo-classes, CSS pseudo-elements do not describe the states of an element; they select certain parts of your document. The most well-known pseudo-elements are the ::before and ::after pseudo-elements.

In this recipe, you can see how to create a .link selector with :hover pseudo-class. In your code, the & reference will be replaced with the parent selector as it appears in the CSS.

Nested selectors are concatenated with a space between them by default. The & reference can be used to avoid the space between the selectors.

When your nesting is more than one level deep, the parent selector will be fully resolved before the & reference is replaced. The following SCSS code makes the meaning of this clear:

// scss-lint:disable ColorKeyword

$link-color: black;
$hover-color: red;

p {
  .link {
    &:hover {
      color: $hover-color;
    }
  }
}

The preceding SCSS code compiles into CSS code as follows:

p .link:hover {
  color: red; }

As you can see, the p .link selector is the compiled concatenated selector.

The & reference is very useful for compiling pseudo classes and pseudo elements. The & reference helps you clarify the relation between the selector and the pseudo classes and elements. Nesting of pseudo classes and pseudo elements improves the readability of your code and makes it easier to maintain.

You can also use the & reference to merge two compound selectors. The following SCSS code will show you how to merge two compound selectors:

.test {
    &-link {
      display: none;
    }
}

The preceding SCSS code compiles into CSS code like that shown here:

.test-link {
  display: none; }

Also, in case you have to concatenate two selectors without a space, you can use the & reference. An SCSS code like that shown here concatenates two selectors into one:

.first {
  &.second {
    width: 90%;
  }
}

The preceding SCSS code compiles into CSS code as follows:

.first.second {
  width: 90%; }

Here, .first.second selects HTML elements having both the .first and .second classes.

Finally, the & reference can also be used with variable interpolation. Read more about variable interpolation in the Interpolation of variables recipe of Chapter 3, Variables, Mixins, and Functions. An example of variable interpolation and the & reference can be found when compiling the following SCSS:

$name: test;

.#{$name} {
  display: inline-block;
 
  @at-root {
    .ie8-#{$name} {
    display: block;
    }
  }
}

The preceding SCSS compiles into CSS code like that shown here:

.test {
  display: inline-block; }
  .ie8-test {
    display: block; }

You can read more about the @at-root directive used here in the Emitting rules at the root of the document recipe of this chapter.

There's more...

When you use the & reference in SassScript, it will also reference the parent selectors and will be set to null if there is no parent selector. Consider the following example SCSS code:

// scss-lint:disable PropertySpelling

selector1,
selector2 {
  $var: &;
  value: $var;
}

The preceding SCSS code compiles into CSS code like that shown here:

selector1, selector2 {
  value: selector1, selector2; }

Note that the & reference in SassScript always is a comma-separated list of space-separated lists, even if the parent selector does not contain a comma or space. You can read more about the built-in list functions of Sass in the List functions recipe of Chapter 5, Built-in Functions. The following SCSS code will show you that the & reference in SassScript is a list (or null) indeed:

// scss-lint:disable PropertySpelling

@mixin parent-selector() {
  length: length(&);
}
 
p {
  @include parent-selector;
}

a,
b {
  @include parent-selector;
}
The SCSS code above compiles into CSS code as follows:
p {
  length: 1; }

a,
b {
  length: 2; }

As you can see, the & reference is a list, which indeed can be used as an argument for the Sass length() built-in function, in the preceding code.