Ampersand can also be used to concatenate additional class names (or IDs, etc.) into a compound selector for higher priority (instead of adding another descendant selector).
While nesting is the most popular feature of Sass it’s also the most abused, as increased specificity means less performant CSS selectors and it’s really easy to get carried away.
When I build a site, I break out component styles into separate files where the file name generally matches the top-most selector.
For example, I would have a file named _pagination.scss, that started with a top level selector of .pagination. From there, all pagination related rulesets are contained within this declaration block by using nesting and the ampersand. Among the other benefits of nesting that I’ve alluded to earlier, this means that when another developer has to work on a component, they only need to look in one place!
Putting together what we’ve looked at so far, that pagination file could look something like this:
.pagination {
&-number {
// & = .pagination-number
&.is-current {
border: 3px solid green;
}
}
// & = .pagination
&-prev {
background-color: red;
// & = .pagination-prev
&:after {
content: '<';
}
}
}
// which compiles to
.pagination-number.is-current {
border: 3px solid green;
}
.pagination-prev {
background-color: red;
}
.pagination-prev:after {
content: '<';
}
The & comes in handy when you’re nesting and you want to create a more specific selector, like an element that has both of two classes, like this:
.some-class.another-class { }
You can do this while nesting by using the &.
.some-class {
&.another-class {}
}
https://css-tricks.com/the-sass-ampersand/
Now case when I need one class to be descendant of another
.parent {
.child {}
}
This can actually be thought of as short-hand for nesting with the &:
.parent {
& .child {}
}
So, these two examples both compile to the same thing:
`.parent .child {}“
Now real-life example (This one is hugely useful to control ng-select styles when appendTo=”body” is passed )
I have following selector
Note, a single space without comma means its a descendant selector relation.
.a .b will select any B that are inside A, even if there are other elements between them.
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option {
@include sdk-ng-select-typography-pad();
border-bottom: 1px solid #ebebeb;
border-width: thin;
&.ng-option-selected .ng-option-label {
@include sdk-text-body();
}
.ng-option-selected.ng-option-marked .ng-option-label {
@include sdk-text-body();
}
}
But I want apply the above styles both for the above case which is below
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option {
...some styles
}
AND also for the below case, i.e. instead of ONLY .ng-dropdown-panel as above, I also want to capture the cases, when both classes are present, like below – and then the rest of the descendants follow
.ng-dropdown-panel.sdk-ng-select
which will be below
.ng-dropdown-panel.sdk-ng-select .ng-dropdown-panel-items .ng-option {
...some styles
}
The brute force way would be to almost duplicate the above styles selectors with another like below.
&.ng-dropdown-panel.sdk-ng-select .ng-dropdown-panel-items .ng-option {
@include sdk-ng-select-typography-pad();
border-bottom: 1px solid #ebebeb;
border-width: thin;
&.ng-option-selected .ng-option-label {
@include sdk-text-body();
}
.ng-option-selected.ng-option-marked .ng-option-label {
@include sdk-text-body();
}
}
But a much better way to do it is as below
.ng-dropdown-panel,
&.ng-dropdown-panel.sdk-ng-select {
.ng-dropdown-panel-items .ng-option {
@include sdk-ng-select-typography-pad();
border-bottom: 1px solid #ebebeb;
border-width: thin;
&.ng-option-selected .ng-option-label {
@include sdk-text-body();
}
.ng-option-selected.ng-option-marked .ng-option-label {
@include sdk-text-body();
}
}
}



