Lo último en CSS y la IU web: Resumen de I/O 2024

La plataforma web está repleta de innovación, con funciones de CSS y de IU web a la vanguardia de esta emocionante evolución. Estamos viviendo una época dorada para la IU web, con nuevas funciones de CSS que llegan a los navegadores a un ritmo sin precedentes, lo que abre un mundo de posibilidades para crear experiencias web atractivas y hermosas. En esta entrada de blog, profundizaremos en el estado actual de CSS y exploraremos algunas de las nuevas funciones más revolucionarias que están redefiniendo la forma en que creamos aplicaciones web, presentadas en vivo en Google I/O 2024.

Experiencias interactivas novedosas

Fundamentalmente, una experiencia web es una llamada y respuesta entre tú y tus usuarios. Por eso, es tan importante invertir en interacciones de calidad con los usuarios. Hemos estado trabajando en algunas mejoras muy importantes que desbloquean capacidades que nunca antes tuvimos en la Web para navegar dentro de las páginas web y entre ellas.

Animaciones basadas en el desplazamiento

Browser Support

  • Chrome: 115.
  • Edge: 115.
  • Firefox: behind a flag.
  • Safari: 26.

Source

Como su nombre lo indica, la API de animaciones basadas en desplazamientos te permite crear animaciones dinámicas basadas en desplazamientos sin depender de observadores de desplazamientos ni de otros lenguajes de programación complejos.

Cómo crear animaciones basadas en el desplazamiento

De manera similar a cómo funcionan las animaciones basadas en el tiempo en la plataforma, ahora puedes usar el progreso de desplazamiento de un desplazador para iniciar, pausar y revertir una animación. Por lo tanto, a medida que te desplaces hacia adelante, verás que la animación progresa y, cuando te desplaces hacia atrás, se invertirá. Esto te permite crear elementos visuales parciales o de página completa con elementos que se animan dentro de la ventana gráfica y en ella, lo que también se conoce como scrollytelling, para lograr un impacto visual dinámico.

Las animaciones controladas por desplazamiento se pueden usar para destacar contenido importante, guiar a los usuarios a través de una historia o simplemente agregar un toque dinámico a tus páginas web.

Elemento visual de la animación controlada por desplazamiento

Demostración en directo

@keyframes appear {
  from {
    opacity: 0;
    scale: 0.8;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}

img {
  animation: appear linear;
  animation-timeline: view();
  animation-range: entry 25% cover 50%;
}

El código anterior define una animación simple que aparece en el viewport cambiando la opacidad y la escala de una imagen. La animación se basa en la posición de desplazamiento. Para crear este efecto, primero configura la animación CSS y, luego, establece el animation-timeline. En este caso, la función view() con sus valores predeterminados hace un seguimiento de la imagen en relación con el puerto de desplazamiento (que, en este caso, también es el viewport).

Es importante tener en cuenta la compatibilidad con el navegador y las preferencias del usuario, especialmente para las necesidades de accesibilidad. Por lo tanto, usa la regla @supports para verificar si el navegador admite animaciones controladas por desplazamiento y, luego, incluye tu animación controlada por desplazamiento en una consulta de preferencias del usuario, como @media (prefers-reduced-motion: no-preference), para respetar las preferencias de movimiento de los usuarios. Después de realizar estas verificaciones, sabrás que tus estilos funcionarán y que la animación no será problemática para el usuario.

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Apply scroll-driven animations here */
  }
}

Las animaciones controladas por desplazamiento pueden significar experiencias de narración visual de página completa, pero también pueden significar animaciones más sutiles, como una barra de encabezado que se minimiza y muestra una sombra a medida que te desplazas por una app web.

Elemento visual de la animación controlada por desplazamiento

Demostración en directo

@keyframes shrink-name {
  from {
    font-size: 2em;
  }
  to {
    font-size: 1.5em;
  }
}

@keyframes add-shadow {
  from {
    box-shadow: none;
  }
  to {
    box-shadow: 0 4px 2px -2px gray;
  }
}

header {
  animation: add-shadow linear both;
}

h2 {
  animation: shrink-name linear both;
}

header, h2 {
  animation-timeline: scroll();
  animation-range: 0 150px;
}

En esta demostración, se usan algunas animaciones de fotogramas clave diferentes (el encabezado, el texto, la barra de navegación y el fondo) y, luego, se aplica la animación controlada por desplazamiento correspondiente a cada una. Si bien cada uno tiene un estilo de animación diferente, todos tienen la misma línea de tiempo de animación, el mismo elemento de desplazamiento más cercano y el mismo rango de animación, desde la parte superior de la página hasta 150 píxeles.

Beneficios de rendimiento de las animaciones basadas en el desplazamiento

Esta API integrada reduce la carga de código que deberías mantener, ya sea un script personalizado que escribiste o la inclusión de una dependencia adicional de terceros. También elimina la necesidad de enviar varios observadores de desplazamiento, lo que significa que hay beneficios de rendimiento bastante significativos. Esto se debe a que las animaciones controladas por desplazamiento funcionan en el subproceso principal cuando se animan propiedades que se pueden animar en el compositor, como las transformaciones y la opacidad, ya sea que uses la nueva API directamente en CSS o los enlaces de JavaScript.

Tokopedia usó recientemente animaciones controladas por desplazamiento para que la barra de navegación de productos apareciera a medida que te desplazabas. El uso de esta API tuvo beneficios importantes, tanto para la administración del código como para el rendimiento.

Las animaciones controladas por desplazamiento impulsan esta barra de navegación de productos en Tokopedia a medida que te desplazas hacia abajo.

"Logramos reducir hasta un 80% nuestras líneas de código en comparación con el uso de eventos de desplazamiento de JS convencionales y observamos que el uso promedio de la CPU se redujo del 50% al 2% durante el desplazamiento. - Andy Wihalim, ingeniero de software sénior, Tokopedia"

El futuro de los efectos de desplazamiento

Sabemos que estos efectos seguirán haciendo de la Web un lugar más atractivo, y ya estamos pensando en lo que podría venir después. Esto incluye la capacidad de no solo usar nuevos cronogramas de animación, sino también un punto de desplazamiento para activar el inicio de una animación, llamadas animaciones activadas por desplazamiento.

Además, en el futuro, los navegadores tendrán aún más funciones de desplazamiento. En la siguiente demostración, se muestra una combinación de estas funciones futuras. Utiliza scroll-start-target de CSS para establecer la fecha y hora iniciales en los selectores, y el evento scrollsnapchange de JavaScript para actualizar la fecha del encabezado, lo que facilita la sincronización de los datos con el evento ajustado.

Ver la demostración en vivo en Codepen

También puedes usar esto para actualizar un selector en tiempo real con el evento scrollsnapchanging de JavaScript.

Actualmente, estas funciones particulares solo están disponibles en Canary detrás de una marca, pero desbloquean capacidades que antes eran imposibles o muy difíciles de crear en la plataforma y destacan el futuro de las posibilidades de interacción basadas en el desplazamiento.

Para obtener más información sobre cómo comenzar a usar las animaciones controladas por desplazamiento, nuestro equipo acaba de lanzar una nueva serie de videos que puedes encontrar en el canal de YouTube de Chrome for Developers. Aquí, aprenderás los conceptos básicos de las animaciones controladas por desplazamiento de Bramus Van Damme, incluido cómo funciona la función, el vocabulario, las diversas formas de crear efectos y cómo combinar efectos para crear experiencias enriquecidas. Es una excelente serie de videos que puedes mirar.

Transiciones de vista

Acabamos de ver una nueva y potente función para animar dentro de las páginas web, pero también hay una nueva y potente función llamada transiciones de vista para animar entre vistas de páginas y crear una experiencia del usuario sin inconvenientes. Las transiciones de vista introducen un nuevo nivel de fluidez en la Web, lo que te permite crear transiciones fluidas entre diferentes vistas dentro de una sola página o incluso entre diferentes páginas.

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 144.
  • Safari: 18.

Source

Airbnb es una de las empresas que ya experimentan con la integración de transiciones de vista en su IU para brindar una experiencia de navegación web fluida y sin inconvenientes. Esto incluye la barra lateral del editor de fichas, la edición de fotos y el agregado de comodidades, todo dentro de un flujo de usuarios fluido.

Una transición de vista en el mismo documento, como se ve en Airbnb.
La cartera de Maxwell Barvian, que muestra transiciones de vista entre vistas.

Si bien estos efectos de página completa son atractivos y fluidos, también puedes crear microinteracciones, como este ejemplo en el que se actualiza la vista de lista cuando el usuario interactúa. Este efecto se puede lograr sin esfuerzo con las transiciones de vista.

La forma de habilitar rápidamente las transiciones de vista en tu aplicación de una sola página es tan simple como encapsular una interacción con document.startViewTransition y asegurarte de que cada elemento que realice la transición tenga un view-transition-name, ya sea intercalado o de forma dinámica con JavaScript a medida que creas nodos DOM.

Demostración visual

Demostración en directo

document.querySelectorAll('.delete-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    document.startViewTransition(() => {
      btn.closest('.card').remove();
    });
  })
});
/* Styles for the transition animation */
::view-transition-old(.card):only-child {
  animation: fade-out ease-out 0.5s;
}

Cómo ver las clases de transición

Los nombres de transición de la vista se pueden usar para aplicar animaciones personalizadas a la transición de la vista, aunque esto puede resultar engorroso con muchos elementos en transición. La primera actualización nueva de las transiciones de vista de este año simplifica este problema y presenta la capacidad de crear clases de transición de vista que se pueden aplicar a animaciones personalizadas.

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: 144.
  • Safari: 18.2.

Source

Tipos de transiciones de vista

Otra gran mejora para las transiciones de vista es la compatibilidad con los tipos de transición de vista. Los tipos de transición de vista son útiles cuando deseas un tipo diferente de transición de vista visual al animar hacia las vistas de página y desde ellas.

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: 144.
  • Safari: 18.

Source

Por ejemplo, es posible que desees que una página de inicio se anime a una página de blog de una manera diferente a la que esa página de blog se anima de nuevo a la página de inicio. O tal vez quieras que las páginas entren y salgan de diferentes maneras, como en este ejemplo, de izquierda a derecha y viceversa. Antes, esto era complicado. Podías agregar clases al DOM para aplicar estilos y, luego, tenías que quitarlas. Los tipos de transición de vista permiten que el navegador limpie las transiciones antiguas en lugar de requerir que lo hagas manualmente antes de iniciar otras nuevas, lo que hace este trabajo por ti.

Grabación de la demostración de paginación. Los tipos determinan qué animación usar. Los diseños se separan en la hoja de diseño gracias a los tipos de transición activos.

Puedes configurar tipos dentro de tu función document.startViewTransition, que ahora acepta un objeto. update es la función de devolución de llamada que actualiza el DOM, y types es un array con los tipos.

document.startViewTransition({
  update: myUpdate,
  types: ['slide', 'forwards']
})

Transiciones de vista de varias páginas

Lo que hace que la Web sea potente es su gran expansión. Muchas aplicaciones no son solo una página, sino un tapiz sólido que contiene varias páginas. Por eso, nos complace anunciar que lanzaremos la compatibilidad con las transiciones de vista entre documentos para aplicaciones de varias páginas en Chromium 126.

Browser Support

  • Chrome: 126.
  • Edge: 126.
  • Firefox: not supported.
  • Safari: 18.2.

Source

Este nuevo conjunto de funciones entre documentos incluye experiencias web que se encuentran en el mismo origen, como navegar de web.dev a web.dev/blog, pero no incluye la navegación entre orígenes, como navegar de web.dev a blog.web.dev o a otro dominio como google.com.

Una de las principales diferencias con las transiciones de vista dentro del mismo documento es que no necesitas incluir la transición en document.startViewTransition(). En su lugar, habilita ambas páginas involucradas en la transición de vista con la regla @view-transition de CSS.

@view-transition {
  navigation: auto;
}

Para lograr un efecto más personalizado, puedes conectar JavaScript con los nuevos objetos de escucha de eventos pageswap o pagereveal, que te brindan acceso al objeto de transición de vista.

Con pageswap, puedes realizar algunos cambios de último momento en la página saliente justo antes de que se tomen las instantáneas anteriores y, con pagereveal, personalizar la página nueva antes de que comience a renderizarse después de que se haya inicializado.

window.addEventListener('pageswap', async (e) => {
    // ...
});

window.addEventListener('pagereveal', async (e) => {
    // ...
});
Muestra transiciones de vistas en una app de varias páginas. Consulta el vínculo de demostración.

En el futuro, planeamos expandir las transiciones de vista, lo que incluye lo siguiente:

  • Transiciones con alcance: Te permiten limitar una transición a un subárbol del DOM, lo que permite que el resto de la página siga siendo interactivo y admite varias transiciones de vista que se ejecutan al mismo tiempo.
  • Transiciones de vistas controladas por gestos: Usa gestos de arrastre o deslizamiento para activar una transición de vistas entre documentos y lograr experiencias más nativas en la Web.
  • Coincidencia de navegación en CSS: Personaliza la transición de vista entre documentos directamente en tu CSS como alternativa al uso de eventos pageswap y pagereveal en JavaScript. Para obtener más información sobre las transiciones de vista para aplicaciones de varias páginas, incluido cómo configurarlas de la manera más eficiente con la renderización previa, consulta la siguiente charla de Bramus Van Damme:

Componentes de la IU habilitados para el motor: Simplificación de interacciones complejas

Compilar aplicaciones web complejas no es tarea fácil, pero CSS y HTML están evolucionando para que este proceso sea mucho más manejable. Las nuevas funciones y mejoras simplifican la creación de componentes de la IU, lo que te permite enfocarte en crear experiencias increíbles. Esto se logra a través de un esfuerzo colaborativo que involucra a varios organismos de estándares y grupos comunitarios clave, incluidos el Grupo de trabajo de CSS, el Grupo de la comunidad de Open UI y el WHATWG (Grupo de trabajo de tecnología de aplicaciones de hipertexto web).

Uno de los principales problemas de los desarrolladores es una solicitud aparentemente simple: la capacidad de aplicar estilo a los menús desplegables (el elemento select). Si bien parece sencillo a primera vista, este es un problema complejo que afecta a muchas partes de la plataforma, desde el diseño y la renderización hasta el desplazamiento y la interacción, pasando por el diseño del agente de usuario y las propiedades de CSS, e incluso los cambios en el propio HTML.

Selección con lista de datos de opciones que tienen opciones dentro, botón de activación, flecha indicadora y opción seleccionada.
Desglose de las partes de un elemento select

Un menú desplegable consta de muchas partes y estados que se deben tener en cuenta, como los siguientes:

  • Vinculaciones de teclado (para ingresar a la interacción o salir de ella)
  • Haz clic fuera para descartar.
  • Administración activa de ventanas emergentes (cierra otras ventanas emergentes cuando se abre una)
  • Administración del enfoque de pestañas
  • Visualiza el valor de la opción seleccionada
  • Estilo de interacción de flecha
  • Administración de estado (abierto/cerrado)

Actualmente, es difícil administrar todo este estado por tu cuenta, pero la plataforma tampoco lo facilita. Para solucionar este problema, desglosamos esas partes y lanzaremos algunas funciones primitivas que permitirán diseñar menús desplegables, pero también mucho más.

La API de Popover

Primero, lanzamos un atributo global llamado popover, que me complace anunciar que alcanzó el estado de Baseline disponible hace unas semanas.

Browser Support

  • Chrome: 114.
  • Edge: 114.
  • Firefox: 125.
  • Safari: 17.

Source

Los elementos emergentes se ocultan con display: none hasta que se abren con un invocador, como un botón o con JavaScript. Para crear un elemento emergente básico, establece el atributo popover en el elemento y vincula su ID a un botón con popovertarget. Ahora, el botón es el invocador.

Demostración visual

Demostración en directo

<button popovertarget="my-popover">Open Popover</button>

<div id="my-popover" popover>
  <p>I am a popover with more information.</p>
</div>

Con el atributo popover ahora habilitado, el navegador controla muchos comportamientos clave sin necesidad de secuencias de comandos adicionales, incluidos los siguientes:

  • Promoción a la capa superior: Una capa separada sobre el resto de la página, por lo que no tienes que jugar con z-index.
  • Funcionalidad de descarte ligero: Si haces clic fuera del área de la ventana emergente, se cerrará y se volverá a enfocar.
  • Administración predeterminada del enfoque de la pestaña: Cuando se abre la ventana emergente, la siguiente parada de tabulación se realiza dentro de ella.
  • Vinculaciones de teclado integradas: Si presionas la tecla esc o cambias dos veces el botón de activación, se cerrará la ventana emergente y se devolverá el enfoque.
  • Vinculaciones predeterminadas de componentes. : El navegador conecta semánticamente una ventana emergente a su activador.
Pantalla principal de GitHub
Menú en la página principal de GitHub.

Es posible que incluso estés usando esta API de ventanas emergentes hoy mismo sin darte cuenta. GitHub implementó ventanas emergentes en el menú “Nuevo” de su página principal y en el resumen de revisión de solicitudes de extracción. Mejoraron progresivamente esta función con el polyfill de ventanas emergentes, creado por Oddbird con el importante apoyo de Keith Cirkel de GitHub, para admitir navegadores más antiguos.

"Logramos desaprobar literalmente miles de líneas de código migrando a la ventana emergente. El elemento emergente nos ayuda a eliminar la necesidad de luchar contra números mágicos de z-index… tener establecida la relación correcta del árbol de accesibilidad con el comportamiento declarativo del botón y los comportamientos de enfoque integrados facilita significativamente que nuestro sistema de diseño implemente patrones de la manera correcta". - Keith Cirkel, ingeniero de software, GitHub

Cómo animar efectos de entrada y salida

Cuando tengas ventanas emergentes, es probable que quieras agregar alguna interacción. En el último año, se lanzaron cuatro nuevas funciones de interacción para admitir la animación de ventanas emergentes. Por ejemplo:

La capacidad de animar display y content-visibility en un cronograma de fotogramas clave

La propiedad transition-behavior con la palabra clave allow-discrete para habilitar las transiciones de propiedades discretas como display.

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 129.
  • Safari: 17.4.

Source

La regla @starting-style para animar los efectos de entrada desde display: none y hacia la capa superior.

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 129.
  • Safari: 17.5.

Source

Es la propiedad de superposición para controlar el comportamiento de la capa superior durante una animación.

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: not supported.
  • Safari: not supported.

Source

Estas propiedades funcionan para cualquier elemento que animes en la capa superior, ya sea un elemento emergente o un diálogo. En conjunto, se ve de la siguiente manera para un diálogo con un fondo:

Demostración visual

Demostración en directo

dialog, ::backdrop{
  opacity: 0;
  transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}

[open], [open]::backdrop {
  opacity: 1;
}

@starting-style {
  [open], [open]::backdrop {
    opacity: 0;
  }
}

Primero, configura @starting-style para que el navegador sepa qué estilos usar para animar este elemento en el DOM. Esto se hace tanto para el diálogo como para el fondo. Luego, aplica un diseño al estado abierto del diálogo y el fondo. En el caso de un diálogo, se usa el atributo open y, en el caso de una ventana emergente, el seudoelemento ::popover-open. Por último, anima opacity, display y overlay con la palabra clave allow-discrete para habilitar el modo de animación en el que las propiedades discretas pueden realizar transiciones.

Posicionamiento del ancla

La ventana emergente fue solo el comienzo de la historia. Una actualización muy interesante es que la compatibilidad con el posicionamiento de anclaje ya está disponible a partir de Chrome 125.

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: not supported.
  • Safari: 26.

Source

Con el posicionamiento de anclaje, el navegador puede controlar la lógica para vincular un elemento posicionado a uno o más elementos de anclaje con solo unas pocas líneas de código. En el siguiente ejemplo, se ancla una información sobre herramientas simple a cada botón, posicionada en el centro inferior.

Demostración visual

Demostración en directo

Configura una relación de posición anclada en CSS con la propiedad anchor-name en el elemento de anclaje (en este caso, el botón) y la propiedad position-anchor en el elemento posicionado (en este caso, la sugerencia). Luego, aplica el posicionamiento absoluto o fijo en relación con el elemento de anclaje usando la función anchor(). El siguiente código posiciona la parte superior de la información sobre herramientas en la parte inferior del botón.

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  position-anchor: --my-anchor;
}

Como alternativa, usa el nombre de anclaje directamente en la función de anclaje y omite la propiedad position-anchor. Esto puede ser útil cuando se ancla a varios elementos.

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  top: anchor(--my-anchor bottom);
}

Por último, usa la nueva palabra clave anchor-center para las propiedades justify y align para centrar el elemento posicionado en su ancla.

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  top: anchor(--my-anchor bottom);
  justify-self: anchor-center;
}

Si bien es muy conveniente usar el posicionamiento de anclaje con el elemento emergente, este último no es un requisito para usar el posicionamiento de anclaje. El posicionamiento de anclaje se puede usar con dos o más elementos para crear una relación visual. De hecho, la siguiente demostración, inspirada en un artículo de Roman Komarov, muestra un estilo de subrayado anclado a los elementos de la lista a medida que los sobrevuelas o los seleccionas con la tecla Tab.

Demostración visual

Demostración en directo

En este ejemplo, se usa la función de anclaje para configurar la posición de anclaje con las propiedades físicas de left, right y bottom. Cuando colocas el cursor sobre uno de los vínculos, cambia el anclaje de destino y el navegador desplaza el destino para aplicar el posicionamiento, y también anima el color al mismo tiempo para crear un efecto ordenado.

ul::before {
  content: "";
  position: absolute;
  left:   anchor(var(--target) left);
  right:  anchor(var(--target) right);
  bottom: anchor(var(--target) bottom);
  ...
}

li:nth-child(1) { --anchor: --item-1 }
ul:has(:nth-child(1) a:is(:hover, :focus-visible)) {
  --target: --item-1;
  --color: red;
}

Posicionamiento inset-area

Además del posicionamiento absoluto direccional predeterminado que probablemente ya usaste, se incluye un nuevo mecanismo de diseño que se incorporó como parte de la API de posicionamiento de anclaje llamada área de inserción. El área de inserción facilita la colocación de elementos posicionados en relación con sus respectivos anclajes y funciona en una cuadrícula de 9 celdas con el elemento de anclaje en el centro. Por ejemplo, inset-area: top coloca el elemento posicionado en la parte superior y inset-area: bottom lo coloca en la parte inferior.

Con inset-area, una versión simplificada de la primera demostración de anclaje se ve de la siguiente manera:

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  position-anchor: --my-anchor;
  inset-area: bottom;
}

Puedes combinar estos valores posicionales con palabras clave de extensión para comenzar en la posición central y extenderte hacia la izquierda, hacia la derecha o en ambas direcciones para ocupar el conjunto completo de columnas o filas disponibles. También puedes usar propiedades lógicas. Para que te resulte más fácil visualizar y comprender este mecanismo de diseño, consulta esta herramienta en Chrome 125 y versiones posteriores:

Dado que estos elementos están anclados, el elemento posicionado se mueve de forma dinámica por la página a medida que se mueve su ancla. En este caso, tenemos elementos de tarjetas con diseño basado en consultas de contenedor, que cambian de tamaño según su tamaño intrínseco (algo que no se podría hacer con consultas de medios), y el menú anclado se desplazará con el nuevo diseño a medida que cambie la IU de la tarjeta.

Demostración visual

Demostración en directo

Posiciones de anclaje dinámicas con position-try-options

Los menús y la navegación por submenús son mucho más fáciles de crear con una combinación de posicionamiento de elementos emergentes y anclajes. Además, cuando llegues al borde de una ventana gráfica con tu elemento anclado, puedes dejar que el navegador controle el cambio de posición por ti. Puedes hacerlo de varias maneras. La primera es crear tus propias reglas de posición. En este caso, el submenú se posiciona inicialmente a la derecha del botón “tienda”. Sin embargo, puedes crear un bloque @position-try para cuando no haya suficiente espacio a la derecha del menú, y asignarle un identificador personalizado de --bottom. Luego, conecta este bloque @position-try al ancla con position-try-options.

Ahora, el navegador cambiará entre estos estados anclados, primero intentará la posición correcta y, luego, se desplazará hacia la parte inferior. Y esto se puede hacer con una transición agradable.

Demostración visual

Demostración en directo

#submenu {
  position-anchor: --submenu;
  top: anchor(top);
  left: anchor(right);
  margin-left: var(--padding);

  position-try-options: --bottom;

  transition: top 0.25s, left 0.25s;
  width: max-content;
}

@position-try --bottom {
  top: anchor(left);
  left: anchor(bottom);
  margin-left: var(--padding);
}

Junto con la lógica de posicionamiento explícito, hay algunas palabras clave que proporciona el navegador si deseas algunas interacciones básicas, como invertir la posición de tu ancla en las direcciones de bloque o intercaladas.

position-try-options: flip-block, flip-inline;

Para una experiencia de cambio simple, aprovecha estos valores de palabras clave de cambio y omite escribir una definición de position-try. Ahora puedes tener un elemento anclado adaptable a la ubicación y completamente funcional con solo unas pocas líneas de CSS.

Demostración visual

Demostración en directo

.tooltip {
  inset-area: top;
  position-try-options: flip-block;
}

Obtén más información para usar el posicionamiento de anclaje.

El futuro de la IU en capas

Vemos experiencias vinculadas en todas partes, y el conjunto de funciones que se muestran en esta publicación es un excelente comienzo para liberar la creatividad y tener un mejor control sobre los elementos posicionados con anclaje y las interfaces en capas. Pero esto es solo el comienzo. Por ejemplo, actualmente, popover solo funciona con botones como elemento de invocación o con JavaScript. En el caso de las vistas previas de estilo Wikipedia, un patrón que se ve en toda la plataforma web, debe ser posible interactuar con ellas y también activar una ventana emergente desde un vínculo y desde el usuario que muestra interés sin necesidad de hacer clic, como un enfoque con el cursor o con la pestaña.

Como siguiente paso para la API de ventanas emergentes, estamos trabajando en interesttarget para satisfacer estas necesidades y facilitar la recreación de estas experiencias con los enlaces de accesibilidad adecuados integrados. Este es un problema de accesibilidad difícil de resolver, con muchas preguntas abiertas sobre los comportamientos ideales, pero resolver y normalizar esta funcionalidad a nivel de la plataforma debería mejorar estas experiencias para todos.

<a interesttarget="my-tooltip">Hover/Focus to show the tooltip</a>

<span popover=hint id="my-toolip">This is the tooltip</span>

Además, hay otro invocador general orientado al futuro (invoketarget) disponible para probar en Canary gracias al trabajo de dos desarrolladores externos, Keith Cirkel y Luke Warlow. invoketarget admite la experiencia del desarrollador declarativa que popovertarget proporciona ventanas emergentes, normalizadas para todos los elementos interactivos, incluidos <dialog>, <details>, <video>, <input type="file"> y muchos más.

<button invoketarget="my-dialog">
  Open Dialog
</button>

<dialog id="my-dialog">
  Hello world!
</dialog>

Sabemos que aún hay casos de uso que no cubre esta API. Por ejemplo, aplicar diseño a la flecha que conecta un elemento anclado a su ancla, en especial a medida que cambia la posición del elemento anclado, y habilitar un elemento para que se “deslice” y permanezca en la ventana gráfica en lugar de ajustarse a otra posición establecida cuando alcanza su cuadro delimitador. Por lo tanto, si bien nos complace lanzar esta potente API, también esperamos expandir aún más sus capacidades en el futuro.

Selector con diseño

Con popover y anchor, el equipo ha avanzado para habilitar finalmente un menú desplegable de selección personalizable. La buena noticia es que se ha avanzado mucho. La mala noticia es que, en este momento, esta API aún se encuentra en un estado experimental. Sin embargo, me entusiasma compartir algunas demostraciones en vivo y actualizaciones sobre nuestro progreso, y espero recibir algunos de sus comentarios. En primer lugar, se avanzó en la forma de habilitar la nueva experiencia de selección personalizable para los usuarios. La forma actual de hacerlo, que aún está en desarrollo, es usar una propiedad de apariencia en CSS, establecida en appearance: base-select. Una vez que se establezca la apariencia, habilitarás una nueva experiencia de selección personalizable.

select {
  appearance: base-select;
}

Además de appearance: base-select, hay algunas actualizaciones nuevas de HTML. Entre ellas, se incluyen la capacidad de ajustar tus opciones en un datalist para la personalización y la capacidad de agregar contenido no interactivo arbitrario, como imágenes, en tus opciones. También tendrás acceso a un nuevo elemento, <selectedoption>, que reflejará el contenido de las opciones en sí mismo, y que podrás personalizar según tus necesidades. Este elemento es muy útil.

Demostración visual

flag demo

Demostración en directo

<select>
  <button type=popover>
    <selectedoption></selectedoption>
  </button>
  <datalist>
    <option value="" hidden>
      <p>Select a country</p>
    </option>
    <option value="andorra">
      <img src="Flag_of_Andorra.svg" />
      <p>Andorra</p>
    </option>
    <option value="bolivia">
      <img src="Flag_of_Bolivia.svg" />
      <p>Bolivia</p>
    </option>
...
  </datalist>
</select>

En el siguiente código, se muestra cómo personalizar <selectedoption> en la IU de Gmail, en la que un ícono visual representa el tipo de respuesta seleccionado para ahorrar espacio. Puedes usar estilos de visualización básicos dentro de selectedoption para diferenciar el diseño de las opciones del diseño de la vista previa. En este caso, el texto que se muestra en la opción se puede ocultar visualmente en selectedoption.

Demostración visual

Demostración de Gmail

Demostración en directo

selectedoption .text {
  display: none;
}

Una de las mayores ventajas de reutilizar el elemento <select> para esta API es la retrocompatibilidad. En esta selección de país, puedes ver una IU personalizada con imágenes de banderas en las opciones para que el usuario pueda analizar el contenido con mayor facilidad. Dado que los navegadores no compatibles ignorarán las líneas que no comprendan, como el botón personalizado, la lista de datos, la opción seleccionada y las imágenes dentro de las opciones, la alternativa será similar a la IU de selección predeterminada actual.

El navegador no compatible obtiene la experiencia de selección actual.
Visualización del navegador compatible a la izquierda y visualización alternativa del navegador no compatible a la derecha.

Con los elementos select personalizables, las posibilidades son infinitas. Me encanta este selector de países al estilo de Airbnb porque tiene un estilo inteligente para el diseño responsivo. Puedes hacer esto y mucho más con el próximo elemento select personalizable, lo que lo convierte en una incorporación muy necesaria a la plataforma web.

Demostración visual

Demostración en directo

Acordeón exclusivo

Resolver la selección de diseño (y todas las partes que la acompañan) no es el único componente de la IU en el que se ha enfocado el equipo de Chrome. La primera actualización de componentes adicionales es la capacidad de crear acordeones exclusivos, en los que solo se puede abrir uno de los elementos del acordeón a la vez.

Browser Support

  • Chrome: 120.
  • Edge: 120.
  • Firefox: 130.
  • Safari: 17.2.

Para habilitar esta opción, debes aplicar el mismo valor de nombre a varios elementos de detalles y, de este modo, crear un grupo conectado de detalles, de manera similar a un grupo de botones de opción.

Demostración exclusiva de acordeón
<details name="learn-css" open>
  <summary>Welcome to Learn CSS!</summary>
</details>

<details name="learn-css">
  <summary>Box Model</summary>
  <p>...</p>
</details>

<details name="learn-css">
  <summary>Selectors</summary>
  <p>...</p>
</details>

:user-valid y :user-invalid

Otra mejora en los componentes de la IU son las seudoclases :user-valid y :user-invalid. Estables en todos los navegadores recientemente, las seudoclases :user-valid y :user-invalid se comportan de manera similar a las seudoclases :valid y :invalid, pero coinciden con un control de formulario solo después de que un usuario interactuó de manera significativa con la entrada. Esto significa que se necesita mucho menos código para determinar si se interactuó con un valor de formulario o si se “ensució”, lo que puede ser muy útil para proporcionar comentarios a los usuarios y reduce gran parte de la secuencia de comandos que sería necesaria para hacer esto en el pasado.

Browser Support

  • Chrome: 119.
  • Edge: 119.
  • Firefox: 88.
  • Safari: 16.5.

Source

Presentación en pantalla de demostración

Demostración en directo

input:user-valid,
select:user-valid,
textarea:user-valid {
    --state-color: green;
    --bg: linear-gradient(...);
}

input:user-invalid,
select:user-invalid,
textarea:user-invalid {
    --state-color: red;
    --bg: linear-gradient(...);
}

Obtén más información para usar los seudoelementos de validación de formularios user-*.

field-sizing: content

Otra actualización de componente útil que se lanzó recientemente es field-sizing: content, que se puede aplicar a controles de formularios, como entradas y áreas de texto. Esto permite que el tamaño de la entrada aumente (o disminuya) según su contenido. field-sizing: content puede ser particularmente útil para los cuadros de texto, ya que ya no se limita a tamaños fijos en los que es posible que debas desplazarte hacia arriba para ver lo que escribiste en las partes anteriores de tu instrucción en un cuadro de entrada demasiado pequeño.

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: not supported.
  • Safari Technology Preview: supported.

Source

Presentación en pantalla de demostración

Demostración en directo

textarea, select, input {
  field-sizing: content;
}

Obtén más información sobre el tamaño de los campos.

<hr> en <select>

La capacidad de habilitar el elemento <hr> o regla horizontal en las selecciones es otra función de componente pequeña pero útil. Si bien no tiene mucho uso semántico, te ayuda a separar bien el contenido dentro de una lista de selección, en especial el contenido que no necesariamente quieres agrupar con un optgroup, como un valor de marcador de posición.

Seleccionar captura de pantalla

Captura de pantalla de HR en un menú de selección con un tema claro y oscuro en Chrome

Selecciona Demostración en vivo.

<select name="majors" id="major-select">
  <option value="">Select a major</option>
  <hr>
  <optgroup label="School of Fine Arts">
    <option value="arthist">
Art History
  </option>
  <option value="finearts">
    Fine Arts
  </option>
...
</select>

Obtén más información para usar hr en select

Mejoras en la calidad de vida

Iteramos constantemente, y no solo en las interacciones y los componentes. Hubo muchas otras actualizaciones de calidad de vida en el último año.

Anidamiento con anticipación

El anidamiento de CSS nativo llegó a todos los navegadores el año pasado y, desde entonces, mejoró para admitir la función de anticipación, lo que significa que el & antes de los nombres de los elementos ya no es un requisito. Esto hace que la anidación se sienta mucho más ergonómica y similar a lo que he usado en el pasado.

Browser Support

  • Chrome: 120.
  • Edge: 120.
  • Firefox: 117.
  • Safari: 17.2.

Source

Una de mis funciones favoritas del anidamiento de CSS es que te permite bloquear visualmente los componentes y, dentro de ellos, incluir estados y modificadores, como las consultas de contenedor y las consultas de medios. Anteriormente, solía agrupar todas estas consultas en la parte inferior del archivo para mayor especificidad. Ahora, puedes escribirlos de una manera que tenga sentido, justo al lado del resto de tu código.

.card {
  /* card base styles */

  h2 {
    /* child element style */
  }

  &.highlight {
    /* modifier style */
  }

  &:hover, &:focus {
    /* state styles */
  }

  @container (width >= 300px) {
    /* container query styles */
  }
}

Alineación de contenido para el diseño de bloques

Otro cambio muy útil es la capacidad de usar mecanismos de centrado como align-content en el diseño de bloques. Esto significa que ahora puedes centrar elementos verticalmente dentro de un div sin necesidad de aplicar un diseño de flex o cuadrícula, y sin efectos secundarios, como evitar el colapso de márgenes, que tal vez no desees de esos algoritmos de diseño.

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: 125.
  • Safari: 17.4.

Captura de pantalla

Demostración en directo

div {
  align-content: center;
}

Ajuste de texto: equilibrado y atractivo

Hablando de diseño, el diseño de texto mejoró considerablemente con la incorporación de text-wrap: balance y pretty. text-wrap: balance se usa para un bloque de texto más uniforme, mientras que text-wrap: pretty se enfoca en reducir los elementos únicos en la última línea del texto.

Presentación en pantalla de demostración

Demostración en directo

En la siguiente demostración, puedes comparar los efectos de balance y pretty en un encabezado y un párrafo arrastrando el control deslizante. Prueba traducir la demostración a otro idioma.
h1 {
  text-wrap: balance;
}

Obtén más información sobre text-wrap: balance.

Actualizaciones de la tipografía internacional

Las actualizaciones del diseño tipográfico para las funciones de texto en CJK recibieron muchas actualizaciones interesantes el año pasado, como la función word-break: auto-phrase que ajusta la línea en el límite natural de la frase.

Browser Support

  • Chrome: 119.
  • Edge: 119.
  • Firefox: not supported.
  • Safari: not supported.

word-break: auto-phrase ajusta la línea en el límite natural de la frase.
Comparación de word-break: normal y word-break: auto-phrase

Y text-spacing-trim, que aplica el interletraje entre los signos de puntuación para mejorar la legibilidad de la tipografía en chino, japonés y coreano, y obtener resultados más atractivos visualmente.

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: not supported.
  • Safari: not supported.

Source

La mitad derecha del período CJK se quita con text-spacing-trim.
Cuando aparecen caracteres de puntuación en una fila, se debe quitar la mitad derecha del período CJK.

Sintaxis de color relativa

En el mundo de los temas de color, vimos una gran actualización con la sintaxis de color relativa.

En este ejemplo, los colores usan temas basados en Oklch. A medida que el valor de tono se ajusta según el control deslizante, cambia todo el tema. Esto se puede lograr con la sintaxis de color relativa. El fondo usa el color principal, según el tono, y ajusta los canales de luminosidad, croma y tono para ajustar su valor. --i es el índice de elementos secundarios en la lista para la gradación de valores, que muestra cómo puedes combinar la discretización con propiedades personalizadas y sintaxis de color relativa para crear temas.

Presentación en pantalla de demostración

Demostración en directo

En la siguiente demostración, puedes comparar los efectos de balance y pretty en un encabezado y un párrafo arrastrando el control deslizante. Prueba traducir la demostración a otro idioma.
:root {
  --hue: 230;
  --primary: oklch(70% .2 var(--hue));
}

li {
  --_bg: oklch(from var(--primary)
    calc(l - (var(--i) * .05))
    calc(c - (var(--i) * .01))
    calc(h - (var(--i) + 5)));
}

Función light-dark()

Junto con la función light-dark(), la aplicación de temas se volvió mucho más dinámica y sencilla.

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: 120.
  • Safari: 17.5.

Source

La función light-dark() es una mejora ergonómica que simplifica las opciones de temas de color para que puedas escribir estilos de temas de una manera más concisa, como se demuestra de forma tan clara en este diagrama visual de Adam Argyle. Antes, necesitabas dos bloques de código diferentes (tu tema predeterminado y una consulta de preferencia del usuario) para configurar las opciones de tema. Ahora, puedes escribir estas opciones de estilo para los temas claro y oscuro en la misma línea de CSS con la función light-dark().

Visualización de light-dark(). Consulta la demostración para obtener más información.
html {
  color-scheme: light dark;
}

button {
    background-color: light-dark(lightblue, darkblue);
}

Si el usuario seleccionó un tema claro, el botón tendrá un fondo azul claro. Si el usuario seleccionó un tema oscuro, el botón tendrá un fondo azul oscuro.

Selector de :has()

Y sería negligente hablar de la IU moderna sin mencionar uno de los aspectos más destacados de la interoperabilidad del año pasado, que debe ser el selector :has(), que se lanzó en todos los navegadores en diciembre del año pasado. Esta API es revolucionaria para escribir estilos lógicos.

Browser Support

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

Source

El selector :has() te permite verificar si un elemento secundario tiene elementos secundarios específicos o si esos elementos secundarios están en un estado específico, y, básicamente, también puede funcionar como un selector principal.

Demostración de has() que se usa para diseñar bloques de comparación en Tokopedia.

:has() ya demostró ser particularmente útil para muchas empresas, incluida PolicyBazaar, que usa :has() para diseñar bloques según su contenido interior, como en la sección de comparación, en la que el diseño se ajusta si hay un plan para comparar en el bloque o si está vacío.

"Con el selector :has(), pudimos eliminar la validación basada en JavaScript de la selección del usuario y reemplazarla por una solución CSS que funciona a la perfección para nosotros con la misma experiencia que antes" (Aman Soni, jefe técnico de PolicyBazaar).

Consultas de contenedores

Otra incorporación clave a la Web que ahora está disponible y cuyo uso está en aumento son las consultas de contenedores, que permiten consultar el tamaño intrínseco de un elemento principal para aplicar estilos: un peine mucho más fino que las consultas de medios, que solo consultan el tamaño del viewport.

Browser Support

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

Source

Recientemente, Angular lanzó un nuevo y atractivo sitio de documentación en angular.dev que utiliza consultas de contenedores para aplicar un diseño a los bloques de encabezado según el espacio disponible en la página. Por lo tanto, incluso si el diseño cambia y pasa de un diseño de barra lateral de varias columnas a un diseño de una sola columna, los bloques de encabezado pueden ajustarse por sí solos.

Angular.dev que muestra consultas de contenedores en las tarjetas de encabezado.

Sin las consultas de contenedor, hacer algo así era bastante difícil y perjudicial para el rendimiento, ya que se requerían observadores de cambio de tamaño y observadores de elementos. Ahora, es trivial aplicar un diseño a un elemento según el tamaño de su elemento principal.

Presentación en pantalla de demostración

Demostración en directo

Cómo recrear la consulta del contenedor de la tarjeta de encabezado de Angular.

@property

Por último, muy pronto, nos entusiasma ver que @property llegue a Baseline. Esta es una función clave para proporcionar significado semántico a las propiedades personalizadas de CSS (también conocidas como variables de CSS) y habilita una gran cantidad de nuevas funciones de interacción. @property también habilita el significado contextual, la verificación de tipos, los valores predeterminados y los valores de resguardo en CSS. Abrimos las puertas a funciones aún más sólidas, como las búsquedas de estilo de rango. Esta es una función que nunca antes fue posible y que ahora proporciona mucha profundidad al lenguaje de CSS.

Browser Support

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

Source

Presentación en pantalla de demostración

Demostración en directo

@property --card-bg {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0bae8;
}

Conclusión

Con todas estas nuevas y potentes funciones de IU disponibles en los navegadores, las posibilidades son infinitas. Las nuevas experiencias interactivas con animaciones controladas por el desplazamiento y transiciones de vista hacen que la Web sea más fluida e interactiva de formas que nunca habíamos visto. Además, los componentes de la IU de nivel superior facilitan más que nunca la creación de componentes sólidos y con una personalización atractiva sin tener que quitar toda la experiencia nativa. Por último, las mejoras en la calidad de vida en la arquitectura, el diseño, la tipografía y el diseño responsivo no solo resuelven los pequeños grandes problemas, sino que también les brindan a los desarrolladores las herramientas que necesitan para crear interfaces complejas que funcionan en una variedad de dispositivos, factores de forma y necesidades del usuario.

Con estas nuevas funciones, podrás quitar secuencias de comandos de terceros para funciones que consumen mucho rendimiento, como el scrollytelling y la vinculación de elementos entre sí con el posicionamiento de anclaje, crear transiciones de página fluidas, aplicar estilos a los menús desplegables y mejorar la estructura general de tu código de forma nativa.

Nunca hubo un mejor momento para ser desarrollador web. No se había visto tanta energía y entusiasmo desde el anuncio de CSS3. Las funciones que necesitábamos, pero que solo soñábamos con que se lanzaran, finalmente se están convirtiendo en realidad y forman parte de la plataforma. Gracias a tus comentarios, podemos priorizar y, finalmente, implementar estas funciones. Estamos trabajando para que sea más fácil hacer las tareas difíciles y tediosas de forma nativa, de modo que puedas dedicar más tiempo a crear lo que importa, como las funciones principales y los detalles de diseño que distinguen a tu marca.

Para obtener más información sobre estas nuevas funciones a medida que se lancen, visita developer.chrome.com y web.dev, donde nuestro equipo comparte las últimas novedades en tecnologías web. Prueba las animaciones controladas por desplazamiento, las transiciones de vista, el posicionamiento de anclaje o incluso el elemento select personalizable, y cuéntanos qué te parece. Estamos aquí para escucharte y ayudarte.