Sass .scss: ¿Anidamiento y clases múltiples?

332

Estoy usando Sass (.scss) para mi proyecto actual.

Siguiente ejemplo:

HTML

<div class="container desc">
    <div class="hello">
        Hello World
    </div>
</div>

SCSS

.container {
    background:red;
    color:white;

    .hello {
        padding-left:50px;
    }
}

Esto funciona muy bien.

¿Puedo manejar múltiples clases mientras uso estilos anidados?

En la muestra anterior, estoy hablando de esto:

CSS

.container.desc {
    background:blue;
}

En este caso, todo div.containersería normalmente redpero div.container.descsería azul.

¿Cómo puedo anidar esto dentro containercon Sass?

mate
fuente
1
Deberías usar un selector de clase doble. Este problema es un ejemplo perfecto de la opción de anidación en Sass. Puede leer todo sobre eso aquí kolosek.com/nesting-in-less-and-sass
Nesha Zoric

Respuestas:

571

Puede usar la referencia del selector principal & , será reemplazado por el selector principal después de la compilación:

Por su ejemplo:

.container {
    background:red;
    &.desc{
       background:blue;
    }
}

/* compiles to: */
.container {
    background: red;
}
.container.desc {
    background: blue;
}

Se &resolverá por completo, por lo que si su selector principal está anidado, la anidación se resolverá antes de reemplazar el &.

Esta notación se usa con mayor frecuencia para escribir pseudoelementos y clases :

.element{
    &:hover{ ... }
    &:nth-child(1){ ... }
}

Sin embargo, puede colocarlo &en prácticamente cualquier posición que desee * , por lo que también es posible lo siguiente:

.container {
    background:red;
    #id &{
       background:blue;
    }
}

/* compiles to: */
.container {
    background: red;
}
#id .container {
    background: blue;
}

Sin embargo, tenga en cuenta que esto de alguna manera rompe su estructura de anidación y, por lo tanto, puede aumentar el esfuerzo de encontrar una regla específica en su hoja de estilo.

*: No se permiten otros caracteres que los espacios en blanco delante del &. Por lo tanto, no puede hacer una concatenación directa de selector+ &- #id&arrojaría un error.

Christoph
fuente
12
Solo una nota al margen, un uso común de &es cuando se usan pseudo-elementos y pseudo-clases. Por ejemplo: &:hover.
aplastar
1
@crush Para completar, agregué esto a mi respuesta. Gracias por el comentario.
Christoph
1
Gracias. ¡Pensé que estaba siendo estúpido ya que no se menciona en la guía básica! Por cierto, la documentación ha movido la URL a: sass-lang.com/documentation/…
scipilot
1
Si &se usa al final de una línea, coloca esa línea al comienzo del resto de las clases en todos los demás niveles. Puede combinar elementos haciendo &.descbajo .container, lo que añadirá .desc a ella, lo que resulta en.container.desc
Kate Miller
scss-lint sugiere usar "& :: hover" (colones dobles)
Marcel Lange
18

Si ese es el caso, creo que necesita usar una mejor manera de crear un nombre de clase o una convención de nombre de clase. Por ejemplo, como dijiste, quieres que la .containerclase tenga un color diferente de acuerdo con un uso o apariencia específica. Puedes hacerlo:

SCSS

.container {
  background: red;

  &--desc {
    background: blue;
  }

  // or you can do a more specific name
  &--blue {
    background: blue;
  }

  &--red {
    background: red;
  }
}

CSS

.container {
  background: red;
}

.container--desc {
  background: blue;
}

.container--blue {
  background: blue;
}

.container--red {
  background: red;
}

El código anterior se basa en la metodología BEM en las convenciones de nomenclatura de clases. Puede consultar este enlace: BEM - Metodología de modificación de elementos de bloque

Murdock Helscream
fuente
Tenga en cuenta que esto suena bien, pero debe evitarse a toda costa. me agradecerá en el futuro cuando intente buscar su proyecto .container--descy termine sin resultados.
Stavm
2

La respuesta de Christoph es perfecta. A veces, sin embargo, es posible que desee ir a más clases de una. En este caso, podría probar las características @at-rooty #{}css que permitirían que dos clases raíz se sentaran una al lado de la otra usando &.

Esto no funcionaría (debido a la nothing before &regla):

container {
    background:red;
    color:white;
    
    .desc& {
      background: blue;
    }

    .hello {
        padding-left:50px;
    }
}

Pero esto (usando @at-root plus #{&}):

container {
    background:red;
    color:white;
    
    @at-root .desc#{&} {
      background: blue;
    }

    .hello {
        padding-left:50px;
    }
}

usuario2299879
fuente