Ayuda a elegir una sintaxis para anidar CSS

Dos sintaxis en competencia necesitan tu ayuda para determinar cuál se debe dirigir a un candidato de especificación.

Adam Argyle
Adam Argyle
Miriam Suzanne
Miriam Suzanne

El anidamiento de CSS es una adición conveniente de sintaxis que permite agregar CSS de un conjunto de reglas. Si ya usaste SCSS, Menos o Stylus y, luego, habrás visto algunos sabores de esto:

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Después de que el preprocesador lo compiló en CSS normal, se convierte en CSS normal, como este:

.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

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

Se está considerando seriamente una versión oficial de CSS de esta sintaxis y una división de preferencia, y nos gustaría emplear la ayuda de la comunidad para romper el empate. El resto de esta publicación presentará las opciones de sintaxis, por lo que puedes sentirte informado para completar una encuesta al final.

¿Por qué el ejemplo exacto de anidación que se muestra arriba no puede ser la sintaxis para la anidación de CSS?

Existen algunos motivos por los que la sintaxis de anidación más popular no se puede usar, tal como se muestra a continuación:

  1. Análisis ambiguo
    Algunos selectores anidados pueden lucir exactamente como las propiedades y los preprocesadores son capaces de resolverlos y administrarlos en el momento de la compilación. Los motores de navegador no tendrán con las mismas posibilidades, los selectores nunca deben interpretarse de manera vaga.

  2. Conflictos de análisis del preprocesador
    La anidación de CSS no debería dañar los preprocesadores ni el desarrollador existente. flujos de trabajo de anidación. Esto sería disruptivo y sería desconsiderado para quienes los ecosistemas y las comunidades.

  3. Esperando a :is()
    El anidamiento básico no necesita :is(), pero el más complejo sí. Consulta el ejemplo n.o 3 para obtener una introducción ligera al selector y el anidamiento. Imagina que la lista del selector estaba en medio de un selector en lugar de al principio, en esos casos, se requiere :is() para agrupar los selectores en el medio de otro selector

Descripción general de lo que comparamos

Queremos que la anidación de CSS sea correcta y, en ese sentido, incluiremos comunidad. Las siguientes secciones ayudarán a describir las tres versiones posibles que estamos evaluando. Luego repasaremos algunos ejemplos de uso para compararlos y al final habrá una encuesta ligera en la que se te preguntará cuál prefieres en general.

Opción 1: @nest

Esta es la sintaxis especificada actualmente en Nesting 1 de CSS. Ofrece una forma conveniente de anidar Anexa estilos iniciando nuevos selectores anidados con &. También ofrece @nest como una forma de colocar el contexto & en cualquier lugar dentro de un selector nuevo, como cuando no solo agregas sujetos. Es flexible y mínima, pero a un de tener que recordar @nest o &, según el caso de uso.

Opción 2: @nest restringido

Esta es una alternativa más estricta, en un intento de reducir los gastos mencionados recordar dos métodos de anidación. Esta sintaxis restringida solo permite anidar en se produce después de @nest, por lo que no existe un patrón de conveniencia solo para agregar. Quitando la ambigüedad de la elección, lo que crea una forma fácil de recordar de anidar, pero sacrifica la versatilidad en favor de lo convencional.

Opción 3: Corchetes

Para evitar la doble sintaxis o el desorden adicional que implica el @nest Miriam Suzanne y Elika Etemad propusieron una sintaxis alternativa que, en su lugar, se basa en llaves adicionales. Esto proporciona claridad a la sintaxis, con solo dos caracteres extra y sin nuevas reglas "at". También permite reglas anidadas según el tipo de anidamiento requerido, como una forma de simplificar varios selectores anidados de forma similar.

Ejemplo 1: Anidación directa

@nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

@nest siempre

.foo {
  color: #111;

  @nest & .bar {
    color: #eee;
  }
}

corchetes

.foo {
  color: #111;

  {
    & .bar {
      color: #eee;
    }
  }
}

CSS equivalente

.foo {
  color: #111;
}

.foo .bar {
  color: #eee;
}

Ejemplo 2: Anidamiento compuesto

@nest

.foo {
  color: blue;

  &.bar {
    color: red;
  }
}

@nest siempre

.foo {
  color: blue;

  @nest &.bar {
    color: red;
  }
}

corchetes

.foo {
  color: blue;

  {
    &.bar {
      color: red;
    }
  }
}

CSS equivalente

.foo {
  color: blue;
}

.foo.bar {
  color: red;
}

Ejemplo 3: Listas de selectores y anidación

@nest

.foo, .bar {
  color: blue;

  & + .baz,
  &.qux {
    color: red;
  }
}

@nest siempre

.foo, .bar {
  color: blue;

  @nest & + .baz,
  &.qux {
    color: red;
  }
}

corchetes

.foo, .bar {
  color: blue;

  {
    & + .baz,
    &.qux {
      color: red;
    }
  }
}

CSS equivalente

.foo, .bar {
  color: blue;
}

:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux {
  color: red;
}

Ejemplo 4: varios niveles

@nest

figure {
  margin: 0;

  & > figcaption {
    background: lightgray;

    & > p {
      font-size: .9rem;
    }
  }
}

@nest siempre

figure {
  margin: 0;

  @nest & > figcaption {
    background: lightgray;

    @nest & > p {
      font-size: .9rem;
    }
  }
}

corchetes

figure {
  margin: 0;

  {
    & > figcaption {
      background: lightgray;

      {
        & > p {
          font-size: .9rem;
        }
      }
    }
  }
}

CSS equivalente

figure {
  margin: 0;
}

figure > figcaption {
  background: hsl(0 0% 0% / 50%);
}

figure > figcaption > p {
  font-size: .9rem;
}

Ejemplo 5: Anidamiento principal o cambio de sujeto

@nest

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

@nest siempre

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

corchetes

.foo {
  color: red;

  {
    .parent & {
      color: blue;
    }
  }
}

CSS equivalente

.foo {
  color: red;
}

.parent .foo {
  color: blue;
}

Ejemplo 6: Combinación de anidamiento directo y superior

@nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    &.baz {
      color: green;
    }
  }
}

@nest siempre

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    @nest &.baz {
      color: green;
    }
  }
}

corchetes

.foo {
  color: blue;

  {
    .bar & {
      color: red;

      {
        &.baz {
          color: green;
        }
      }
    }
  }
}

CSS equivalente

.foo {
  color: blue;
}

.bar .foo {
  color: red;
}

.bar .foo.baz {
  color: green;
}

Ejemplo 7: Anidación de consultas de medios

@nest

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

o explícitamente / ampliadas

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

@nest siempre (siempre es explícito)

.foo {
  display: grid;

  @media (width => 30em) {
    @nest & {
      grid-auto-flow: column;
    }
  }
}

corchetes

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

o explícitamente / ampliadas

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

CSS equivalente

.foo {
  display: grid;
}

@media (width => 30em) {
  .foo {
    grid-auto-flow: column;
  }
}

Ejemplo 8: Grupos de anidación

@nest

fieldset {
  border-radius: 10px;

  &:focus-within {
    border-color: hotpink;
  }

  & > legend {
    font-size: .9em;
  }

  & > div {
    & + div {
      margin-block-start: 2ch;
    }

    & > label {
      line-height: 1.5;
    }
  }
}

@nest siempre

fieldset {
  border-radius: 10px;

  @nest &:focus-within {
    border-color: hotpink;
  }

  @nest & > legend {
    font-size: .9em;
  }

  @nest & > div {
    @nest & + div {
      margin-block-start: 2ch;
    }

    @nest & > label {
      line-height: 1.5;
    }
  }
}

corchetes

fieldset {
  border-radius: 10px;

  {
    &:focus-within {
      border-color: hotpink;
    }
  }

  > {
    legend {
      font-size: .9em;
    }

    div {
      + div {
        margin-block-start: 2ch;
      }

      > label {
        line-height: 1.5;
      }
    }}
  }
}

CSS equivalente

fieldset {
  border-radius: 10px;
}

fieldset:focus-within {
  border-color: hotpink;
}

fieldset > legend {
  font-size: .9em;
}

fieldset > div + div {
  margin-block-start: 2ch;
}

fieldset > div > label {
  line-height: 1.5;
}

Ejemplo 9: Grupo de anidación complejo "Fregadero de la cocina"

@nest

dialog {
  border: none;

  &::backdrop {
    backdrop-filter: blur(25px);
  }

  & > form {
    display: grid;

    & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

@nest siempre

dialog {
  border: none;

  @nest &::backdrop {
    backdrop-filter: blur(25px);
  }

  @nest & > form {
    display: grid;

    @nest & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

corchetes

dialog {
  border: none;

  {
    &::backdrop {
      backdrop-filter: blur(25px);
    }

    & > form {
      display: grid;

      {
        & > :is(header, footer) {
          align-items: flex-start;
        }
      }
    }
  }

  {
    html:has(&[open]) {
      overflow: hidden;
    }
  }
}

CSS equivalente

dialog {
  border: none;
}

dialog::backdrop {
  backdrop-filter: blur(25px);
}

dialog > form {
  display: grid;
}

dialog > form > :is(header, footer) {
  align-items: flex-start;
}

html:has(dialog[open]) {
  overflow: hidden;
}

Hora de votar

Espero que sientas que fue una comparación justa y un ejemplo de la sintaxis. las opciones que estamos evaluando. Revísalos detenidamente y cuéntanos cuáles son a continuación. Gracias por ayudarnos a avanzar la anidación de CSS a una sintaxis ¡todos llegarán a conocerse y amar!

Responder la encuesta