Estado del CSS 2022

Funciones de diseño web actuales y futuras, como se ve en Google IO 2022, además de algunos servicios adicionales.

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

Descripción general

Esta publicación es la versión en artículo de la charla que se dio en Google IO 2022. No se trata de una guía detallada sobre cada función, sino de una introducción y una breve descripción general para despertar tu interés y brindarte amplitud en lugar de profundidad. Si te llama la atención, consulta al final de una sección los vínculos a los recursos para obtener más información.

Índice

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

Compatibilidad del navegador

Uno de los principales motivos por los que tantas funciones de CSS se lanzarán de forma cooperativa se debe a los esfuerzos de Interop 2022. Antes de estudiar los esfuerzos de interoperabilidad, es importante observar los esfuerzos de Compat 2021.

Compatibilidad 2021

Los objetivos para 2021, impulsados por los comentarios de los desarrolladores a través de encuestas, eran estabilizar las funciones actuales, mejorar el paquete de pruebas y aumentar las puntuaciones de aprobación de los navegadores para cinco funciones:

  1. Posicionamiento de sticky
  2. Tamaño de 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. ¡Felicitaciones a los equipos!

Interop 2022

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

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

Esta es una lista emocionante y ambiciosa que no puedo esperar a ver desarrollarse.

Novedades de 2022

No es de extrañar que el estado del CSS 2022 se vea afectado de forma significativa por el trabajo de Interop 2022.

Capas en cascada

Navegadores compatibles

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

Origen

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

Con @layer, el archivo de entrada puede definir previamente las capas y su orden con anticipación. Luego, a medida que se cargan, se cargan o definen los diseños, se pueden colocar dentro de una capa, lo que permite preservar la importancia de la anulación del diseño, pero sin una organización de carga administrada meticulosamente.

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

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

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

Recursos

Subred

Navegadores compatibles

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

Origen

Antes del subgrid, una cuadrícula dentro de otra cuadrícula no se podía alinear con sus celdas superiores o líneas de cuadrícula. 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 puede hacer en CSS.

Después de subgrid, un elemento secundario de una cuadrícula puede adoptar las columnas o filas de sus elementos superiores 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 del medio se llama main, y las columnas izquierda y derecha nombren sus líneas fullbleed. Luego, cada elemento del cuerpo, <nav> y <main>, adopta las líneas nombradas del cuerpo configurando 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> se pueden alinear o definir 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 subcuadrículas (solo Firefox, por el momento). En la siguiente imagen, se superponen la cuadrícula principal y las subcuadrículas. Ahora resembla cómo los diseñadores pensaban en 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ículas de Chrome DevTools 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 es muy útil para depurar o validar el diseño.

Captura de pantalla del panel Elementos de herramientas para desarrolladores de Chrome que etiqueta qué elementos tienen diseños de cuadrícula o subcuadrícula.
Captura de pantalla de DevTools de Firefox

Recursos

Consultas de contenedores

Navegadores compatibles

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

Origen

Antes de @container, los elementos de una página web solo podían responder al tamaño del viewport completo. Esto es ideal para diseños macro, pero para los diseños micro, en los que su contenedor externo no es toda la ventana de visualización, es imposible que el diseño se ajuste de manera adecuada.

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

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

Estos estilos son los que permiten que los elementos del evento puedan consultar las columnas de lunes, martes, miércoles, jueves y viernes en el siguiente video.

Demostración de Una Kravets

Este es el código CSS para consultar el tamaño del contenedor calendar-day y, luego, ajustar un diseño y 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 por Max Böck

Una tiene razón al evaluar la situación como la nueva respuesta. Hay muchas decisiones de diseño emocionantes y significativas para tomar cuando usas @container.

Recursos

accent-color

Navegadores compatibles

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

Origen

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 brindaban todas las opciones y, con suerte, también incluían accesibilidad, seguir eligiendo la opción de usar los componentes integrados o adoptar los tuyos es tedioso.

Después de accent-color, una línea de CSS agrega un color de marca a los componentes integrados. Además de un tono, el navegador elige de forma inteligente los colores de contraste adecuados para las partes secundarias del componente y se adapta a los esquemas de colores del sistema (claros o oscuros).

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

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

Elementos HTML con acentos claros y oscuros en paralelo para compararlos.

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

Recursos

Niveles de color 4 y 5

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

Sin embargo, no en 2022. CSS tiene varias funciones y espacios de color nuevos: Colores que llegan a las capacidades de color HD de las pantallas. - Espacios de color que coinciden con un intent, 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 trabajar.

Antes de todas estas funciones de color, los sistemas de diseño necesitaban calcular previamente los colores de contraste adecuados y garantizar paletas de colores adecuados, 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 temas y los colores de visualización de datos, CSS puede realizar la organización y los cálculos. CSS también está mejor preparado para verificar la compatibilidad antes del uso o controlar los resguardos con elegancia.

@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()

Navegadores compatibles

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

Origen

HWB significa tono, blancura y negrura. Se presenta como una forma amigable para las personas de articular el color, ya que es solo un tono y una cantidad de blanco o negro para aclarar o oscurecer. Es posible que los artistas que mezclan colores con blanco o negro aprecien esta adición a la sintaxis de colores.

El uso de esta función de color genera colores del espacio de color sRGB, al igual que HSL y RGB. En términos de novedad para 2022, esto no ofrece colores nuevos, pero puede facilitar algunas tareas para los fans de la sintaxis y el modelo mental.

Recursos

Espacios de color

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

El CSS de 2022 ofrecerá 10 espacios de color nuevos, cada uno con funciones ú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 color, pero ahora CSS desbloquea un nuevo potencial y un nuevo espacio de color predeterminado: LCH.

color-mix()

Navegadores compatibles

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

Origen

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 combinación de colores tampoco proporcionaban la opción de especificar en qué espacio de color se debía realizar la combinación, 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 los demás estilos, sin ejecutar procesos de compilación ni incluir JavaScript. Además, pueden especificar en qué espacio de color realizar la combinación o usar el espacio de color de combinación predeterminado de LCH.

A menudo, se usa un color de 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 del mouse. A continuación, te mostramos cómo 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 quieres 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 mezclar colores en varios espacios de color en tus hojas de estilo en 2022.

Recursos

color-contrast()

Navegadores compatibles

  • Chrome: No se admite.
  • Edge: No es compatible.
  • Firefox: No es compatible.
  • Safari: Detrás de una marca.

Origen

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

Captura de pantalla de 3 paletas de Material, que 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 transferir la tarea por completo al navegador. No solo puedes emplear el navegador para elegir automáticamente un color negro o blanco, sino también proporcionarle una lista de colores adecuados del sistema de diseño y pedirle que elija el primero para pasar la relación de contraste deseada.

Esta es una captura de pantalla de una demo de conjunto de paleta de colores HWB en la que el navegador elige automáticamente los colores de texto según el color de la muestra:

Captura de pantalla de la demostración de HWB en la que cada paleta tiene una combinación diferente de texto claro o oscuro, según lo determine el navegador.
Probar la demostración

Los conceptos básicos de la sintaxis se ven de la siguiente manera, en los que el gris se pasa 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 se elegirá el color con el contraste más alto 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 contraste más alto de la lista, se puede proporcionar una relación de contraste objetivo, y se elige el primer color que la cumpla:

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 */
);

Esta función no solo sirve para el color de texto, aunque estimamos que ese será su caso de uso principal. Piensa en lo mucho más fácil que será entregar interfaces accesibles y legibles una vez que la elección de colores contrastantes adecuados esté integrada en el lenguaje CSS.

Recursos

Sintaxis de colores relativos

Navegadores compatibles

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

Origen

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

Después de la sintaxis de color relativa, cualquier color en cualquier espacio se puede deconstruir, modificar y mostrar como un color, todo en una línea de CSS. No hay más 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 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 con 75%, manteniendo el 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 el 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 es más similar a las alteraciones que a la combinación. Puedes transmitir un color desde otro color y obtener acceso a los tres valores de canal según el nombre que le asigne la función de color que se use, con la oportunidad de ajustar esos canales. En resumen, esta es una sintaxis muy interesante y potente para el color.

En la siguiente demostración, usé la sintaxis de color relativa para crear variantes más claras y más 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 del centro.
Probar la demostración

Esta función también se puede usar para generar una paleta de colores. Esta es una demostración en la que se generan paletas completas a partir de un color base proporcionado. Este conjunto de CSS potencia todas las paletas, y cada una simplemente proporciona una base diferente. Como beneficio adicional, como usé LCH, observa lo uniformes que son las paletas a nivel perceptual: no se ven puntos calientes ni 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 por CSS.
Probar la demostración

Con suerte, a estas alturas, puedes ver cómo los espacios de color y las diferentes funciones de color se pueden usar para diferentes fines, según sus fortalezas y debilidades.

Recursos

Espacios de color de gradiente

Antes de los espacios de color con gradiente, sRGB era el espacio de color predeterminado. Por lo general, sRGB es confiable, pero presenta algunas debilidades, como la zona muerta gris.

4 gradientes en una cuadrícula, todos de cian a rosa intenso. LCH y LAB tienen una vitalidad más constante, en la 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 usar para la interpolación de colores. Esto 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
);

Este es 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 vuelven blancos demasiado tarde.

11 espacios de color que comparan el negro con el blanco.

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

Se muestran 11 espacios de color que comparan el azul con el negro.

Para obtener exploraciones, ejemplos y comentarios más detallados, consulta esta conversación de Twitter.

Recursos

inert

Navegadores compatibles

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

Origen

Antes de inert, se recomendaba guiar la atención del usuario a 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, escuchaban eventos de cambio de enfoque y, si el enfoque salía del espacio interactivo, se volvía a forzar. Los usuarios que usan teclados o lectores de pantalla se dirigen al espacio interactivo para asegurarse de que la tarea se haya completado antes de continuar.

Después de inert, no se requiere la captura, ya que puedes inmovilizar o proteger secciones completas de una página o app. Los clics y los intentos de cambio de enfoque simplemente no están disponibles mientras esas partes de un documento están inertes. También se puede pensar en esto como guardias en lugar de una trampa, en la que inert no está interesado en hacerte quedar en algún lugar, sino en hacer 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 alert() y la página ya no está activa.

En el video anterior, observa 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 se congeló, o inert. El enfoque de los usuarios se coloca dentro del diálogo de la alerta y no tiene adó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 a los desarrolladores lograr esta misma experiencia de enfoque guiada con facilidad.

Este es 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 deslizante. Cuando un usuario desliza el menú lateral, no es correcto permitir que el mouse o el teclado interactúen con la página detrás de él. Eso es un poco complicado para los usuarios. En su lugar, cuando se muestre el menú lateral, debes desactivar la página. Ahora los usuarios deben cerrar o navegar dentro de ese menú lateral y no se perderán en ningún otro lugar de la página con el menú abierto.

Recursos

Fuentes COLRv1

Antes de las fuentes COLRv1, la Web tenía fuentes OT-SVG, que también es un formato abierto para fuentes con gradientes 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 con un menor espacio en disco, escalables vectoriales, reposicionables, con gradientes y con modo de combinación que aceptan parámetros para personalizar la fuente según el caso de uso o para que coincida con una marca.

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

Este es un ejemplo de la entrada de blog de Chrome Developers sobre los emojis. Tal vez hayas notado que, si aumentas el tamaño de la fuente de un emoji, no se mantiene nítido. Es una imagen y no arte vectorial. A menudo, cuando se usa un emoji en las aplicaciones, estos se reemplazan por uno de mayor calidad. Con las fuentes COLRv1, los emojis son atractivos y vectoriales:

Las fuentes de íconos pueden hacer cosas increíbles con este formato, ya que ofrecen paletas de colores de dos tonos personalizados y mucho más. Cargar una fuente COLRv1 es igual que 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 at-rule CSS especial para agrupar y nombrar un conjunto de opciones de personalización en un paquete para referencia posterior. Observa cómo especificas un nombre personalizado, al igual que una propiedad personalizada, que comienza 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 use 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/

A medida que cada vez más fuentes variables y fuentes de color están disponibles, la tipografía web está en un camino magnífico hacia una personalización enriquecida y una 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 viewports.

Antes de las nuevas variantes de viewports, 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). Estos funcionaban 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, que ocupa parte del espacio del viewport. Después de unos segundos y cierta interactividad, es posible que la barra de estado se deslice para permitir una experiencia de viewport más grande para el usuario. Sin embargo, cuando esa barra se desliza hacia afuera, cambia la altura del viewport y cualquier unidad vh se desplazaría y cambiaría de tamaño a medida que cambie su tamaño objetivo. En años posteriores, la unidad vh necesitaba específicamente decidir cuál de los dos tamaños de viewport iba a usar, ya que causaba problemas de diseño visual molestos en dispositivos móviles. Se determinó que vh siempre representaría la ventana de visualización más grande.

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

Después de las nuevas variantes de viewport, se ponen a disposición las unidades de viewport pequeñas, grandes y dinámicas, con la adición de equivalentes lógicos a las físicas. La idea es brindar a los desarrolladores y diseñadores la capacidad de elegir qué unidad quieren usar para su situación determinada. Tal vez esté bien tener un pequeño cambio de diseño molesto cuando la barra de estado desaparezca, por lo que se podría usar dvh (altura de viewport dinámico) sin preocupaciones.

Gráfico con tres teléfonos para ayudar a ilustrar el DVH, la 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 del viewport, y otra entre la parte superior de la barra de búsqueda (debajo de la barra de estado del sistema) y la parte inferior del viewport, lo que muestra cómo el DVH puede tener cualquiera de estas dos longitudes. La 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 del viewport 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 del viewport.

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

Unidades de altura del viewport
​​.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 la ventana de visualización de ancho
.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 más pequeñas del viewport
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
Unidades laterales más grandes de la vista del puerto
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

Con suerte, esto les dará a los desarrolladores y diseñadores la flexibilidad necesaria para lograr sus diseños responsivos de viewport.

Recursos

:has()

Navegadores compatibles

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

Origen

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

Después de :has(), un tema más alto en el árbol de elementos puede permanecer como tema mientras proporciona una consulta sobre los elementos secundarios: ul:has(> li). Es fácil comprender cómo :has() obtuvo el nombre común de “selector superior”, ya que el sujeto del selector ahora es el superior en este caso.

Este es un ejemplo de sintaxis básica en el que la clase .parent sigue siendo el tema, 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 asunto, 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 utilidad fantástica una vez que se hacen evidentes más casos de uso prácticos. Por ejemplo, actualmente no es posible seleccionar etiquetas <a> cuando unen imágenes, lo que dificulta enseñarle a la etiqueta de ancla cómo cambiar sus estilos en ese caso de uso. Es posible con :has() de la siguiente manera:

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

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

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

Las combinaciones son aparentemente infinitas. Combina :has() con consultas de cantidad y ajusta los diseños de cuadrícula de CSS en función de la cantidad de elementos secundarios. Combina :has() con estados de pseudoclase interactivos y crea aplicaciones que respondan de nuevas formas creativas.

La verificación de compatibilidad se simplifica 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 más allá

Hay una serie de cosas que será difícil de hacer después de que se lancen estas increíbles funciones en 2022. En la siguiente sección, se analizan algunos de los problemas restantes y las soluciones que se desarrollan activamente para resolverlos. Estas soluciones son experimentales, aunque pueden estar especificadas o disponibles detrás de marcas en los navegadores.

El resultado de las siguientes secciones debería ser la tranquilidad de que muchas personas de muchas empresas buscan una solución para los problemas enumerados, no que estas soluciones se lanzarán en 2023.

Propiedades personalizadas con tipado flexible

Navegadores compatibles

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

Origen

Las propiedades personalizadas de CSS son increíbles. Permiten que se almacene todo tipo de elementos dentro de una variable nombrada, que luego se puede extender, calcular, compartir y mucho más. De hecho, son tan flexibles que sería bueno tener algunos que sean menos flexibles.

Considera una situación en la que un objeto 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 se cambia una de las propiedades a un valor que CSS no acepta, como --x: red. Toda la sombra se interrumpe si falta alguna de las variables anidadas o si se establece en un tipo de valor no válido.

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

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

Ahora, cuando box-shadow use var(--x) y, más tarde, se intente --x: red, se ignorará red, ya que no es un <length>. Esto significa que la sombra sigue funcionando, aunque se haya otorgado un valor no válido a una de sus propiedades personalizadas. En lugar de fallar, se revierte 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 algunos elementos, como los gradientes. @property ayuda aquí porque la propiedad CSS escrita puede informar al navegador sobre la intención de un desarrollador dentro de una interpolación demasiado compleja. En esencia, limita el alcance de las posibilidades en la medida en que un navegador puede animar aspectos de un estilo que antes no podía.

Considera este ejemplo de demostración, en el que se usa un gradiente radial para formar una parte de una superposición y crear un efecto de enfoque destacado. JavaScript establece las teclas x e y del mouse cuando se presiona la tecla alt/opt y, luego, cambia el tamaño focal a un valor más pequeño, como 25%, lo que crea el círculo de enfoque destacado en la posición del mouse:

Prueba 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 “derive” cómo quieres que se animen. Sin embargo, con @property, se puede escribir y animar una propiedad de forma aislada, por lo que el navegador puede comprender fácilmente el intent.

Los videojuegos que usan este efecto de enfoque siempre animan el círculo, desde un círculo grande hasta uno pequeño. A continuación, te mostramos cómo usar @property con nuestra demo 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

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

@property puede hacer mucho más, pero estos pequeños habilitamientos pueden ser muy útiles.

Recursos

Estaba en min-width o max-width

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

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

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

@media (width >= 320px) {
  
}

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

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

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

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

Según tu experiencia en programación, una de ellas se verá mucho más legible que la otra. Gracias a las incorporaciones a las especificaciones, los desarrolladores podrán elegir cuál prefieren o incluso usarlos de forma intercambiable.

Recursos

No hay variables de consulta de contenido multimedia

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

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

Nombrar elementos es muy importante: puede alinear el propósito con la sintaxis, lo que facilita compartir y usar en equipos. Estas son algunas búsquedas de contenido multimedia personalizado que me siguen 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 personalizados que uso en mi biblioteca de propiedades personalizadas de CSS Open Props.

Recursos

Anidar selectores es muy bueno

Antes de @nest, había mucha repetición en los diseños de plantillas. Se volvió especialmente difícil de manejar cuando los selectores eran largos y cada uno se orientaba a diferencias pequeñas. La conveniencia 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 de anidamiento habilitadas por 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 para mí sobre el anidamiento, 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 saltar de un selector y sus estilos a otro que tenga diseños (ejemplo 1), el lector puede permanecer dentro del contexto de un artículo y ver si el artículo posee vínculos dentro de él. La relación y el intent de estilo se agrupan, por lo que article parece tener sus propios estilos.

La propiedad también podría considerarse centralización. En lugar de buscar en un hoja de estilo los estilos relevantes, todos se pueden encontrar anidados juntos dentro de 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 quiere ajustarse cuando se encuentra en un contexto superior diferente, en comparación con el elemento superior que posee el estilo y cambia un elemento 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 con una organización, centralización y propiedad de estilo más saludables. Los componentes pueden agrupar y poseer sus propios estilos, en lugar de que se distribuyan entre otros bloques de estilo. Puede parecer pequeño en estos ejemplos, pero puede tener impactos muy grandes, tanto para la comodidad como para la legibilidad.

Recursos

Definir los estilos de alcance es muy difícil.

Navegadores compatibles

  • Chrome: 118.
  • Edge: 118.
  • Firefox: Detrás de una marca.
  • Safari: 17.4.

Origen

Antes del @scope, existían muchas estrategias porque los estilos de CSS se transmiten en cascada, heredan y tienen alcance global de forma predeterminada. Estas funciones de CSS son muy convenientes para muchas cosas, pero en el caso de 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 se sientan como si se filtraran.

Después de @scope, no solo se pueden definir los estilos dentro de un contexto, como una clase, sino que también se pueden articular 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 nombres de BEM se puede revertir en el intent real. El selector de BEM intenta asignar el color de un elemento header a un contenedor .card con convenciones de nombres. Esto requiere que el encabezado tenga este nombre de clase, lo que completa el objetivo. Con @scope, no se requieren convenciones de nombres 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 del CSS. Los temas oscuro y claro deben coexistir dentro de una hoja de estilo, en la que el orden es importante para determinar un estilo ganador. Por lo general, esto significa que los estilos del tema oscuro aparecen después del tema claro, lo que establece el tema claro como el predeterminado y el oscuro como el opcional. Evita la lucha entre 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 termina el alcance del estilo. Esto no se puede hacer con ninguna convención de nombres ni preprocesador. Es especial y solo CSS integrado en el navegador puede hacerlo. 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 opciones de CSS para un diseño de mampostería

Antes de la mampostería de CSS con cuadrícula, JavaScript era la mejor manera de lograr un diseño de mampostería, ya que cualquiera de los métodos CSS con columnas o flexbox representaba 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, en el que se muestran los 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 logra con el siguiente CSS:

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

Es reconfortante saber que esto está en el radar como una estrategia de diseño faltante, además, puedes probarlo hoy en Firefox.

Recursos

CSS no puede ayudar a los usuarios a reducir los datos.

Navegadores compatibles

  • Chrome: detrás de una bandera.
  • Edge: Detrás de una marca.
  • Firefox: No es compatible.
  • Safari: no es compatible.

Origen

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

Después de la consulta de medios prefers-reduced-data, el 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 contenido multimedia y los ahorros pueden ser enormes. Cuanto más grande sea el viewport de los visitantes, más ahorros se obtendrán en la carga de la página. El guardado continúa a medida que los usuarios interactúan con los controles deslizantes de contenido multimedia. Todas las imágenes tienen atributos loading="lazy", lo que, combinado con el CSS que oculta el elemento por completo, 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.

Para mi prueba, en un viewport de tamaño medio, se cargaron inicialmente 40 solicitudes y 700 KB de recursos. A medida que un usuario se desplaza por la selección de contenido multimedia, se cargan más solicitudes y recursos. Con CSS y la consulta de medios de datos reducida, se cargan 10 solicitudes y 172 KB de recursos. Eso es medio megabyte de ahorro y el usuario ni siquiera desfiló ninguno de los elementos multimedia, en cuyo punto no se realizan solicitudes adicionales.

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

Esta experiencia de datos reducidos tiene 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 la atención. Muchos usuarios navegan en el modo de ahorro de datos porque pagan por megabyte de datos. Es bueno ver que CSS puede ayudar aquí.

Recursos

Las funciones de ajuste de desplazamiento son demasiado limitadas

Antes de estas propuestas de ajuste del desplazamiento, escribir tu propio código JavaScript para administrar un carrusel, un control deslizante o una galería podía complicarse rápidamente, con todos los observadores y la administración de estado. Además, si no tienes 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 sienta un poco poco natural y, posiblemente, torpe.

API nuevas

snapChanging()

En cuanto el navegador lance un elemento secundario de instantáneas, se activará este evento. Esto permite que la IU refleje la falta de un elemento secundario de ajuste y el estado de ajuste indeterminado del control deslizante, ya que ahora se está usando y se ubicará en un 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 elemento secundario nuevo y se detiene el control deslizante. 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, cuando se carga la página, está oculta inicialmente hasta que te desplazas hacia la parte superior. Esta propiedad de CSS permite a los desarrolladores especificar que un desplazador 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 en ese momento.

.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 del desplazamiento, es mucho más fácil crear un control deslizante, un carrusel o una galería, ya que el navegador ahora ofrece comodidades para la tarea, lo que elimina los observadores y el código de orquestación del 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 su adopción y prueba pronto.

Recursos

Cómo alternar entre estados conocidos

Antes de toggle(), solo se podían aprovechar los estados integrados en el navegador para aplicar diseño y establecer interacciones. La entrada de la casilla de verificación, por ejemplo, tiene :checked, un estado del navegador administrado internamente para la entrada que CSS puede usar a fin de cambiar el elemento de forma visual.

Después de toggle(), se pueden crear estados personalizados en cualquier elemento para que CSS los cambie y los use con fines de diseño. Permite grupos, alternancia dirigida, ciclismo y mucho más.

En el siguiente ejemplo, se logra el mismo efecto de una línea diagonal en 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 relevantes:

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 compilar más de su estado en CSS, lo que, con suerte, dará como resultado formas más claras y semánticas de organizar la interacción y el estado.

Recursos

Personaliza elementos seleccionados

Antes de <selectmenu>, CSS no podía personalizar 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 diseñarlos tanto como necesiten, sin dejar de cumplir con los requisitos de accesibilidad y proporcionar HTML semántico.

En el siguiente ejemplo, tomado 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>

CSS puede orientar y aplicar diseño a 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 realce rojo.

Puedes probar el elemento <selectmenu> en Chromium en Canary con el indicador de experimentos web habilitado. En 2023 y en el futuro, presta atención a los elementos del menú seleccionables y personalizables.

Recursos

Cómo fijar un elemento a otro

Antes de anchor(), la posición absoluta y relativa eran estrategias de posición proporcionadas para que los desarrolladores hicieran que los elementos secundarios se movieran dentro de un elemento superior.

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

Si te interesa obtener más información, en la explicación se proporcionan algunos ejemplos y muestras de código excelentes.

Recursos