# CSS nesting with &, &:hover, .dark & and @media

> Nest CSS rules with &, &:hover, .dark &, &-suffix, selector lists and @media inside rules. CSS Post Processor compiles it to flat CSS for every browser.

Source: https://csspp.dev/docs/nesting/


Write related rules inside each other and css-pp flattens them into ordinary CSS. The output works in every browser, including those without native CSS nesting.

## Children

A nested selector without `&` is a descendant of its parent:

```css
.card {
  padding: 1.5rem;
  h2 { margin: 0; }
  > footer { border-top: 1px solid #ddd; }
}
```

```css Output
.card{padding:1.5rem}
.card h2{margin:0}
.card > footer{border-top:1px solid #ddd}
```

## The parent reference `&`

`&` stands for the parent selector, wherever you put it:

```css
.button {
  &:hover        { filter: brightness(1.1); }   /* .button:hover */
  &.primary      { background: #0ea5e9; }       /* .button.primary */
  &-icon         { width: 1em; }                /* .button-icon (BEM) */
  .dark &        { color: #fff; }               /* .dark .button */
  & + &          { margin-left: .5rem; }        /* .button + .button */
  &:has(svg)     { gap: .5rem; }                /* .button:has(svg) */
}
```

The older `&{ ... }` block, which styles the parent itself, still works and can go anywhere in the rule:

```css
.panel {
  h3 { font-size: 1.1rem; }
  &{ background: #fff; padding: 1rem; }
}
```

## Selector lists

Lists on either side combine every parent with every child:

```css
.alert, .toast {
  a, button { font-weight: 600; }
}
```

```css Output
.alert a,.toast a,.alert button,.toast button{font-weight:600}
```

Commas inside functional pseudo-classes are not list separators, so `:is()`, `:where()`, `:not()` and `:has()` work inside nested rules:

```css
.nav {
  a:is(:hover, :focus-visible) { text-decoration: underline; }
  li:has(> a.active, > a[aria-current]) { font-weight: 600; }
}
```

## @media inside rules

Put a media query, `@supports` or `@container` block inside a rule and css-pp moves it out for you:

```css
.sidebar {
  width: 18rem;
  @media (max-width: 768px) {
    width: auto;
    .widget { display: none; }
  }
}
```

```css Output
.sidebar{width:18rem}
@media (max-width:768px){
.sidebar{width:auto}
.sidebar .widget{display:none}
}
```

## Order is preserved

Declarations and nested rules are written out in the order you wrote them, the same way native nesting works. Declarations after a nested rule become a second rule for the same selector, so they still come later in the cascade.

## Combining with the other features

Nesting works with every css-pp feature:

```css
.gallery {
  > figure {
    background-image: url(/img/photo-$[index].jpg);
    &:not(:seen) { opacity: 0; }
  }
  &:has(figure:overflowing) .hint { display: block; }
}
```
