Skip links

La sintaxis de alcance se ha aplicado a consultas de estilo contenedor y if()

La sintaxis del alcance no es nada nuevo. Hemos podido usarlo con consultas de medios. Consultar tamaño, resolución y contenedor de la ventana gráfica tamaño Consulta para consultar las dimensiones del contenedor. Se puede utilizar con contenedores. estilo Consultar (que podemos hacer a partir de Chrome 142) significa que podemos comparar valores literales, así como valores generados por propiedades personalizadas o attr() Función.

Además, esta característica incluye if() Lo mismo ocurre con la funcionalidad.

Aquí hay una demostración rápida que muestra la sintaxis de rango utilizada en dos contextos para comparar propiedades personalizadas (--lightness) se convierte a un valor literal (50%):

#container {
  /* Choose any value 0-100% */
  --lightness: 10%;

  /* Applies it to the background */
  background: hsl(270 100% var(--lightness));

  color: if(
    /* If --lightness is less than 50%, white text */
    style(--lightness < 50%): white;
    /* If --lightness is more than or equal to 50%, black text */
    style(--lightness >= 50%): black
  );

  /* Selects the children */
  * {
    /* Specifically queries parents */
    @container style(--lightness < 50%) {
      color: white;
    }

    @container style(--lightness >= 50%) {
      color: black;
    }
  }
}

Nuevamente, necesitas Chrome 142 o superior para ver esta función:

Ambos métodos hacen lo mismo, pero de formas ligeramente diferentes.

Echemos un vistazo más de cerca.

Sintaxis de alcance con propiedades personalizadas

En la siguiente demostración eliminé if() cosas, dejando solo consultas de estilo contenedor. Lo que sucede aquí es que creamos una propiedad personalizada llamada --lightness En #container. No es posible consultar el valor de una propiedad normal, por lo que la guardamos (o parte de ella) como una propiedad personalizada y luego la usamos para formar el valor en formato HSL. background.

#container {
  /* Choose any value 0-100% */
  --lightness: 10%;

  /* Applies it to the background */
  background: hsl(270 100% var(--lightness));
}

Después de eso seleccionamos los subcontenedores del contenedor y los declaramos condicionalmente. color Utilice consultas de estilo contenedor. Específicamente, si --lightness propiedad #container (Y, por extensión, background) es menor que 50%establecemos color llegar white. O si es mayor o igual a 50%establecemos color llegar black.

#container {
  /* etc. */

  /* Selects the children */
  * {
    /* Specifically queries parents */
    @container style(--lightness < 50%) {
      color: white;
    }

    @container style(--lightness >= 50%) {
      color: black;
    }
  }
}

/explicación Tenga en cuenta que no podemos movernos @container en las reglas #container Bloquear porque entonces consultaríamos --lightness en contenedor #container (donde no existe) y más allá (donde tampoco existe).

Antes de que las consultas de estilo de contenedor usaran sintaxis de rango, solo podíamos consultar valores específicos, por lo que la sintaxis de rango hacía que las consultas de estilo de contenedor fueran más útiles.

En contraste, if()Las declaraciones basadas en – pueden funcionar en cualquier bloque:

#container {
  --lightness: 10%;
  background: hsl(270 100% var(--lightness));

  /* --lightness works here */
  color: if(
    style(--lightness < 50%): white;
    style(--lightness >= 50%): black
  );

  * {
    /* And here! */
    color: if(
      style(--lightness < 50%): white;
      style(--lightness >= 50%): black
    );
  }
}

Dado que las consultas de estilo contenedor solo parecen arriba cascada (mientras if() También busca propiedades personalizadas declaradas en la misma regla CSS) ¿Por qué utilizar consultas de estilo de contenedor? Bueno, dejando de lado las preferencias personales, las consultas de contenedor nos permiten definir un contexto contenedor específico usando: container-name Propiedades CSS:

#container {
  --lightness: 10%;
  background: hsl(270 100% var(--lightness));

  /* Define a named containment context */
  container-name: myContainer;

  * {
    /* Specify the name here */
    @container myContainer style(--lightness < 50%) {
      color: white;
    }

    @container myContainer style(--lightness >= 50%) {
      color: black;
    }
  }
}

En esta versión, si @container en regla no encontrada --lightness existir myContainerel bloque no se ejecuta. si queremos @container Para profundizar en la cascada sólo necesitamos declarar container-name: myContainer Cascada más hacia arriba. este if() Las funciones no permiten esto, pero las consultas de contenedor nos permiten controlar el alcance.

sintaxis de alcance attr() Funciones CSS

También podemos extraer valores de atributos HTML usando attr() Funciones CSS.

En el siguiente HTML, he creado un elemento con un atributo de datos llamado data-notifs Su valor representa la cantidad de notificaciones no leídas para el usuario:

<div data-notifs="8"></div>

queremos elegir (data-notifs)::after Entonces podemos poner los números dentro. (data-notifs) usar content Propiedades CSS. A su vez, aquí es donde colocamos @container en regla, con (data-notifs) como contenedor. También incluí un height y combinar border-radius Para peinar:

(data-notifs)::after {
  height: 1.25rem;
  border-radius: 1.25rem;

  /* Container style queries here */
}

Ahora introduzca la lógica de consulta del estilo de contenedor. En el primero, está claro que si el recuento de notificaciones es de 1 a 2 dígitos (o, como se muestra en la consulta, menor o igual a 99), entonces content: attr(data-notifs) Insertar números data-notifs Atributos al mismo tiempo. aspect-ratio: 1 / 1 Asegúrese de que el ancho coincida con el alto para formar una insignia de notificación circular.

En la segunda consulta, haga coincidir si el número es mayor que 99cambiamos a content: "99+" Porque no creo que las insignias de notificación puedan contener cuatro dígitos. También incluimos algo de relleno en línea en lugar de widthporque en el círculo no caben ni tres personajes.

Para resumir, básicamente estamos usando esta lógica de consulta de estilo de contenedor para determinar el contenido y el estilo, lo cual es bastante bueno:

(data-notifs)::after {
  height: 1.25rem;
  border-radius: 1.25rem;

  /* If notification count is 1-2 digits */
  @container style(attr(data-notifs type(<number>)) <= 99) {

    /* Display count */
    content: attr(data-notifs);

    /* Make width equal the height */
    aspect-ratio: 1 / 1;
  }

  /* If notification count is 3 or more digits */
  @container style(attr(data-notifs type(<number>)) > 99) {
    /* After 99, simply say "99+" */
    content: "99+";

    /* Instead of width, a little padding */
    padding-inline: 0.1875rem;
  }
}

Pero quizás se pregunte por qué cuando leemos el valor en la consulta de estilo de contenedor, se escribe como attr(data-notifs type(<number>) en lugar de attr(data-notifs). Bueno, la razón es que cuando no especificamos el tipo de datos (o unidad), puedes leer sobre cambios recientes attr() aquí), el valor se analiza como una cadena. Esto está bien cuando generamos el valor. content: attr(data-notifs)pero cuando nosotros Comparar llega 99tenemos que analizarlo como un número (aunque type(<integer>) también funcionará).

De hecho, todas las comparaciones de sintaxis de rango deben ser del mismo tipo de datos (aunque no es necesario que utilicen las mismas unidades). Los tipos de datos admitidos incluyen <length>, <number>, <percentage>, <angle>, <time>, <frequency>y <resolution>. En el ejemplo anterior, en realidad podríamos expresar el brillo sin unidades porque las modernas hsl() La gramática admite esto, pero debemos ser coherentes con ella y asegurarnos de que todas las comparaciones también sean sin unidades:

#container {
  /* 10, not 10% */
  --lightness: 10;

  background: hsl(270 100 var(--lightness));

  color: if(
    /* 50, not 50% */
    style(--lightness < 50): white;
    style(--lightness >= 50): black
  );

  * {
    /* 50, not 50% */
    @container style(--lightness < 50) {
      color: white;
    }

    @container style(--lightness >= 50) {
      color: black;
    }
  }
}

notas: Este ejemplo de recuento de notificaciones no encaja del todo if()ya que necesita incluir lógica para cada propiedad CSS relevante, pero es posible y se usará la misma lógica.

Sintaxis de rango con valores literales

También podemos comparar valores literales, por ejemplo, 1em llegar 32px. Sí, son unidades diferentes, pero recuerda que solo deben ser del mismo tipo de datos y ambas son válidas. CSS <length>s.

En el siguiente ejemplo establecemos font-size de <h1> elemento a 31px. este <span> heredar esto font-sizey desde 1em igual font-size de los padres, 1em al alcance <span> También 31px. ¿Estás conmigo hasta ahora?

de acuerdo a if() lógico si 1em igual a menos que 32pxeste font-weight Más pequeño (una exageración, digamos 100), y si 1em igual o mayor que 32pxestablecemos font-weight a un fuerte 900. si eliminamos font-size declaración, entonces 1em Calcular el valor predeterminado del agente de usuario 32pxy Ni Las condiciones coinciden, quédate. font-weight También calcula el valor predeterminado del agente de usuario, que para todos los encabezados es 700.

Básicamente, la idea es que si nos metemos con el valor predeterminado font-size de <h1>entonces declaramos un optimizado font-weight Mantenga la legibilidad y evite textos gruesos y finos.

<h1>
  <span>Heading 1</span>
</h1>
h1 {
  /*
    The default value is 32px,
    but we overwrite it to 31px,
    causing the first if() condition to match
  */
  font-size: 31px;

  span {
    /* Here, 1em is equal to 31px */

    font-weight: if(
      style(1em < 32px): 100;
      style(1em > 32px): 900
    );
  }
}

Las consultas CSS han recorrido un largo camino, ¿no?

Me parece que la sintaxis de rango para consultas de estilo contenedor y if() La función representa el mayor avance de CSS en la lógica condicional, especialmente considerando que se puede combinar con consultas de medios, consultas de características y otros tipos de consultas de contenedor (recuerde declarar container-type Si se combina con la consulta del tamaño del contenedor). De hecho, ahora habrá una excelente Es hora de actualizar la consulta, así que, como regalo de despedida, aquí hay algunos enlaces para leer más:

Leave a comment

Home
Account
Cart
Search
¡Hola! ¡Pregúntame lo que quieras!
Explore
Drag