SyntaxStudy
Sign Up
SASS / SCSS The & Selector in Advanced Patterns
SASS / SCSS Beginner 1 min read

The & Selector in Advanced Patterns

The parent selector `&` is more flexible than it first appears. It can be placed at the end of a selector to flip the nesting relationship — a technique useful when a parent context modifier should change the appearance of a child element. For instance, writing `.theme-dark & { color: white; }` inside a nested rule generates a selector where `.theme-dark` is an ancestor of the current element. When `&` appears in the middle or at the end of a selector string (rather than at the beginning), SASS refers to this as a "suffixed parent selector." Combined with string interpolation using `#{}`, the parent selector can be used to dynamically build selectors inside loops and mixins, enabling powerful automated generation of utility classes or modifier variants. Modern SASS also supports the `@at-root` directive, which moves a nested rule out of its ancestor context and places it at the root of the stylesheet. This is particularly useful when generating a completely independent selector (such as a keyframe name or a top-level utility class) from within a nested block where the context is useful for organisation but should not appear in the compiled selector.
Example
// ── & at the end — inverting the nesting direction ───────────────────────────

.button {
    background: #3498db;
    color     : #fff;
    padding   : 0.6rem 1.2rem;

    // Generates: .theme-dark .button
    .theme-dark & {
        background: #1a252f;
        border    : 1px solid #5dade2;
    }

    // Generates: .sidebar .button
    .sidebar & {
        display: block;
        width  : 100%;
    }
}

// ── String interpolation with & ───────────────────────────────────────────────

$sizes: sm, md, lg;

@each $size in $sizes {
    .btn-#{$size} {
        // & refers to .btn-sm, .btn-md, .btn-lg in turn
        &:hover { opacity: 0.85; }
        &:active { transform: translateY(1px); }
    }
}

// ── @at-root ─────────────────────────────────────────────────────────────────

.component {
    $anim-name: component-fade;  // local variable, useful for context

    color: #333;

    // @at-root moves this rule to the stylesheet root — no .component prefix
    @at-root {
        @keyframes #{$anim-name} {
            from { opacity: 0; transform: translateY(-8px); }
            to   { opacity: 1; transform: translateY(0); }
        }
    }

    &.is-visible {
        animation: $anim-name 0.3s ease-out;
    }
}