Período de prueba de CSS

Una de nuestras funciones favoritas del preprocesador de CSS ahora está integrada en el lenguaje: las reglas de estilo de anidamiento.

Adam Argyle
Adam Argyle

Antes de anidar, cada selector debía declararse explícitamente, independientemente del entre sí. Esto conduce a la repetición, la creación masiva de hojas de estilo y la creación dispersa. una experiencia fluida a los desarrolladores.

Antes
.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

.nesting > .is > .awesome {
  color: deeppink;
}

Después de anidar, los selectores se pueden y las reglas de estilo relacionadas con él pueden agruparse.

Después
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Pruébalo en el navegador.

El Nesting ayuda a los desarrolladores reduciendo la necesidad de repetir selectores y, al mismo tiempo, las reglas de estilo de ubicación conjunta para los elementos relacionados. También puede ayudar a que los estilos coincidan con HTML al que se orientan. Si el componente .nesting del ejemplo anterior se del proyecto, puedes borrar todo el grupo en lugar de buscar archivos para instancias de selector relacionadas.

El Nesting puede ayudar con lo siguiente: - Organización - Reducir el tamaño de los archivos - Refactorización

El Nesting está disponible a partir de Chrome 112 y también para probarlo en la Versión preliminar técnica de Safari 162.

Comienza a usar el período de Nesting de CSS

En el resto de esta publicación,se usa la siguiente zona de pruebas de demostración para ayudarte visualizarás las selecciones. En este estado predeterminado, no se selecciona nada todo sea visible. Al seleccionar las diversas formas y tamaños, puedes practicar la sintaxis y verla en acción.

Una cuadrícula colorida de círculos pequeños y grandes, triángulos y cuadrados.

Dentro de la zona de pruebas hay círculos, triángulos y cuadrados. Algunos son pequeños, medianos o grandes. Otros son azules, rosados o púrpuras. Todos están dentro del .demo elemento contenedor. La siguiente es una vista previa de los elementos HTML con los que la segmentación de clientes.

<div class="demo">
  <div class="sm triangle pink"></div>
  <div class="sm triangle blue"></div>
  <div class="square blue"></div>
  <div class="sm square pink"></div>
  <div class="sm square blue"></div>
  <div class="circle pink"></div>
  …
</div>

Ejemplos de anidación

El anidamiento de CSS te permite definir estilos para un elemento dentro del contexto de otro selector.

.parent {
  color: blue;

  .child {
    color: red;
  }
}

En este ejemplo, el selector de clases .child se anida en el selector de clase .parent. Esto significa que el selector .child anidado Solo se aplica a elementos que son secundarios de elementos con una clase .parent.

De manera alternativa, este ejemplo se puede escribir con el símbolo & para explícitamente indican dónde se debe colocar la clase principal.

.parent {
  color: blue;

  & .child {
    color: red;
  }
}

Estos dos ejemplos son funcionalmente equivalentes y la razón por la que tienes opciones se aclararán a medida que se exploren ejemplos más avanzados en este artículo.

Selección de los círculos

En este primer ejemplo, la tarea es agregar estilos para atenuar y desenfocar solo dentro de la demostración.

Sin anidar, CSS en la actualidad:

.demo .circle {
  opacity: .25;
  filter: blur(25px);
}

Con el anidamiento, existen dos maneras válidas:

/* & is explicitly placed in front of .circle */
.demo {
  & .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

o

/* & + " " space is added for you */
.demo {
  .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

Resultado, todos los elementos dentro de .demo con una clase .circle se desenfocado y casi invisible:

La colorida cuadrícula de formas ya no tiene círculos,
    son muy débiles en el fondo.
Probar demostración
.

Seleccionar cualquier triángulo y cuadrado

Esta tarea requiere seleccionar varios elementos anidados, también llamados selectores de grupos.

Sin anidar, actualmente el CSS tiene dos maneras:

.demo .triangle,
.demo .square {
  opacity: .25;
  filter: blur(25px);
}

o con :is()

/* grouped with :is() */
.demo :is(.triangle, .square) {
  opacity: .25;
  filter: blur(25px);
}

Con anidación, estas son dos maneras válidas:

.demo {
  & .triangle,
  & .square {
    opacity: .25;
    filter: blur(25px);
  }
}

o

.demo {
  .triangle, .square {
    opacity: .25;
    filter: blur(25px);
  }
}

Resultado, solo los elementos .circle permanecen dentro de .demo:

La colorida cuadrícula de formas solo queda con círculos,
    todas las demás formas son casi invisibles.
Probar demostración
.

Selección de triángulos y círculos grandes

Esta tarea requiere un selector compuesto, en el que los elementos deben tener ambas clases presentes para que se los seleccione.

Sin anidar, CSS en la actualidad:

.demo .lg.triangle,
.demo .lg.square {
  opacity: .25;
  filter: blur(25px);
}

o

.demo .lg:is(.triangle, .circle) {
  opacity: .25;
  filter: blur(25px);
}

Con anidación, estas son dos maneras válidas:

.demo {
  .lg.triangle,
  .lg.circle {
    opacity: .25;
    filter: blur(25px);
  }
}

o

.demo {
  .lg {
    &.triangle,
    &.circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

El resultado, todos los triángulos y círculos grandes están ocultos dentro de .demo:

La cuadrícula colorida solo tiene formas pequeñas y medianas visibles.
Probar demostración
.
Sugerencia profesional con anidación y selectores compuestos

El símbolo & es tu amigo, ya que muestra explícitamente cómo adjuntar anidados selectores. Consulta el siguiente ejemplo:

.demo {
  .lg {
    .triangle,
    .circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

Si bien es una forma válida de anidar, los resultados no coincidirán con los elementos que podrías esperar. Esto se debe a que, sin & para especificar el resultado deseado de .lg.triangle, .lg.circle combinado, el resultado real sería .lg .triangle, .lg .circle. selectores descendientes.

Seleccionar todas las formas, excepto las rosas

Esta tarea requiere una seudoclase funcional de negación, en la que los elementos no deben tener el selector especificado.

Sin anidar, CSS en la actualidad:

.demo :not(.pink) {
  opacity: .25;
  filter: blur(25px);
}

Con anidación, estas son dos maneras válidas:

.demo {
  :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

o

.demo {
  & :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

El resultado, todas las formas que no son rosas están ocultas dentro de .demo:

La cuadrícula colorida ahora es monocromática y solo muestra formas rosas.
Probar demostración
.
Precisión y flexibilidad con &

Supongamos que quieres orientar .demo con el selector :not(). & se requiere para que:

.demo {
  &:not() {
    ...
  }
}

Esto suma .demo y :not() a .demo:not(), a diferencia del anterior ejemplo que necesitaba .demo :not(). Este recordatorio es muy importante cuando en el que se desea anidar una interacción :hover.

.demo {
  &:hover {
    /* .demo:hover */
  }

  :hover {
    /* .demo :hover */
  }
}

Más ejemplos de anidamiento

La especificación de CSS para la anidación es con más ejemplos. Si quieres obtener más información sobre la sintaxis mediante ejemplos, abarca una amplia gama de ejemplos válidos y no válidos.

En los siguientes ejemplos, presentaremos brevemente una función de anidamiento de CSS para ayudarte a comprender la variedad de capacidades que ofrece.

Período de prueba de @media

Puede ser muy molesto desplazarse a un área diferente de la hoja de estilo para encontrar condiciones de consultas de medios que modifican un selector y sus estilos. Esa distracción desaparece con la capacidad de anidar las condiciones dentro del contexto.

Por conveniencia de la sintaxis, si la consulta de medios anidada solo modifica los estilos. para el contexto del selector actual, se puede usar una sintaxis mínima.

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    font-size: 1.25rem;
  }
}

También se puede usar & explícitamente:

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    &.large {
      font-size: 1.25rem;
    }
  }
}

En este ejemplo, se muestra la sintaxis expandida con & y, al mismo tiempo, se orienta a .large. para demostrar que las funciones de anidamiento adicionales continúan funcionando.

Obtén más información sobre cómo anidar @rules.

Anidar en cualquier lugar

Todos los ejemplos hasta este punto continuaron o se adjuntaron a un contexto anterior. Puedes cambiar o reorganizar completamente el contexto si es necesario.

.card {
  .featured & {
    /* .featured .card */
  }
}

El símbolo & representa una referencia a un objeto selector (no una cadena). se pueden colocar en cualquier lugar de un selector anidado. Incluso se pueden colocar varias veces:

.card {
  .featured & & & {
    /* .featured .card .card .card */
  }
}

Aunque este ejemplo parece un poco inútil, hay situaciones en las que poder repetir un contexto selector es útil.

Ejemplos de anidamiento no válidos

Hay algunas situaciones de sintaxis anidada que no son válidas y pueden sorprenderte. si has estado anidando en preprocesadores.

Anidación y concatenación

Muchas convenciones de nomenclatura de clases CSS cuentan con que el anidamiento puede concatenar o adjuntar selectores como si fueran cadenas. Esto no funciona en el anidamiento de CSS, como los selectores no son cadenas, son referencias a objetos.

.card {
  &--header {
    /* is not equal to ".card--header" */
  }
}

Puede encontrar una explicación más detallada en las especificaciones.

Ejemplo de anidamiento complejo

Anidación en listas de selectores y :is()

Considera el siguiente bloque CSS anidado:

.one, #two {
  .three {
    /* some styles */
  }
}

Este es el primer ejemplo que comienza con una lista de selección y luego continúa anidándose. Los ejemplos anteriores solo habían terminado con una lista de selector. No hay nada válido en este ejemplo de anidación, pero hay un detalle de implementación potencialmente complicado sobre cómo anidar dentro de listas de selectores, especialmente aquellas que incluyen un selector de ID.

Para que la intent de anidación funcione, el navegador unirá cualquier lista de selección que no sea la más anidada con :is(). Esta unión mantiene la agrupación de la lista del selector dentro de cualquier contexto creado. El efecto secundario de esta agrupación, :is(.one, #two), es que adopta la especificidad de la puntuación más alta dentro de los selectores dentro del paréntesis. Así es como :is() siempre funciona, pero puede sorprenderte cuando se usa la sintaxis de anidamiento, ya que no es exactamente lo que se creó. El truco que se resume: la anidación con IDs y listas de selectores puede generar selectores de especificidad muy alta.

Para recapitular claramente el ejemplo complicado, el bloque de anidamiento anterior se aplicará al documento de la siguiente manera:

:is(.one, #two) .three {
  /* some styles */
}

Presta atención o enseña a tus linters a que adviertan que cuando anidan dentro de una lista de selector que usa un selector de ID, la especificidad de todos los elementos anidados dentro de esa lista de selectores será alta.

Cómo mezclar anidamiento y declaraciones

Considera el siguiente bloque CSS anidado:

.card {
  color: green;
  & { color: blue; }
  color: red;
}

El color de los elementos .card será blue.

Cualquier declaración de estilo entremezclado se eleva a la parte superior, como si estuviera que se crearon antes de la anidación. Puedes encontrar más detalles en las especificaciones.

Hay formas de evitarlo. Lo siguiente une los tres estilos de color en &, que mantiene el orden de la cascada como lo pretendía el autor. El color de Los elementos .card serán de color rojo.

.card {
  color: green;
  & { color: blue; }
  & { color: red; }
}

De hecho, se recomienda unir cualquier estilo que siga a la anidación con un &.

.card {
  color: green;

  @media (prefers-color-scheme: dark) {
    color: lightgreen;
  }

  & {
    aspect-ratio: 4/3;
  }
}

Detección de funciones

Existen dos formas excelentes de detectar el anidamiento de CSS: usar la anidación o usar @supports para verificar la capacidad de análisis del selector de anidación.

Una captura de pantalla de la demostración de CodePen de Bramus, en la que se pregunta si tu navegador es compatible
  Anidación de CSS Debajo de esa pregunta, hay un cuadro verde que indica apoyo.

Uso de la anidación:

html {
  .has-nesting {
    display: block;
  }

  .no-nesting {
    display: none;
  }
}

Usa @supports de la siguiente manera:

@supports (selector(&)) {
  /* nesting parsing available */
}

Mi colega Bramus tiene un excelente CodePen en el que muestra esta estrategia.

Depuración con Herramientas para desarrolladores de Chrome

La compatibilidad actual con la anidación en Herramientas para desarrolladores es mínima. Actualmente encontrarás los estilos se representan en el panel Estilos como se espera, pero se seguirá el proceso de anidación y su contexto de selector completo aún no es compatible. Tenemos un diseño y planes para haz que esto sea transparente y claro.

Captura de pantalla de la sintaxis de anidamiento de las Herramientas para desarrolladores de Chrome.

Chrome 113 planea tener compatibilidad adicional con la anidación de CSS. ¡No te pierdas las novedades!

El futuro

El Nesting de CSS solo está disponible en la versión 1. La versión 2 incorporará más azúcar sintáctica y posiblemente menos reglas memorizar. Hay mucha demanda para que el análisis de la anidación no sea limitado. o tienen momentos complicados.

El anidamiento es una gran mejora del lenguaje CSS. Tiene implicaciones para la creación para casi todos los aspectos arquitectónicos de CSS. Este gran impacto necesita ser profundamente explorar y comprender antes de que se pueda especificar la versión 2 de manera eficaz.

Para terminar, aquí hay una demostración que usa @scope, anidación y @layer todos juntos. ¡Es muy emocionante!

Una tarjeta clara sobre un fondo gris. La tarjeta tiene título y texto,
  algunos botones de acción
y una imagen de estilo cyberpunk.