Estado del CSS 2022

Funciones de diseño web del presente y del futuro, como se vieron en Google I/O 2022, además de algunos extras.

El 2022 será uno de los mejores años de CSS, tanto en funciones como en lanzamientos de funciones cooperativas del navegador, con el objetivo colaborativo de implementar 14 funciones.

Descripción general

Esta publicación es la versión en formato de artículo de la charla que se brindó en Google I/O 2022. No pretende ser una guía detallada sobre cada función, sino una introducción y una breve descripción general para despertar tu interés, y proporcionar amplitud en lugar de profundidad. Si te interesa, consulta el final de una sección para ver vínculos a recursos con más información.

Índice

Usa la siguiente lista para ir a los temas que te interesen:

Compatibilidad del navegador

Una de las principales razones por las que se lanzan tantas funciones de CSS de forma cooperativa es gracias a los esfuerzos de Interop 2022. Antes de estudiar los esfuerzos de Interop, es importante analizar los esfuerzos de Compat 2021.

Compat 2021

Los objetivos para 2021, basados en los comentarios de los desarrolladores a través de encuestas, fueron estabilizar las funciones actuales, mejorar el conjunto de pruebas y aumentar las puntuaciones de aprobación de los navegadores para cinco funciones:

  1. Posicionamiento sticky
  2. Tamaño aspect-ratio
  3. Diseño flex
  4. Diseño grid
  5. Posicionamiento y animación de transform

Las puntuaciones de las pruebas aumentaron en todos los ámbitos, lo que demuestra una mayor estabilidad y confiabilidad. ¡Muchas felicidades a los equipos!

Interop 2022

Este año, los navegadores se reunieron para analizar las funciones y las prioridades en las que planeaban trabajar, y unieron sus esfuerzos. Planearon lanzar las siguientes funciones web para desarrolladores:

  1. @layer
  2. Espacios y funciones de color
  3. Contención
  4. <dialog>
  5. Compatibilidad con formularios
  6. Desplazamiento
  7. Subgrid
  8. Tipografía
  9. Unidades de viewport
  10. Compatibilidad web

Esta es una lista emocionante y ambiciosa que no puedo esperar a ver cómo se desarrolla.

Novedades de 2022

Como era de esperarse, el estado de CSS en 2022 se vio afectado de manera significativa por el trabajo de Interop 2022.

Capas en cascada

Browser Support

  • Chrome: 99.
  • Edge: 99.
  • Firefox: 97.
  • Safari: 15.4.

Source

Antes de @layer, el orden descubierto de las hojas de estilo cargadas era muy importante, ya que los estilos cargados en último lugar pueden anular los estilos cargados anteriormente. Esto llevó a hojas de estilo de entrada administradas meticulosamente, en las que los desarrolladores debían cargar primero los estilos menos importantes y, luego, los más importantes. Existen metodologías completas para ayudar a los desarrolladores a administrar esta importancia, como ITCSS.

Con @layer, el archivo de entrada puede definir previamente las capas y su orden. Luego, a medida que se cargan los estilos, se pueden colocar dentro de una capa, lo que permite conservar la importancia de la anulación de estilos, pero sin la orquestación de carga administrada meticulosamente.

En el video, se muestra cómo las capas en cascada definidas permiten un proceso de carga y creación más libre y de estilo libre, a la vez que se mantiene la cascada según sea necesario.

Las Herramientas para desarrolladores de Chrome son útiles para visualizar qué estilos provienen de qué capas:

Captura de pantalla de la barra lateral Styles de las Herramientas para desarrolladores de Chrome, en la que se destaca cómo aparecen los estilos dentro de los nuevos grupos de capas.

Recursos

Subgrid

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 71.
  • Safari: 16.

Source

Antes de subgrid, una cuadrícula dentro de otra no podía alinearse con las celdas o las líneas de la cuadrícula principal. Cada diseño de cuadrícula era único. Muchos diseñadores colocan una sola cuadrícula sobre todo su diseño y alinean constantemente los elementos dentro de ella, lo que no se podría hacer en CSS.

Después de subgrid, un elemento secundario de una cuadrícula puede adoptar las columnas o filas de sus elementos principales como propias y alinearse a sí mismo o a sus elementos secundarios con ellas.

En la siguiente demostración, el elemento body crea una cuadrícula clásica de tres columnas: la columna central se llama main, y las columnas izquierda y derecha nombran sus líneas fullbleed. Luego, cada elemento del cuerpo, <nav> y <main>, adopta las líneas con nombre del cuerpo estableciendo grid-template-columns: subgrid.

​​body {
  display: grid;
  grid-template-columns:
    [fullbleed-start]
    auto [main-start] min(90%, 60ch) [main-end] auto
    [fullbleed-end]
  ;
}

body > * {
  display: grid;
  grid-template-columns: subgrid;
}

Por último, los elementos secundarios de <nav> o <main> pueden alinearse o establecer su tamaño con las columnas y líneas fullbleed y main.

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}

Las Herramientas para desarrolladores pueden ayudarte a ver las líneas y las subcuadrículas (por el momento, solo en Firefox). En la siguiente imagen, se superpusieron la cuadrícula principal y las secundarias. Ahora se parece más a lo que los diseñadores tenían en mente para el diseño.

Captura de pantalla de una demostración de subcuadrícula, en la que se usan las herramientas de superposición de cuadrícula de las Herramientas para desarrolladores de Chrome para mostrar las líneas definidas por CSS.

En el panel de elementos de las Herramientas para desarrolladores, puedes ver qué elementos son cuadrículas y subcuadrículas, lo que resulta muy útil para depurar o validar el diseño.

Captura de pantalla del panel Elements de Chrome DevTools en la que se etiquetan los elementos que tienen diseños de cuadrícula o subcuadrícula.
Captura de pantalla de las Herramientas para desarrolladores de Firefox

Recursos

Consultas de contenedores

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Source

Antes de @container, los elementos de una página web solo podían responder al tamaño de todo el viewport. Esto es ideal para diseños macro, pero para diseños micro, en los que su contenedor externo no es toda la ventana gráfica, es imposible que el diseño se ajuste según corresponda.

Después de @container, los elementos pueden responder al tamaño o al estilo de un contenedor principal. La única advertencia es que los contenedores deben declararse como posibles objetivos de la búsqueda, lo que es un requisito pequeño para un gran beneficio.

/* establish a container */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}

Estos son los estilos que permiten que los elementos del evento consulten las columnas Lun., Mar., Mié., Jue. y Vie. en el siguiente video.

Demostración de Una Kravets

A continuación, se muestra el código CSS para consultar el tamaño del contenedor calendar-day y, luego, ajustar un diseño y los tamaños de fuente:

@container calendar-day (max-width: 200px) {
  .date {
    display: block;
  }

  .date-num {
    font-size: 2.5rem;
    display: block;
  }
}

Este es otro ejemplo: Un componente de libro se adapta al espacio disponible en la columna a la que se arrastra:

Demo de Max Böck

Una tiene razón al evaluar la situación como la nueva versión adaptable. Hay muchas decisiones de diseño interesantes y significativas que tomar cuando se usa @container.

Recursos

accent-color

Browser Support

  • Chrome: 93.
  • Edge: 93.
  • Firefox: 92.
  • Safari: 15.4.

Source

Antes de accent-color, cuando querías un formulario con colores que coincidieran con la marca, podías terminar con bibliotecas complejas o soluciones de CSS que se volvían difíciles de administrar con el tiempo. Si bien te brindaron todas las opciones y, con suerte, incluyeron la accesibilidad, la elección de usar los componentes integrados o adoptar los tuyos se vuelve tediosa.

Después de accent-color, una línea de CSS agrega un color de la marca a los componentes integrados. Además de un tinte, el navegador elige de forma inteligente colores de contraste adecuados para las partes auxiliares del componente y se adapta a los esquemas de color del sistema (claro u oscuro).

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

Elementos HTML acentuados en modo claro y oscuro uno al lado del otro para comparar.

Para obtener más información sobre accent-color, consulta mi entrada en web.dev, en la que exploro muchos más aspectos de esta útil propiedad de CSS.

Recursos

Nivel de color 4 y 5

En las últimas décadas, sRGB dominó la Web, pero en un mundo digital en expansión con pantallas de alta definición y dispositivos móviles equipados con pantallas OLED o QLED, sRGB no es suficiente. Además, se esperan páginas dinámicas que se adapten a las preferencias del usuario, y la administración del color ha sido una preocupación creciente para los diseñadores, los sistemas de diseño y los encargados del mantenimiento del código.

Sin embargo, no en 2022, ya que CSS tiene varias funciones y espacios de color nuevos: - Colores que alcanzan las capacidades de color HD de las pantallas - Espacios de color que coinciden con una intención, como la uniformidad perceptual. - Espacios de color para gradientes que cambian drásticamente los resultados de la interpolación - Funciones de color para ayudarte a mezclar y contrastar, y elegir en qué espacio trabajas

Antes de todas estas funciones de color, los sistemas de diseño debían precalcular los colores de contraste adecuados y garantizar paletas vibrantes apropiadas, todo mientras los preprocesadores o JavaScript hacían el trabajo pesado.

Después de todas estas funciones de color, el navegador y CSS pueden hacer todo el trabajo de forma dinámica y justo a tiempo. En lugar de enviar muchos KB de CSS y JavaScript a los usuarios para habilitar los colores de temas y visualización de datos, CSS puede encargarse de la organización y los cálculos. CSS también está mejor equipado para verificar la compatibilidad antes del uso o controlar los resguardos de forma correcta.

@media (dynamic-range: high) {
  .neon-pink {
    --neon-glow: color(display-p3 1 0 1);
  }
}

@supports (color: lab(0% 0 0)) {
  .neon-pink {
    --neon-glow: lab(150% 160 0);
  }
}

hwb()

Browser Support

  • Chrome: 101.
  • Edge: 101.
  • Firefox: 96.
  • Safari: 15.

Source

HWB significa tono, blancura y negrura. Se presenta como una forma fácil de articular el color, ya que solo se trata de un tono y una cantidad de blanco o negro para aclarar u oscurecer. Los artistas que mezclan colores con blanco o negro pueden apreciar esta incorporación de sintaxis de color.

El uso de esta función de color genera colores del espacio de color sRGB, igual que HSL y RGB. En cuanto a las novedades para 2022, esto no te brinda colores nuevos, pero puede facilitar algunas tareas para los fanáticos de la sintaxis y el modelo mental.

Recursos

Espacios de color

La forma en que se representan los colores se realiza con un espacio de color. Cada espacio de color ofrece diversas funciones y compensaciones para trabajar con el color. Algunos pueden juntar todos los colores brillantes, mientras que otros pueden alinearlos primero según su luminosidad.

Se espera que CSS del 2022 ofrezca 10 nuevos espacios de color, cada uno con características únicas para ayudar a los diseñadores y desarrolladores a mostrar, elegir y mezclar colores. Anteriormente, sRGB era la única opción para trabajar con el color, pero ahora CSS desbloquea un nuevo potencial y un nuevo espacio de color predeterminado, LCH.

color-mix()

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 16.2.

Source

Antes de color-mix(), los desarrolladores y diseñadores necesitaban preprocesadores como Sass para mezclar los colores antes de que el navegador los viera. La mayoría de las funciones de mezcla de colores tampoco proporcionaban la opción de especificar en qué espacio de color se debía realizar la mezcla, lo que a veces generaba resultados confusos.

Después de color-mix(), los desarrolladores y diseñadores pueden mezclar colores en el navegador, junto con todos sus otros estilos, sin ejecutar procesos de compilación ni incluir JavaScript. Además, pueden especificar en qué espacio de color se realizará la mezcla o usar el espacio de color de mezcla predeterminado de LCH.

A menudo, se usa un color de la marca como base y se crean variantes a partir de él, como colores más claros o más oscuros para los estilos de desplazamiento. Así se ve con color-mix():

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(var(--brand) 25%, black);
  --lighter: color-mix(var(--brand) 25%, white);
}

y, si quisieras mezclar esos colores en un espacio de color diferente, como sRGB, cámbialo:

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}

A continuación, se muestra una demostración de temas con color-mix(). Intenta cambiar el color de la marca y observa cómo se actualiza el tema:

¡Disfruta de la combinación de colores en varios espacios de color en tus hojas de estilo en 2022!

Recursos

color-contrast()

Antes de color-contrast(), los autores de hojas de estilo debían conocer los colores accesibles con anticipación. A menudo, una paleta mostraría texto en blanco o negro sobre una muestra de color para indicarle al usuario del sistema de color qué color de texto se necesitaría para contrastar correctamente con esa muestra.

Captura de pantalla de 3 paletas de Material, en la que se muestran 14 colores y sus colores de contraste en blanco o negro adecuados para el texto.
Ejemplo de las paletas de colores de Material Design de 2014

Después de color-contrast(), los autores de hojas de estilo pueden delegar la tarea por completo en el navegador. No solo puedes emplear el navegador para elegir automáticamente un color blanco o negro, sino que también puedes proporcionarle una lista de colores adecuados para el sistema de diseño y hacer que elija el primero que supere la proporción de contraste deseada.

A continuación, se muestra una captura de pantalla de una demostración de un conjunto de paletas de colores HWB en la que el navegador elige automáticamente los colores del texto según el color de la muestra:

Captura de pantalla de la demostración de HWB en la que cada paleta tiene un par diferente de texto claro u oscuro, según lo determina el navegador.
Probar la demostración

Los conceptos básicos de la sintaxis se ven de la siguiente manera, donde se pasa el color gris a la función y el navegador determina si el negro o el blanco tienen el mayor contraste:

color: color-contrast(gray);

La función también se puede personalizar con una lista de colores, de la que elegirá el color con mayor contraste de la selección:

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);

Por último, en caso de que sea preferible no elegir el color con el mayor contraste de la lista, se puede proporcionar una relación de contraste objetivo y se elegirá el primer color que la supere:

color: color-contrast(
  var(--bg-blue-1)
  vs
  var(--text-lightest), var(--text-light), var(--text-subdued)
  to AA /* 4.5 could also be passed */
);

Sin embargo, esta función se puede usar para más que solo el color del texto, aunque estimo que ese será su caso de uso principal. Piensa en lo mucho más fácil que será ofrecer interfaces accesibles y legibles una vez que la elección de colores contrastantes adecuados se incorpore al lenguaje CSS.

Recursos

Sintaxis de color relativa

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 15.

Source

Antes de la sintaxis de color relativa, para calcular el color y realizar ajustes, los canales de color debían colocarse individualmente en propiedades personalizadas. Esta limitación también convirtió a HSL en la función de color principal para manipular colores, ya que el tono, la saturación o la luminosidad se podían ajustar de forma sencilla con calc().

Después de la sintaxis de color relativa, cualquier color en cualquier espacio se puede deconstruir, modificar y devolver como un color, todo en una sola línea de CSS. Ya no hay limitaciones para HSL: las manipulaciones se pueden realizar en cualquier espacio de color deseado y se deben crear muchas menos propiedades personalizadas para facilitarlo.

En el siguiente ejemplo de sintaxis, se proporciona un valor hexadecimal base y se crean dos colores nuevos en relación con él. El primer color --absolute-change crea un color nuevo en LCH a partir del color base y, luego, reemplaza la luminosidad del color base por 75%, manteniendo la croma (c) y el tono (h). El segundo color --relative-change crea un color nuevo en LCH a partir del color base, pero esta vez reduce la croma (c) en un 20%.

.relative-color-syntax {
  --color: #0af;
  --absolute-change: lch(from var(--color) 75% c h);
  --relative-change: lch(from var(--color) l calc(c-20%) h);
}

Es similar a mezclar colores, pero se parece más a las alteraciones que a la mezcla. Puedes convertir un color a partir de otro, lo que te permite acceder a los tres valores de canal según el nombre de la función de color utilizada, con la oportunidad de ajustar esos canales. En general, esta es una sintaxis muy útil y potente para el color.

En la siguiente demostración, usé la sintaxis de color relativa para crear variantes más claras y oscuras de un color base, y usé color-contrast() para garantizar que las etiquetas tengan el contraste adecuado:

Captura de pantalla con 3 columnas, cada una más oscura o más clara que la columna central.
Probar la demostración

Esta función también se puede usar para generar paletas de colores. Aquí tienes una demostración en la que se generan paletas completas a partir de un color base proporcionado. Este conjunto de CSS alimenta todas las paletas, y cada una simplemente proporciona una base diferente. Como beneficio adicional, dado que usé LCH, observa qué tan uniformes son las paletas en términos de percepción: no se ven puntos calientes ni puntos muertos gracias a este espacio de color.

:root {
  --_color-base: #339af0;

  --color-0:  lch(from var(--_color-base) 98% 10 h);
  --color-1:  lch(from var(--_color-base) 93% 20 h);
  --color-2:  lch(from var(--_color-base) 85% 40 h);
  --color-3:  lch(from var(--_color-base) 75% 46 h);
  --color-4:  lch(from var(--_color-base) 66% 51 h);
  --color-5:  lch(from var(--_color-base) 61% 52 h);
  --color-6:  lch(from var(--_color-base) 55% 57 h);
  --color-7:  lch(from var(--_color-base) 49% 58 h);
  --color-8:  lch(from var(--_color-base) 43% 55 h);
  --color-9:  lch(from var(--_color-base) 39% 52 h);
  --color-10: lch(from var(--_color-base) 32% 48 h);
  --color-11: lch(from var(--_color-base) 25% 45 h);
  --color-12: lch(from var(--_color-base) 17% 40 h);
  --color-13: lch(from var(--_color-base) 10% 30 h);
  --color-14: lch(from var(--_color-base) 5% 20 h);
  --color-15: lch(from var(--_color-base) 1% 5 h);
}
Captura de pantalla de 15 paletas generadas de forma dinámica con CSS.
Probar la demostración

Esperamos que ahora puedas ver cómo los espacios de color y las diferentes funciones de color se pueden usar para diferentes propósitos, según sus fortalezas y debilidades.

Recursos

Espacios de color de gradiente

Antes de los espacios de color de gradiente, se usaba sRGB como espacio de color predeterminado. sRGB suele ser confiable, pero tiene algunas debilidades, como la zona gris muerta.

4 gradientes en una cuadrícula, todos de cian a rosa intenso. LCH y LAB tienen una intensidad más uniforme, mientras que sRGB se desatura un poco en el medio.

Después de los espacios de color del gradiente, indícale al navegador qué espacio de color debe usar para la interpolación de color. Esto les permite a los desarrolladores y diseñadores elegir el gradiente que prefieran. El espacio de color predeterminado también cambia a LCH en lugar de sRGB.

La adición de sintaxis va después de la dirección del gradiente, usa la nueva sintaxis in y es opcional:

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);

Aquí tienes un gradiente básico y esencial de negro a blanco. Observa el rango de resultados en cada espacio de color. Algunos alcanzan el negro oscuro antes que otros, y algunos se desvanecen a blanco demasiado tarde.

Se muestran 11 espacios de color en los que se compara el negro con el blanco.

En este siguiente ejemplo, el negro se transforma en azul porque es un espacio de problemas conocido para los gradientes. La mayoría de los espacios de color se acercan al púrpura durante la interpolación de color o, como me gusta pensar, a medida que los colores viajan dentro de su espacio de color desde el punto A al punto B. Dado que el gradiente tomará una línea recta desde el punto A hasta el punto B, la forma del espacio de color cambia drásticamente las paradas que toma la ruta en el camino.

Se muestran 11 espacios de color en los que se compara el azul con el negro.

Para obtener más información, ejemplos y comentarios, consulta este hilo de Twitter.

Recursos

inert

Browser Support

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 112.
  • Safari: 15.5.

Source

Antes de inert, era una práctica recomendada guiar el enfoque del usuario hacia las áreas de la página o la app que necesitaban atención inmediata. Esta estrategia de enfoque guiado se conoció como captura de enfoque porque los desarrolladores colocaban el enfoque en un espacio interactivo, detectaban los eventos de cambio de enfoque y, si el enfoque salía del espacio interactivo, se lo forzaba a volver. Los usuarios que usan teclados o lectores de pantalla vuelven al espacio interactivo para asegurarse de que la tarea se complete antes de continuar.

Después de inert, no se requiere ninguna trampa porque puedes congelar o proteger secciones completas de la página o la app. Los clics y los intentos de cambio de enfoque simplemente no están disponibles mientras esas partes de un documento son inertes. También se puede pensar en esto como guardias en lugar de una trampa, en la que a inert no le interesa que te quedes en un lugar, sino que otros lugares no estén disponibles.

Un buen ejemplo de esto es la función alert() de JavaScript:

El sitio web se muestra como interactivo, luego se llama a un alert() y la página deja de estar activa.

Observa en el video anterior cómo se podía acceder a la página con el mouse y el teclado hasta que se llamó a un alert(). Una vez que se mostró la ventana emergente del diálogo de alerta, el resto de la página quedó inmovilizado o inert. El enfoque del usuario se coloca dentro del diálogo de alerta y no tiene a dónde ir. Una vez que el usuario interactúa y completa la solicitud de la función de alerta, la página vuelve a ser interactiva. inert permite que los desarrolladores logren esta misma experiencia de enfoque guiado con facilidad.

A continuación, se incluye un pequeño ejemplo de código para mostrar cómo funciona:

<body>
  <div class="modal">
    <h2>Modal Title</h2>
    <p>...<p>
    <button>Save</button>
    <button>Discard</button>
  </div>
  <main inert>
    <!-- cannot be keyboard focused or clicked -->
  </main>
</body>

Un diálogo es un gran ejemplo, pero inert también es útil para elementos como la experiencia del usuario del menú lateral desplegable. Cuando un usuario desliza el menú lateral, no es correcto permitir que el mouse o el teclado interactúen con la página que se encuentra detrás, ya que esto puede ser un poco complicado para los usuarios. En cambio, cuando se muestra el menú lateral, la página se vuelve inerte, y los usuarios deben cerrar el menú lateral o navegar dentro de él, y nunca se perderán en otro lugar de la página con un menú abierto.

Recursos

Fuentes COLRv1

Antes de las fuentes COLRv1, la Web tenía fuentes OT-SVG, que también son un formato abierto para fuentes con degradados y colores y efectos integrados. Sin embargo, podían crecer mucho y, si bien permitían editar el texto, no había mucho margen para la personalización.

Después de las fuentes COLRv1, la Web tiene fuentes más pequeñas, escalables vectorialmente, reposicionables, con degradados y con modos de fusión que aceptan parámetros para personalizar la fuente según el caso de uso o para que coincida con una marca.

Visualización comparativa y gráfico de barras que muestran cómo las fuentes COLRv1 son más nítidas y pequeñas.
Imagen obtenida de https://developer.chrome.com/blog/colrv1-fonts/

Este es un ejemplo de la entrada de blog para desarrolladores de Chrome sobre emojis. Quizás notaste que, si aumentas el tamaño de la fuente de un emoji, no se mantiene nítido. Es una imagen, no arte vectorial. A menudo, en las aplicaciones, cuando se usa un emoji, se reemplaza por un recurso de mayor calidad. Con las fuentes COLRv1, los emojis son vectoriales y atractivos:

Las fuentes de íconos podrían hacer cosas increíbles con este formato, como ofrecer paletas de colores de dos tonos personalizadas y mucho más. Cargar una fuente COLRv1 es igual que cargar cualquier otro archivo de fuente:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

La personalización de la fuente COLRv1 se realiza con @font-palette-values, una regla @ especial de CSS para agrupar y nombrar un conjunto de opciones de personalización en un paquete para su referencia posterior. Observa cómo especificas un nombre personalizado de la misma manera que una propiedad personalizada, comenzando con --:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

Con --colorized como alias para las personalizaciones, el último paso es aplicar la paleta a un elemento que usa la familia de fuentes de color:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

.spicy {
  font-family: "Bungee Spice";
  font-palette: --colorized;
}
Captura de pantalla de la fuente Bungee Spice con la palabra DUNE.
La fuente Bungee Spice se muestra con colores personalizados. Fuente de https://developer.chrome.com/blog/colrv1-fonts/

Con la disponibilidad cada vez mayor de fuentes variables y fuentes de color, la tipografía web se encuentra en un camino muy magnífico hacia la personalización enriquecida y la expresión creativa.

Recursos

Unidades de viewport

Gráfico que muestra cómo la pantalla del dispositivo, la ventana del navegador y un iframe tienen diferentes ventanas gráficas.

Antes de las nuevas variantes del viewport, la Web ofrecía unidades físicas para ayudar a ajustar los viewports. Había uno para la altura, el ancho, el tamaño más pequeño (vmin) y el lado más grande (vmax). Funcionaron bien para muchas cosas, pero los navegadores para dispositivos móviles introdujeron una complejidad.

En dispositivos móviles, cuando se carga una página, se muestra la barra de estado con la URL, y esta barra consume parte del espacio de la ventana gráfica. Después de unos segundos y algo de interactividad, es posible que la barra de estado se deslice para permitir una experiencia de ventana gráfica más grande para el usuario. Sin embargo, cuando esa barra se desliza hacia afuera, la altura del viewport cambia, y cualquier unidad vh se desplazaría y cambiaría de tamaño a medida que cambiara su tamaño objetivo. En años posteriores, la unidad vh necesitaba decidir específicamente cuál de los dos tamaños de viewport iba a usar, ya que causaba problemas visuales de diseño en los dispositivos móviles. Se determinó que vh siempre representaría el viewport más grande.

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

Después de las nuevas variantes de viewport, se encuentran disponibles las unidades de viewport pequeñas, grandes y dinámicas, además de los equivalentes lógicos de los físicos. La idea es brindarles a los desarrolladores y diseñadores la capacidad de elegir qué unidad quieren usar para su situación específica. Quizás sea aceptable tener un pequeño cambio de diseño brusco cuando desaparece la barra de estado, por lo que dvh (altura dinámica del viewport) se podría usar sin problemas.

Un gráfico con tres teléfonos para ilustrar el DVH, el LVH y el SVH. El teléfono de ejemplo del DVH tiene dos líneas verticales, una entre la parte inferior de la barra de búsqueda y la parte inferior de la ventana gráfica, y otra entre la parte superior de la barra de búsqueda (debajo de la barra de estado del sistema) y la parte inferior de la ventana gráfica, lo que muestra cómo el DVH puede tener cualquiera de estas dos longitudes. El LVH se muestra en el medio con una línea entre la parte inferior de la barra de estado del dispositivo y el botón de la ventana gráfica del teléfono. El último es el ejemplo de la unidad de SVH, que muestra una línea desde la parte inferior de la barra de búsqueda del navegador hasta la parte inferior de la ventana gráfica.

A continuación, se incluye una lista completa de todas las opciones nuevas de unidades de viewport disponibles con las nuevas variantes de viewport:

Unidades de altura de la ventana gráfica
​​.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}
Unidades de ancho de la ventana gráfica
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}
Unidades laterales de viewport más pequeñas
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
Unidades laterales de la ventana gráfica más grande
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

Esperamos que esto les brinde a los desarrolladores y diseñadores la flexibilidad necesaria para lograr sus diseños adaptables a la ventana gráfica.

Recursos

:has()

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

Antes de :has(), el sujeto de un selector siempre estaba al final. Por ejemplo, el sujeto de este selector es un elemento de lista: ul > li. Los pseudoselectores pueden alterar el selector, pero no cambian el sujeto: ul > li:hover o ul > li:not(.selected).

Después de :has(), un sujeto más alto en el árbol de elementos puede seguir siendo el sujeto mientras proporciona una búsqueda sobre los hijos: ul:has(> li). Es fácil comprender por qué :has() recibió el nombre común de "selector principal", ya que el sujeto del selector ahora es el elemento principal en este caso.

Este es un ejemplo de sintaxis básica en el que la clase .parent sigue siendo el sujeto, pero solo se selecciona si un elemento secundario tiene la clase .child:

.parent:has(.child) {...}

Este es un ejemplo en el que un elemento <section> es el sujeto, pero el selector solo coincide si uno de los elementos secundarios tiene :focus-visible:

section:has(*:focus-visible) {...}

El selector :has() comienza a convertirse en una herramienta fantástica una vez que se hacen evidentes los casos de uso más prácticos. Por ejemplo, actualmente no es posible seleccionar etiquetas <a> cuando contienen imágenes, lo que dificulta enseñarle a la etiqueta de anclaje cómo cambiar sus estilos en ese caso de uso. Sin embargo, es posible con :has():

a:has(> img) {...}

Todos estos fueron ejemplos en los que :has() solo parece un selector principal. Considera el caso de uso de imágenes dentro de elementos <figure> y ajusta los estilos en las imágenes si la figura tiene un <figcaption>. En el siguiente ejemplo, se seleccionan figuras con leyendas y, luego, imágenes dentro de ese contexto. Se usa :has() y no se cambia el tema, ya que el tema al que nos dirigimos son imágenes, no figuras:

figure:has(figcaption) img {...}

Las combinaciones parecen infinitas. Combina :has() con consultas de cantidad y ajusta los diseños de cuadrícula CSS según la cantidad de elementos secundarios. Combina :has() con estados de seudoclase interactivos y crea aplicaciones que respondan de formas creativas nuevas.

Comprobar la compatibilidad es sencillo con @supports y su función selector(), que prueba si el navegador comprende la sintaxis antes de usarla:

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

Recursos

2022 y años posteriores

Aún hay varias cosas que serán difíciles de hacer después de que se lancen todas estas increíbles funciones en 2022. En la siguiente sección, se analizan algunos de los problemas restantes y las soluciones que se están desarrollando de forma activa para resolverlos. Estas soluciones son experimentales, aunque se puedan especificar o estar disponibles detrás de marcas en los navegadores.

En las siguientes secciones, se debe tener la certeza de que muchas personas de muchas empresas buscan resolver los problemas mencionados, no que estas soluciones se lanzarán en 2023.

Propiedades personalizadas con escritura flexible

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

Las propiedades personalizadas de CSS son increíbles. Permiten almacenar todo tipo de elementos dentro de una variable con nombre, que luego se puede extender, calcular, compartir y mucho más. De hecho, son tan flexibles que sería bueno tener algunas que no lo fueran tanto.

Considera una situación en la que un box-shadow usa propiedades personalizadas para sus valores:

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

Todo funciona bien hasta que una de las propiedades se cambia a un valor que CSS no acepta allí, como --x: red. Toda la sombra se rompe si falta alguna de las variables anidadas o si se establece en un tipo de valor no válido.

Aquí es donde entra en juego @property: --x puede convertirse en una propiedad personalizada con tipo, ya no flexible y suelta, sino segura con algunos límites definidos:

@property --x {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

Ahora, cuando box-shadow usa var(--x) y, más tarde, se intenta usar --x: red, se ignorará red, ya que no es un <length>. Esto significa que la sombra sigue funcionando, aunque se haya proporcionado un valor no válido para una de sus propiedades personalizadas. En lugar de fallar, vuelve a su initial-value de 0px.

Animación

Además de la seguridad de tipos, también abre muchas puertas para la animación. La flexibilidad de la sintaxis de CSS hace que sea imposible animar algunas cosas, como los gradientes. @property ayuda en este caso porque la propiedad CSS con tipo puede informar al navegador sobre la intención de un desarrollador dentro de una interpolación que, de otro modo, sería demasiado compleja. Básicamente, limita el alcance de las posibilidades de tal manera que un navegador puede animar aspectos de un diseño que antes no podía.

Considera este ejemplo de demostración, en el que se usa un gradiente radial para crear una parte de una capa superpuesta, lo que genera un efecto de foco de luz. JavaScript establece las coordenadas X e Y del mouse cuando se presiona la tecla Alt/Option y, luego, cambia el tamaño focal a un valor más pequeño, como el 25%, lo que crea el círculo de enfoque de luz en la posición del mouse:

Probar la demostración
.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );
}

Sin embargo, los gradientes no se pueden animar. Son demasiado flexibles y complejos para que el navegador "simplemente derive" cómo quieres que se animen. Sin embargo, con @property, una propiedad se puede escribir y animar de forma aislada, por lo que el navegador puede comprender fácilmente la intención.

Los videojuegos que usan este efecto de enfoque siempre animan el círculo, desde un círculo grande hasta un círculo pequeño. A continuación, te mostramos cómo usar @property con nuestra demostración para que el navegador anime la máscara de gradiente:

@property --focal-size {
  syntax: '<length-percentage>';
  initial-value: 100%;
  inherits: false;
}

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );

  transition: --focal-size .3s ease;
}
Probar la demostración

Ahora el navegador puede animar el tamaño del gradiente porque redujimos la superficie de la modificación a una sola propiedad y escribimos el valor para que el navegador pueda interpolar de forma inteligente las longitudes.

@property puede hacer mucho más, pero estas pequeñas habilitaciones pueden ser de gran utilidad.

Recursos

Estuvo en min-width o max-width

Antes de los rangos de consultas de medios, una consulta de medios de CSS usaba min-width y max-width para expresar condiciones superiores e inferiores. Es posible que se vea de este modo:

@media (min-width: 320px) {
  
}

Después de los rangos de consultas de medios, la misma consulta de medios podría verse así:

@media (width >= 320px) {
  
}

Una consulta de medios CSS que usa min-width y max-width podría verse así:

@media (min-width: 320px) and (max-width: 1280px) {
  
}

Después de los rangos de consultas de medios, la misma consulta de medios podría verse así:

@media (320px <= width <= 1280px) {
  
}

Según tus conocimientos de programación, uno de ellos se verá mucho más legible que el otro. Gracias a las incorporaciones de especificaciones, los desarrolladores podrán elegir la que prefieran o incluso usarlas de forma intercambiable.

Recursos

No hay variables de consultas de medios

Antes de @custom-media, las consultas de medios debían repetirse una y otra vez, o bien depender de preprocesadores para generar el resultado adecuado en función de variables estáticas durante el tiempo de compilación.

Después de @custom-media, CSS permite crear alias para las consultas de medios y hacer referencia a ellos, al igual que una propiedad personalizada.

Nombrar las cosas es muy importante: puede alinear el propósito con la sintaxis, lo que facilita compartir y usar las cosas en los equipos. Estas son algunas consultas de medios personalizadas que me acompañan entre proyectos:

@custom-media --OSdark  (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);

@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse   (hover) and (pointer: fine);

@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);

Ahora que están definidos, puedo usar uno de ellos de la siguiente manera:

@media (--OSdark) {
  :root {
    
  }
}

Encuentra una lista completa de las consultas de medios personalizadas que uso en mi biblioteca de propiedades personalizadas de CSS Open Props.

Recursos

Anidar selectores es muy útil

Antes de @nest, había mucha repetición en las hojas de estilo. Se volvió especialmente difícil de manejar cuando los selectores eran largos y cada uno apuntaba a pequeñas diferencias. La comodidad del anidamiento es uno de los motivos más comunes para adoptar un preprocesador.

Después de @nest, la repetición desaparece. Casi todas las funciones del anidamiento habilitado para el preprocesador estarán disponibles integradas en CSS.

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

Lo más importante de la anidación para mí, además de no repetir article en el selector anidado, es que el contexto de diseño permanece dentro de un bloque de diseño. En lugar de pasar de un selector y sus diseños a otro selector con diseños (ejemplo 1), el lector puede permanecer en el contexto de un artículo y ver los vínculos que contiene. La relación y la intención de estilo se agrupan, por lo que article puede parecer que posee sus propios estilos.

La propiedad también se puede considerar como centralización. En lugar de buscar en una hoja de estilo los estilos pertinentes, todos se pueden encontrar anidados en un contexto. Esto funciona con relaciones de elemento superior a secundario, pero también con relaciones de elemento secundario a superior.

Considera un componente secundario que se quiere ajustar cuando está en un contexto superior diferente, en lugar de que el componente superior sea propietario del diseño y cambie un componente secundario:

/* parent owns this, adjusting children */
section:focus-within > article {
  border: 1px solid hotpink;
}

/* with @nest becomes */

/* article owns this, adjusting itself when inside a section:focus-within */
article {
  @nest section:focus-within > & {
     border: 1px solid hotpink;
  }
}

@nest ayuda en general a organizar, centralizar y definir la propiedad de los estilos de forma más saludable. Los componentes pueden agrupar y poseer sus propios estilos, en lugar de tenerlos distribuidos entre otros bloques de estilos. Puede parecer pequeño en estos ejemplos, pero puede tener un gran impacto, tanto en la comodidad como en la legibilidad.

Recursos

Es muy difícil definir el alcance de los estilos

Browser Support

  • Chrome: 118.
  • Edge: 118.
  • Firefox: behind a flag.
  • Safari: 17.4.

Source

Antes de @scope, existían muchas estrategias porque los estilos en CSS se aplican en cascada, se heredan y tienen un alcance global de forma predeterminada. Estas características de CSS son muy convenientes para muchas cosas, pero para sitios y aplicaciones complejos, con potencialmente muchos estilos diferentes de componentes, el espacio global y la naturaleza de la cascada pueden hacer que los estilos parezcan filtrarse.

Después de @scope, los estilos no solo se pueden limitar a un contexto, como una clase, sino que también pueden indicar dónde terminan los estilos y no continúan en cascada ni se heredan.

En el siguiente ejemplo, el alcance de la convención de nomenclatura BEM se puede invertir en la intención real. El selector de BEM intenta definir el alcance del color de un elemento header en un contenedor .card con convenciones de nomenclatura. Esto requiere que el encabezado tenga este nombre de clase, lo que completa el objetivo. Con @scope, no se requieren convenciones de nomenclatura para completar el mismo objetivo sin marcar el elemento de encabezado:

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

Este es otro ejemplo, menos específico del componente y más sobre la naturaleza del alcance global de CSS. Los temas oscuro y claro deben coexistir dentro de una hoja de diseño, en la que el orden es importante para determinar un diseño ganador. Por lo general, esto significa que los estilos del tema oscuro se aplican después del tema claro, lo que establece el tema claro como el predeterminado y el oscuro como el estilo opcional. Evita la lucha por el orden y el alcance con @scope:

​​@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

Para completar la historia aquí, @scope también permite establecer dónde finaliza el alcance del diseño. Esto no se puede hacer con ninguna convención de nomenclatura ni con ningún preprocesador; es especial y solo lo puede hacer CSS integrado en el navegador. En el siguiente ejemplo, los estilos img y .content se aplican exclusivamente cuando un elemento secundario de un .media-block es hermano o superior de .content:

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

Recursos

No hay forma de usar CSS para un diseño de mampostería

Antes de la disposición en mampostería con CSS y cuadrícula, JavaScript era la mejor manera de lograr un diseño de mampostería, ya que cualquiera de los métodos de CSS con columnas o Flexbox representaría de forma imprecisa el orden del contenido.

Después de la mampostería de CSS con cuadrícula, no se requerirán bibliotecas de JavaScript y el orden del contenido será correcto.

Captura de pantalla del diseño de mampostería que muestra números que se desplazan por la parte superior y, luego, hacia abajo.
Imagen y demostración de Smashing Magazine
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

La demostración anterior se logró con el siguiente CSS:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

Es reconfortante saber que esta estrategia de diseño faltante está en la mira, además de que puedes probarla hoy mismo en Firefox.

Recursos

CSS no puede ayudar a los usuarios a reducir los datos

Browser Support

  • Chrome: behind a flag.
  • Edge: behind a flag.
  • Firefox: not supported.
  • Safari: not supported.

Source

Antes de la consulta de medios prefers-reduced-data, JavaScript y un servidor podían cambiar su comportamiento según el sistema operativo o la opción de "ahorro de datos" del navegador de un usuario, pero CSS no podía hacerlo.

Después de la consulta de medios prefers-reduced-data, CSS puede unirse a la mejora de la experiencia del usuario y desempeñar su papel en el ahorro de datos.

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

El CSS anterior se usa en este componente de desplazamiento de medios, y los ahorros pueden ser enormes. Cuanto más grande sea el viewport de visita, más ahorros se obtendrán en la carga de la página. El guardado continúa mientras los usuarios interactúan con los controles deslizantes de medios. Todas las imágenes tienen atributos loading="lazy" y, en combinación con el CSS que oculta el elemento por completo, esto significa que nunca se realiza una solicitud de red para la imagen.

Captura de pantalla de la interfaz de un carrusel de programas de TV con muchas miniaturas y títulos.

En mis pruebas, en un viewport de tamaño mediano, se cargaron inicialmente 40 solicitudes y 700 KB de recursos. A medida que el usuario se desplaza por la selección de medios, se cargan más solicitudes y recursos. Con CSS y la consulta de medios de datos reducidos, se cargan 10 solicitudes y 172 KB de recursos. Esto equivale a medio megabyte de ahorro, y el usuario ni siquiera se desplazó por el contenido multimedia, por lo que no se realizaron solicitudes adicionales.

Captura de pantalla de la interfaz de un carrusel de programas de TV sin miniaturas y con muchos títulos.

Esta experiencia de datos reducidos ofrece más ventajas que solo el ahorro de datos. Se pueden ver más títulos y no hay imágenes de portada que distraigan y roben la atención. Muchos usuarios navegan en un modo de ahorro de datos porque pagan por megabyte de datos, por lo que es muy bueno ver que CSS puede ayudar en este caso.

Recursos

Las funciones de ajuste de desplazamiento son demasiado limitadas

Antes de estas propuestas de ajuste de desplazamiento, escribir tu propio código JavaScript para administrar un carrusel, un control deslizante o una galería podía volverse rápidamente complejo, con todos los observadores y la administración de estados. Además, si no se tiene cuidado, las velocidades de desplazamiento naturales podrían normalizarse con la secuencia de comandos, lo que haría que la interacción del usuario se sintiera un poco artificial y, posiblemente, torpe.

API nuevas

snapChanging()

Este evento se activa en cuanto el navegador libera un elemento secundario de ajuste. Esto permite que la IU refleje la falta de un elemento secundario de ajuste y el estado de ajuste indeterminado del desplazador, ya que ahora se está usando y se detendrá en algún lugar nuevo.

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()

Este evento se activa en cuanto el navegador se ajusta a un nuevo elemento secundario y el desplazador se detiene. Esto permite que cualquier IU que dependa del elemento secundario ajustado se actualice y refleje la conexión.

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
scroll-start

El desplazamiento no siempre comienza al principio. Considera usar componentes deslizables en los que deslizar el dedo hacia la izquierda o la derecha active diferentes eventos, o una barra de búsqueda que, al cargar la página, esté oculta inicialmente hasta que te desplaces hacia la parte superior. Esta propiedad de CSS permite que los desarrolladores especifiquen que un elemento de desplazamiento debe comenzar en un punto específico.

:root { --nav-height: 100px }

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
:snap-target

Este selector CSS coincidirá con los elementos de un contenedor de ajuste de desplazamiento que el navegador haya ajustado actualmente.

.card {
  --shadow-distance: 5px;
  box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
  transition: box-shadow 350ms ease;
}

.card:snapped {
  --shadow-distance: 30px;
}

Después de estas propuestas de ajuste de desplazamiento, crear un control deslizante, un carrusel o una galería es mucho más fácil, ya que el navegador ahora ofrece comodidades para la tarea, lo que elimina los observadores y el código de orquestación de desplazamiento en favor del uso de APIs integradas.

Aún es muy pronto para estas funciones de CSS y JS, pero estate atento a los polyfills que pueden ayudar a adoptarlas y probarlas pronto.

Recursos

Ciclo entre estados conocidos

Antes de toggle(), solo se podían aprovechar los estados integrados en el navegador para el diseño y la interacción. Por ejemplo, la entrada de casilla de verificación tiene :checked, un estado del navegador administrado internamente para la entrada que CSS puede usar para cambiar el elemento visualmente.

Después de toggle(), se pueden crear estados personalizados en cualquier elemento para que CSS los cambie y los use para aplicar estilos. Permite agrupar, andar en bicicleta, activar o desactivar de forma dirigida y mucho más.

En el siguiente ejemplo, se logra el mismo efecto de tachado de un elemento de lista cuando se completa, pero sin ningún elemento de casilla de verificación:

<ul class='ingredients'>
   <li>1 banana
   <li>1 cup blueberries
  ...
</ul>

Y los estilos toggle() de CSS pertinentes:

li {
  toggle-root: check self;
}

li:toggle(check) {
  text-decoration: line-through;
}

Si conoces las máquinas de estados, es posible que notes la gran cantidad de coincidencias con toggle(). Esta función permitirá a los desarrolladores incorporar más estados en CSS, lo que, con suerte, generará formas más claras y semánticas de orquestar la interacción y el estado.

Recursos

Cómo personalizar elementos de selección

Antes de <selectmenu>, CSS no podía personalizar los elementos <option> con HTML enriquecido ni cambiar mucho la visualización de una lista de opciones. Esto llevó a los desarrolladores a cargar bibliotecas externas que recreaban gran parte de la funcionalidad de un <select>, lo que terminó siendo mucho trabajo.

Después de <selectmenu>, los desarrolladores pueden proporcionar HTML enriquecido para los elementos de opciones y darles el estilo que necesiten, sin dejar de cumplir con los requisitos de accesibilidad y proporcionar HTML semántico.

En el siguiente ejemplo, extraído de la página de explicación de <selectmenu>, se crea un nuevo menú de selección con algunas opciones básicas:

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

El CSS puede segmentar y diseñar las partes del elemento:

.my-select-menu::part(button) {
  color: white;
  background-color: red;
  padding: 5px;
  border-radius: 5px;
}

.my-select-menu::part(listbox) {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid red;
  border-radius: 5px;
}

Un menú de aspecto selecto con colores de acento rojos.

Puedes probar el elemento <selectmenu> en Chromium Canary con la marca de experimentos web habilitada. En 2023 y años posteriores, podrás personalizar los elementos del menú de selección.

Recursos

Cómo anclar un elemento a otro

Antes de anchor(), las posiciones absoluta y relativa eran estrategias de posición que se proporcionaban a los desarrolladores para que los elementos secundarios se movieran dentro de un elemento principal.

Después de anchor(), los desarrolladores pueden posicionar elementos en relación con otros, independientemente de si son secundarios o no. También permite que los desarrolladores especifiquen contra qué borde posicionar y otras opciones para crear relaciones de posición entre elementos.

En el explicador, se proporcionan algunos ejemplos y muestras de código excelentes si te interesa obtener más información.

Recursos