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

La plataforma web está viva en innovación, con funciones de IU web y CSS a la vanguardia de esta emocionante evolución. Vivimos en una era dorada para la IU web, con nuevas funciones de CSS que llegan a los navegadores a un ritmo que nunca vimos, lo que abre un mundo de posibilidades para crear experiencias web hermosas y atractivas. En esta entrada de blog, se analiza en profundidad el estado actual de los CSS y se exploran algunas de las funciones nuevas más revolucionarias que redefinen la manera de compilar aplicaciones web. Se presentaron en vivo en Google I/O 2024.

Novedosas experiencias interactivas

Una experiencia web es básicamente una llamada y una respuesta entre tú y tus usuarios, y por eso es tan importante invertir en interacciones de calidad entre los usuarios. Estamos trabajando en algunas mejoras realmente importantes que desbloquean capacidades que nunca antes habíamos tenido en la Web para navegar dentro de páginas web y entre ellas.

Animaciones basadas en desplazamientos

Navegadores compatibles

  • 115
  • 115
  • x

Origen

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 desplazamiento u otras secuencias de comandos pesadas.

Cómo crear animaciones basadas en desplazamientos

Así como 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 el progreso de esa animación, mientras que, cuando te desplaces hacia atrás, avanzará en sentido contrario. Esto te permite crear elementos visuales parciales o de página completa con elementos que se animan en el viewport y dentro de él, lo que también se conoce como scrollytelling, para generar un impacto visual dinámico.

Las animaciones basadas en desplazamientos 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.

Animación basada en desplazamientos

Demostración en vivo

@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 escala de una imagen. La posición de desplazamiento controla la animación. Para crear este efecto, primero configura la animación CSS y, luego, configura el animation-timeline. En este caso, la función view() con sus valores predeterminados realiza 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 del 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 basadas en desplazamientos y ajusta tu animación basada en desplazamientos en una consulta de preferencias del usuario, como @media (prefers-reduced-motion: no-preference), para respetar las preferencias de movimiento de los usuarios. Una vez realizadas estas comprobaciones, sabes 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 basadas en desplazamientos pueden significar experiencias de desplazamiento de página completa, pero también pueden significar animaciones más sutiles, como una barra de encabezado que minimiza y muestra una sombra a medida que te desplazas por una app web.

Animación basada en desplazamientos

Demostración en vivo

@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 respectiva animación basada en desplazamientos a cada una. Si bien cada uno tiene un estilo de animación diferente, todos tienen el mismo cronograma de animación, el desplazador más cercano y el mismo intervalo de animación (desde la parte superior de la página hasta 150 píxeles).

Beneficios de rendimiento de las animaciones basadas en desplazamientos

Esta API integrada reduce la carga de código que tendrías que mantener, ya sea que se trate de una secuencia de comandos personalizada que escribiste o la inclusión de una dependencia adicional de terceros. Además, elimina la necesidad de enviar varios observadores de desplazamiento, lo que genera algunos beneficios de rendimiento bastante significativos. Esto se debe a que las animaciones basadas en desplazamientos funcionan fuera del 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 hooks de JavaScript.

Recientemente, Tokopedia usó animaciones basadas en desplazamientos para que la barra de navegación del producto aparezca mientras te desplazabas. El uso de esta API ha tenido serios beneficios, tanto para la administración del código como para el rendimiento.

Las animaciones basadas en desplazamientos activan esta barra de navegación del producto en Tokopedia a medida que te desplazas hacia abajo.

"Logramos reducir hasta un 80% de 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 de 50% a 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 que la Web sea un lugar más atractivo y ya estamos pensando en lo que podría venir a continuación. Esto incluye la capacidad de usar no solo nuevos cronogramas de animación, sino también un punto de desplazamiento para activar el inicio de una animación, denominada animaciones activadas por desplazamiento.

Y, en el futuro, se agregarán más funciones de desplazamiento a los navegadores. En la siguiente demostración, se muestra una combinación de estas funciones futuras. Usa scroll-start-target de CSS para establecer la fecha y hora iniciales dentro de los selectores, y el evento scrollsnapchange de JavaScript para actualizar la fecha del encabezado, por lo que es trivial sincronizar los datos con el evento ajustado.

Mira la demostración en vivo en CodePen

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

Actualmente, estas funciones en particular solo se encuentran en Canary detrás de una bandera. Sin embargo, desbloquean capacidades que antes eran imposibles o muy difíciles de compilar en la plataforma y destacan el futuro de las posibilidades de interacciones basadas en desplazamientos.

Para obtener más información sobre cómo comenzar a usar las animaciones basadas en desplazamientos, nuestro equipo acaba de lanzar una nueva serie de videos que puedes encontrar en el canal de YouTube de Chrome for Developers. Aprenderás los conceptos básicos de las animaciones basadas en desplazamientos de Bramus Van Damme, incluido cómo funciona la función, el vocabulario, las diversas formas de crear efectos y cómo combinarlos para crear experiencias enriquecidas. Es una buena serie de videos para ver.

Ver transiciones

Acabamos de explicar una nueva y potente función para animar dentro de páginas web, pero también existe una nueva y potente función llamada transiciones de vistas para animar entre vistas de página y así crear una experiencia del usuario fluida. Las transiciones de vistas 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.

Navegadores compatibles

  • 111
  • 111
  • x
  • x

Origen

Airbnb es una de las empresas que ya están experimentando con la integración de transiciones de vistas en su IU para lograr una experiencia de navegación web fluida y fluida. Esto incluye la barra lateral del editor de fichas, que permite editar fotos y agregar comodidades, todo dentro de un flujo de usuarios fluido.

Una transición de vista del mismo documento que en Airbnb.
La cartera de Maxwell Barvian, que muestra las transiciones 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 tu vista de lista se actualiza ante la interacción del usuario. Este efecto se puede lograr sin esfuerzo con las transiciones de vistas.

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

Imagen de demostración

Demostración en vivo

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;
}

Ver clases de transición

Los nombres de transición de vistas se pueden usar para aplicar animaciones personalizadas a tu transición de vistas, aunque esto puede resultar complicado debido a la transición de muchos elementos. La primera actualización nueva para ver transiciones de este año simplifica este problema y presenta la capacidad de crear clases de transición de vistas que se pueden aplicar a animaciones personalizadas.

Navegadores compatibles

  • 125
  • 125
  • x
  • x

Ver tipos de transición

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

Por ejemplo, es posible que quieras que la página de inicio se anime a la página de un blog de una manera diferente a como la animación de esa página de blog vuelve a la página de inicio. O es posible que quieras que las páginas se intercambien de una manera diferente, como en este ejemplo, yendo de izquierda a derecha y viceversa. Antes todo era complicado. Se podían agregar clases al DOM para aplicar estilos y, luego, se debían quitar las clases. Los tipos de transición de vista permiten que el navegador borre las transiciones antiguas en lugar de requerir que lo hagas manualmente antes de iniciar las nuevas.

Grabación de la demostración de paginación. Los tipos determinan qué animación usar. Los estilos se separan en la hoja de estilo 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 lo extensa que es. Muchas aplicaciones no son solo una sola página, sino un tapiz sólido que contiene varias páginas. Por ese motivo, nos complace anunciar que lanzaremos la compatibilidad con las transiciones de vistas entre documentos para aplicaciones de varias páginas en Chromium 126.

Navegadores compatibles

  • 126
  • 126
  • x
  • x

Origen

Este nuevo conjunto de atributos de varios documentos incluye experiencias web que se encuentran dentro del mismo origen, como navegar de web.dev a web.dev/blog, pero esto no incluye la navegación de origen cruzado, como la navegación de web.dev a blog.web.dev o a otro dominio, como google.com.

Una de las diferencias clave con las transiciones de vistas del mismo documento es que no necesitas unir tu transición con document.startViewTransition(). En su lugar, habilita las dos páginas involucradas en la transición de vistas mediante la regla at @view-transition de CSS.

@view-transition {
  navigation: auto;
}

Para obtener un efecto más personalizado, puedes vincularte en JavaScript con los nuevos objetos de escucha de eventos pageswap o pagereveal, que te otorgan acceso al objeto de transición de vistas.

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

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

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

En el futuro, planeamos ampliar las transiciones de vistas, incluidas las siguientes:

  • 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 admita varias transiciones de vistas que se ejecuten al mismo tiempo.
  • Transiciones de vistas basadas en gestos: Usa gestos de arrastre o deslizamiento para activar una transición de vista entre documentos y ofrecer experiencias más similares a las nativas en la Web.
  • Coincidencia de navegación en CSS: Personaliza la transición de vistas de varios documentos directamente en CSS como alternativa al uso de los eventos pageswap y pagereveal en JavaScript. Para obtener más información sobre las transiciones de vistas para aplicaciones de varias páginas, incluido cómo configurarlas con el procesamiento previo de manera más eficaz, consulta la siguiente charla de Bramus Van Damme:

Componentes de IU habilitados para motores: cómo simplificar interacciones complejas

Compilar aplicaciones web complejas no es una tarea fácil, pero el CSS y el 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 IU, lo que te permite enfocarte en crear experiencias excelentes. Esto se lleva a cabo a través de una iniciativa colaborativa que involucra varios organismos de estandarización y grupos comunitarios, incluido el Grupo de trabajo de CSS, el Grupo de comunidad de IU abierto y el Grupo de trabajo de tecnología de aplicaciones de hipertexto web (WhatWG).

Un gran punto débil de los desarrolladores es una solicitud aparentemente simple: la capacidad de definir el estilo de menús desplegables (el elemento de selección). Aunque parezca sencillo en la superficie, es un problema complejo, que afecta muchas partes de la plataforma: desde el diseño y la renderización, hasta el desplazamiento y la interacción, el estilo del usuario-agente y las propiedades de CSS, e incluso los cambios en HTML.

Selecciona con una lista de datos de opciones que tienen opciones dentro, el botón de activación, la flecha indicadora y la opción seleccionada.
Cómo desglosar las partes de una selección

Un menú desplegable consta de muchas partes e incluye muchos estados que deben tenerse en cuenta, como los siguientes:

  • Vinculaciones del teclado (para ingresar/salir de la interacción)
  • Haz clic para descartar
  • Administración activa de ventanas emergentes (cierra otras ventanas emergentes cuando se abran una)
  • Administración del enfoque de pestañas
  • Visualiza el valor de la opción seleccionada
  • Estilo de interacción de la flecha
  • Administración del estado (abierta/cerrada)

Actualmente, es difícil administrar todo este estado tú mismo, pero la plataforma tampoco lo facilita. Para solucionar este problema, desglosamos esas partes y enviamos algunas funciones básicas que permitirán definir el estilo de los menús desplegables, pero que también permiten mucho más.

La API de Popover

Primero, enviamos un atributo global llamado popover, que me complace anunciar que acaba de alcanzar el estado de nueva disponibilidad del modelo de referencia hace unas semanas.

Navegadores compatibles

  • 114
  • 114
  • 125
  • 17

Origen

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

Imagen de demostración

Demostración en vivo

<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 de ventana emergente ahora habilitado, el navegador controla muchos comportamientos clave sin ninguna secuencia de comandos adicional, como los siguientes:

  • Asciende a la capa superior.: Una capa separada sobre el resto de la página, para que no tengas que jugar con z-index
  • Función de descarte ligero: Si haces clic fuera del área de la ventana emergente, esta se cerrará y volverá al enfoque.
  • Administración predeterminada del enfoque de la pestaña: Al abrir la ventana emergente, la pestaña siguiente se detiene dentro de ella.
  • Vinculaciones de teclado integradas: Si presionas la tecla esc o actívalas dos veces, se cerrará la ventana emergente y se volverá a enfocar.
  • Vinculaciones de componentes predeterminados. : El navegador conecta semánticamente una ventana emergente a su activador.
Pantalla principal de GitHub
Menú de la página principal de GitHub.

Incluso es posible que actualmente uses esta API de ventana emergente sin darte cuenta. GitHub implementó la ventana emergente en el menú “nuevo” de su página principal y en la descripción general de la revisión de la solicitud de extracción. Mejoraron de forma progresiva esta función con el polyfill emergente, compilado por Oddbird, con compatibilidad significativa por Keith Cirkel de GitHub, para admitir navegadores anteriores.

“Logramos que miles de líneas de código dejen de estar disponibles literalmente gracias a la migración a las ventanas emergentes. Popover nos ayuda al eliminar la necesidad de luchar contra números mágicos del índice z... tener la relación correcta del árbol de accesibilidad establecida con el comportamiento del botón declarativo y los comportamientos de enfoque integrados facilita significativamente a nuestro sistema de diseño implementar patrones de la manera correcta. Keith Cirkel, ingeniero de Software, GitHub”.

Cómo animar efectos de entrada y salida

Cuando tengas ventanas emergentes, te recomendamos que agregues algo de interacción. El año pasado, lanzamos cuatro funciones de interacción nuevas para admitir la animación de ventanas emergentes. Examinémoslos.

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

Navegadores compatibles

  • 117
  • 117
  • 17.4

Origen

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

Navegadores compatibles

  • 117
  • 117
  • x
  • 17,5

Origen

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

Navegadores compatibles

  • 117
  • 117
  • x
  • x

Origen

Estas propiedades funcionan para cualquier elemento que se anime en la capa superior, ya sea una ventana emergente o un diálogo. En conjunto, se ve así para un diálogo con un fondo:

Imagen de demostración

Demostración en vivo

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 el @starting-style de modo que el navegador sepa desde qué estilos animar este elemento en el DOM. Esto se hace para el diálogo y el fondo. Luego, define el estilo del estado abierto tanto para el diálogo como para el fondo. En el caso de un diálogo, se usa el atributo open, y para 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 pueden realizar la transición de propiedades discretas.

Posicionamiento del ancla

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

Navegadores compatibles

  • 125
  • 125
  • x
  • x

Origen

Mediante el posicionamiento de los anclajes y con solo unas pocas líneas de código, el navegador puede controlar la lógica para conectar un elemento posicionado a uno o más elementos de anclaje. En el siguiente ejemplo, se ancla un simple cuadro de información a cada botón, que se ubica en la parte inferior central.

Imagen de demostración

Demostración en vivo

Configura una relación de posición de anclaje 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 información sobre la herramienta). Luego, aplica un posicionamiento absoluto o fijo sobre el ancla con la función anchor(). El siguiente código posiciona la parte superior de la información sobre la herramienta hasta la parte inferior del botón.

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

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

Como alternativa, puedes usar el nombre del ancla directamente en la función de anclaje y omitir 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 anclajes con ventanas emergentes, el desplazamiento emergente no es un requisito para usar el posicionamiento de anclajes. El posicionamiento de anclaje se puede usar con dos (o más) elementos cualesquiera 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 que se ancla a los elementos de una lista cuando colocas el cursor sobre ellos o colocas la tecla Tab sobre ellos.

Imagen de demostración

Demostración en vivo

En este ejemplo, se usa la función de anclaje para configurar la posición del ancla 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 cambia el objetivo para aplicar la posición, además de animar 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 de inset-area

Además del posicionamiento direccional absoluto predeterminado que probablemente ya hayas usado antes, se incluye un nuevo mecanismo de diseño que aterrizó como parte de la API de posicionamiento de anclajes llamada área de inserción. El área de inserción facilita la colocación de elementos posicionados en relación con sus respectivas anclas 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 coloca el elemento posicionado en la parte inferior.

Una versión simplificada de la primera demostración fija se ve de la siguiente manera con inset-area:

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

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

Puedes combinar estos valores posicionales con palabras clave de intervalo para comenzar en la posición central y abarcar la izquierda, la derecha, o bien todos los intervalos para ocupar el conjunto completo de columnas o filas disponibles. También puedes usar propiedades lógicas. Para facilitar la visualización y la utilización de este mecanismo de diseño, prueba 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. Entonces, en este caso, tenemos elementos de tarjetas con estilo de consulta de contenedor, que cambian de tamaño según su tamaño intrínseco (algo que no se podía hacer con las consultas de medios), y el menú fijo cambia con el nuevo diseño a medida que cambia la IU de la tarjeta.

Imagen de demostración

Demostración en vivo

Posiciones de los anuncios fijos dinámicos 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 ventanas emergentes y de anclas. Además, cuando tocas el borde de un viewport con tu elemento anclado, puedes dejar que el navegador controle el cambio de posicionamiento también por ti. Puedes hacerlo de varias maneras. La primera es crear tus propias reglas de posicionamiento. En este caso, el submenú inicialmente se posicionará a la derecha del botón de “vidriera”. Sin embargo, puedes crear un bloque @position-try para cuando no haya suficiente espacio a la derecha del menú, lo que le da un identificador personalizado de --bottom. Luego, conecta este bloque @position-try al ancla con position-try-options.

Ahora, el navegador cambiará entre estos estados fijos, probará primero la posición correcta y, luego, cambiará a la parte inferior. Esto se puede lograr con una buena transición.

Imagen de demostración

Demostración en vivo

#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ícita, existen algunas palabras clave que proporciona el navegador si deseas algunas interacciones básicas, como voltear el anclaje en el bloque o insertar direcciones en línea.

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

Para una experiencia de cambio simple, aprovecha estos valores de palabras clave de rotación y omite escribir una definición de position-try por completo. Así que ahora puedes tener un elemento posicionado de anclajes que sea totalmente funcional y con capacidad de respuesta en la ubicación con solo unas pocas líneas de CSS.

Imagen de demostración

Demostración en vivo

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

Obtenga más información sobre cómo utilizar el posicionamiento de los anclajes.

El futuro de la IU en capas

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

Como siguiente paso para la API de ventana emergente, estamos trabajando en interesttarget para resolver estas necesidades y facilitar la recreación de estas experiencias con los hooks de accesibilidad adecuados integrados. Este es un problema de accesibilidad difícil de resolver, con muchas preguntas abiertas sobre 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 futuro (invoketarget) disponible para probar en Canary gracias al trabajo de dos desarrolladores externos, Keith Cirkel y Luke Warlow. invoketarget admite la experiencia declarativa para desarrolladores que proporciona popovertarget de ventanas emergentes, normalizadas para todos los elementos interactivos, como <dialog>, <details>, <video> y <input type="file">, entre otros.

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

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

Sabemos que hay casos de uso que aún no están cubiertos por esta API. Por ejemplo, aplicar diseño a la flecha que conecta un elemento anclado a su ancla, en especial cuando cambia la posición del elemento anclado, y permitir que un elemento se "desliza" y permanezca en el viewport en lugar de ajustarse a otra posición establecida cuando alcanza su cuadro delimitador. Si bien nos entusiasma lanzar esta API potente, también esperamos ampliar sus capacidades aún más en el futuro.

Selección con estilo estilístico

Con popover y anchor en conjunto, el equipo ha estado avanzando para habilitar finalmente un menú desplegable de selección personalizable. La buena noticia es que hubo muchos avances. La mala noticia es que esta API todavía se encuentra en un estado experimental. Sin embargo, me emociona compartir algunas demostraciones en vivo y actualizaciones sobre nuestro progreso, y esperamos recibir algunos de tus comentarios. En primer lugar, hubo avances respecto a cómo habilitar a los usuarios para que usen la nueva experiencia de selección personalizable. La forma actual en proceso de hacerlo es usar una propiedad de apariencia en CSS, configurada como appearance: base-select. Una vez que configures la apariencia, accederás a una nueva experiencia de selección personalizable.

select {
  appearance: base-select;
}

Además de appearance: base-select, hay algunas actualizaciones HTML nuevas. Estas incluyen la capacidad de unir tus opciones en un datalist para la personalización y la capacidad de agregar contenido arbitrario no interactivo, 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 luego puedes personalizar según tus necesidades. Este elemento es muy útil.

Imagen de demostración

marcar demostración

Demostración en vivo

<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 la personalización de <selectedoption> en la IU de Gmail, donde un ícono visual representa el tipo de respuesta seleccionada para ahorrar espacio. Puedes usar estilos de visualización básicos en selectedoption para diferenciar el estilo de la opción del estilo de la vista previa. En este caso, el texto que se muestra en la opción se puede ocultar visualmente en selectedoption.

Imagen de demostración

demostración de Gmail

Demostración en vivo

selectedoption .text {
  display: none;
}

Una de las mayores ventajas de reutilizar el elemento <select> para esta API es la retrocompatibilidad. Allí podrás ver una IU personalizada con imágenes de banderas en las opciones para que los usuarios analicen el contenido con más facilidad. Debido a que los navegadores no compatibles ignorarán las líneas que no entiendan, como el botón personalizado, la lista de datos, la opción seleccionada y las imágenes dentro de las opciones, el resguardo será similar a la IU de selección predeterminada actual.

El navegador no compatible obtiene la experiencia de selección actual.
Imagen de navegador compatible a la izquierda en comparación con un resguardo de navegador no compatible del lado derecho.

Con selecciones personalizables, las posibilidades son infinitas. En particular, me encanta este selector de país al estilo Airbnb porque tiene un estilo inteligente para el diseño adaptable. Puedes hacer esto y mucho más con la próxima selección estilable, lo que la convierte en una adición muy necesaria a la plataforma web.

Imagen de demostración

Demostración en vivo

Acordeón exclusivo

Resolver determinados estilos (y todas las partes que vienen con él) no es el único componente de la IU en el que se ha enfocado el equipo de Chrome. La primera actualización de componente adicional es la capacidad de crear acordeones exclusivos, en los que solo se puede abrir uno de los elementos del acordeón a la vez.

Navegadores compatibles

  • 120
  • 120
  • x
  • 17.2

La forma de habilitar esta opción es aplicar el mismo valor de nombre para varios elementos de detalles, por lo que se crea un grupo conectado de detalles, como un grupo de botones de selección.

Demostración de acordeón exclusiva
<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 de los componentes de la IU son las seudoclases :user-valid y :user-invalid. Estable 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 haya interactuado de forma significativa con la entrada. Esto significa que se necesita mucho menos código para determinar si se interactuó con el valor de un formulario o si se descartó, lo que puede ser muy útil para brindar comentarios al usuario y reduce la cantidad de secuencias de comandos necesarias para hacerlo en el pasado.

Navegadores compatibles

  • 119
  • 119
  • 88
  • 16.5

Origen

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 pseudoelementos de validación de formulario user-*.

field-sizing: content

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

Navegadores compatibles

  • 123
  • 123
  • x
  • x

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 <hr> (o el elemento de regla horizontal en las selecciones) es otra función componente pequeña pero útil. Si bien esto 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 quieras agrupar con un grupo de opciones, como un valor de marcador de posición.

Seleccionar captura de pantalla

captura de pantalla de hr en Select con un tema claro y oscuro en Chrome

Seleccionar 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>

Más información para usar h en select

Mejoras en la calidad de vida

Estamos iterando de forma constante, y esto no es solo para las interacciones y los componentes. Hay muchas otras actualizaciones sobre la calidad de vida que llegaron el año pasado.

Período de prueba con elementos anticipados

El anidamiento de CSS nativo llegó a todos los navegadores el año pasado y, desde entonces, ha mejorado para admitir la visualización anticipada, lo que significa que el elemento & antes de los nombres de los elementos ya no es un requisito. Esto hace que el anidamiento se sienta mucho más ergonómico y similar a lo que solían hacer en el pasado.

Navegadores compatibles

  • 120
  • 120
  • 117
  • 17.2

Origen

Uno de los aspectos que más me gusta de la anidación de CSS es que permite bloquear visualmente los componentes, y dentro de ellos se incluyen estados y modificadores, como consultas de contenedores y de medios. Antes, tenía el hábito de agrupar todas estas consultas en la parte inferior del archivo por motivos de 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 bueno es la capacidad de usar mecanismos de centrado como align-content en el diseño de bloques. Esto significa que ahora puedes realizar acciones como el enfoque vertical dentro de un elemento div sin necesidad de aplicar un diseño flexible o de cuadrícula, y sin efectos secundarios, como evitar la contracción de márgenes, que tal vez no desees de esos algoritmos de diseño.

Navegadores compatibles

  • 123
  • 123
  • 125
  • 17.4

Captura de pantalla

Demostración en directo

div {
  align-content: center;
}

Ajuste de texto: Equilibrio y belleza

Hablando de diseño, se mejoró bastante el diseño de texto 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 singletons en la última línea.

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. Intenta traducir la demostración a otro idioma.
h1 {
  text-wrap: balance;
}

Obtén más información sobre ajuste de texto: equilibrio.

Actualizaciones de tipografía internacional

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

Navegadores compatibles

  • 119
  • 119
  • x
  • x

salto de palabra: la frase automática une la línea dentro del límite de la frase natural.
Comparación entre word-break: normal y word-break: auto-phrase

Y text-spacing-trim, que aplica el interletraje entre los caracteres de puntuación para mejorar la legibilidad de la tipografía china, japonesa y coreana para lograr resultados más agradables visualmente.

Navegadores compatibles

  • 123
  • 123
  • x
  • x

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 punto CJK.

Sintaxis de colores relativos

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

En este ejemplo, aquí los colores usan temas basados en Oklch. A medida que el valor de matiz se ajusta en función del control deslizante, cambia todo el tema. Esto se puede lograr con la sintaxis relativa de colores. El fondo usa el color principal, según el matiz, y ajusta los canales de luminosidad, croma y matiz para ajustar su valor. --i es el índice del mismo nivel en la lista para la gradación de valores, que muestra cómo se pueden combinar los pasos con propiedades personalizadas y la sintaxis relativa de colores 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. Intenta 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(), los temas se volvieron mucho más dinámicos y simplificados.

Navegadores compatibles

  • 123
  • 123
  • 120
  • 17,5

Origen

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 muestra muy bien en este diagrama visual de Adam Argyle. Antes, necesitabas dos bloques de código diferentes (tu tema predeterminado y una consulta de preferencias del usuario) para configurar las opciones de temas. 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 celeste. Si el usuario seleccionó un tema oscuro, el botón tendrá un fondo azul oscuro.

Selector de :has()

Sería negativo hablar de la IU moderna sin mencionar uno de los aspectos destacados de interoperabilidad de mayor impacto del año pasado, que debe ser el selector :has(), que llegará en todos los navegadores en diciembre del año pasado. Esta API cambia las reglas del juego para escribir estilos lógicos.

Navegadores compatibles

  • 105
  • 105
  • 121
  • 15.4

Origen

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 pueden funcionar como selectores superiores.

Demostración de que has() 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 aplicar diseño a los bloques según su contenido interior, como en la sección de comparación, en la que el estilo 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 de CSS que funciona a la perfección con la misma experiencia que antes. Aman Soni, líder de Tecnología, PolicyBazaar".

Consultas de contenedores

Otra adición clave a la Web que está recientemente disponible y en uso son las consultas de contenedor, que permiten consultar el tamaño intrínseco de un elemento superior para aplicar estilos: un peine mucho más detallado que las consultas de medios, que solo consultan el tamaño del viewport.

Navegadores compatibles

  • 105
  • 105
  • 110
  • 16

Origen

Recientemente, Angular lanzó un hermoso sitio de documentación nuevo en angular.dev usando consultas de contenedores para definir el estilo de los bloques de encabezados según su 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 automáticamente.

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

Sin las consultas de contenedores, hacer algo como esto era bastante difícil y perjudicial para el rendimiento, ya que se requería observadores de cambio de tamaño y observadores de elementos. Ahora, es fácil aplicar diseño a un elemento según el tamaño de elemento superior.

Presentación en pantalla de demostración

Demostración en directo

Vuelve a crear la consulta del contenedor de la tarjeta de encabezado de Angular.

@property

Por último, muy pronto, nos emociona ver el terreno de @property en 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 permite una gran cantidad de funciones de interacción nuevas. @property también habilita el significado contextual, la verificación de tipo, la configuración predeterminada y los valores de resguardo en CSS. Así, se abren las puertas a funciones aún más sólidas, como consultas de estilo de rangos. Esta es una función que nunca antes era posible y que ahora proporciona tanta profundidad al lenguaje de CSS.

Navegadores compatibles

  • 85
  • 85
  • 16.4

Origen

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 potentes funciones de IU que llegan a todos los navegadores, las posibilidades son infinitas. Las nuevas experiencias interactivas con animaciones basadas en desplazamientos y transiciones de vistas hacen que la Web sea más interactiva y fluida de formas nunca antes vistas. Además, los componentes de IU de primer nivel hacen que sea más fácil que nunca compilar componentes sólidos y personalizados con gran belleza sin afectar la experiencia nativa por completo. Y, 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 pequeñas cosas importantes, sino que también brindan a los desarrolladores las herramientas que necesitan para compilar interfaces complejas que funcionan en una variedad de dispositivos, factores de forma y necesidades de los usuarios.

Debes poder quitar las secuencias de comandos de terceros para funciones de alto rendimiento, como el desplazamiento y la conexión entre elementos entre sí con el posicionamiento de anclaje, la compilación de transiciones fluidas de la página, el estilo de menús desplegables y para mejorar la estructura general de tu código de forma nativa.

Este es el mejor momento para ser desarrollador web. No ha habido mucha energía y entusiasmo desde el anuncio de CSS3. Las funciones que necesitábamos, pero que solo soñamos con tener en el pasado, finalmente se están convirtiendo en una realidad y parte de la plataforma. Gracias a sus opiniones, podemos priorizar y, finalmente, hacer realidad estas capacidades. Estamos trabajando para que sea más fácil hacer las tareas tediosas y tediosas de forma nativa, para que puedas dedicar más tiempo a crear lo que importa, como las funciones principales y los detalles de diseño que diferencien tu marca del resto.

Para obtener más información sobre estas nuevas funciones, consulta developer.chrome.com y web.dev, donde nuestro equipo comparte las novedades más recientes sobre tecnologías web. Prueba las animaciones basadas en desplazamientos, las transiciones de vistas, el posicionamiento de las anclas o incluso la selección estilizada, y danos tu opinión. Estamos aquí para escucharlos y para ayudarte.