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, analizaremos en detalle el estado actual del CSS y exploraremos algunas de las funciones nuevas más innovadoras que están redefiniendo la forma en que compilamos aplicaciones web, que se presentaron en vivo en Google I/O 2024.
Experiencias interactivas novedosas
Una experiencia web es, en esencia, una llamada y una respuesta entre tú y tus usuarios. Por eso es tan importante invertir en interacciones de calidad con 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 el desplazamiento
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 ni de otras secuencias de comandos pesadas.
Crea 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 del desplazamiento de un control deslizante 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 imágenes parciales o de página completa con elementos animados dentro del viewport, también conocido como narración de desplazamiento, para lograr un impacto visual dinámico.
Las animaciones impulsadas por el 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.
Visualización de animación basada en el 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 controla según la posición de desplazamiento. Para crear este efecto, primero configura la animación CSS y, luego, configura animation-timeline
. En este caso, la función view()
con sus valores predeterminados hace un seguimiento de la imagen en relación con el 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. Después de realizar estas verificaciones, sabes que tus estilos funcionarán y que la animación no es problemática para el usuario.
@supports (animation-timeline: view()) {
@media (prefers-reduced-motion: no-preference) {
/* Apply scroll-driven animations here */
}
}
Las animaciones impulsadas por el desplazamiento pueden significar experiencias de narración de desplazamiento 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 mientras te desplazas por una app web.
Visualización de animación basada en el 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 respectiva animación de desplazamiento 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 control deslizante 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 la secuencia de comandos personalizada que escribiste o la inclusión de una dependencia de terceros adicional. También quita la necesidad de enviar varios observadores de desplazamiento, lo que significa algunos beneficios de rendimiento bastante significativos. Esto se debe a que las animaciones impulsadas por el 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 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 tuvo algunos beneficios importantes, tanto para la administración de código como para el rendimiento.
“Logramos reducir hasta el 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 del 50% al 2% durante el desplazamiento. - Andy Wihalim, ingeniero sénior de software, 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 suceder a continuación. Esto incluye la capacidad de no solo usar nuevos cronogramas de animación, sino también usar un punto de desplazamiento para activar el inicio de una animación, llamadas animaciones activadas por desplazamiento.
Además, en el futuro, se agregarán aún más funciones de desplazamiento a los navegadores. En la siguiente demostración, se muestra una combinación de estas funciones futuras. Usa CSS scroll-start-target
para establecer la fecha y la hora iniciales dentro de 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.
También puedes basarte en 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.
Si quieres obtener más información para comenzar a usar animaciones impulsadas por el desplazamiento, nuestro equipo acaba de lanzar una nueva serie de videos que puedes encontrar en el canal de YouTube de Chrome para desarrolladores. 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 gran serie de videos para mirar.
Cómo ver transiciones
Acabamos de analizar una nueva función potente que permite animar dentro de las páginas web, pero también existe una nueva función potente llamada transiciones de vista para animar entre vistas de página y crear una experiencia del usuario fluida. 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.
Airbnb es una de las empresas que ya experimenta con la integración de transiciones de vista en su IU para lograr una experiencia de navegación web fluida y sin inconvenientes. Esto incluye la barra lateral del editor de fichas, que permite editar fotos y agregar comodidades, todo dentro de un flujo de usuarios fluido.
Si bien estos efectos de página completa son hermosos y fluidos, también puedes crear microinteracciones, como en este ejemplo, en el que la vista de lista se actualiza cuando el usuario interactúa con ella. Este efecto se puede lograr sin esfuerzo con transiciones de vistas.
La forma de habilitar rápidamente las transiciones de vista en tu aplicación de una sola página es tan simple como unir una interacción con document.startViewTransition
y asegurarte de que cada elemento que esté en transición tenga un view-transition-name
intercalado o con JavaScript de forma dinámica 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 vista se pueden usar para aplicar animaciones personalizadas a la transición de vista, aunque esto puede ser engorroso con muchos elementos en transición. 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
Cómo ver los tipos de transición
Otra gran mejora para las transiciones de vistas es la compatibilidad con los tipos de transiciones de vistas. Los tipos de transición de vista son útiles cuando deseas un tipo diferente de transición visual de vista cuando animas desde y hacia las vistas de página.
Navegadores compatibles
Por ejemplo, es posible que desees que una página principal se anime a una página de blog de una manera diferente a la que esa página de blog se anima a la página principal. También puedes querer que las páginas se intercambien de diferentes maneras, como en este ejemplo, de izquierda a derecha y viceversa. Antes, esto era un proceso desordenado. Podías agregar clases al DOM para aplicar estilos y, luego, quitarlas. View-transition-types permite que el navegador borre las transiciones anteriores en lugar de que debas hacerlo de forma manual antes de iniciar otras nuevas, lo que hace el trabajo por ti.
Puedes configurar tipos dentro de la 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 amplitud. Muchas aplicaciones no son solo de una sola 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.
Navegadores compatibles
Este nuevo conjunto de funciones entre documentos incluye experiencias web que se encuentran dentro del 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 diferencias clave con las transiciones de vista del mismo documento es que no necesitas unir la 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 realizar algunos cambios de último minuto 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) => {
// ...
});
En el futuro, planeamos expandir las transiciones de vista, incluidas las siguientes:
- Transiciones centradas: Te permiten limitar una transición a un subárbol de DOM, lo que permite que el resto de la página siga siendo interactiva y admita varias transiciones de vista que se ejecutan 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 vista entre documentos directamente en tu CSS como alternativa al uso de eventos
pageswap
ypagereveal
en JavaScript. Para obtener más información sobre las transiciones de vista para aplicaciones de varias páginas, incluida la forma de configurarlas con el mejor rendimiento con la renderización previa, consulta la siguiente charla de Bramus Van Damme:
Componentes de la IU habilitados por el motor: Simplifica las interacciones complejas
Crear aplicaciones web complejas no es tarea fácil, pero CSS y HTML evolucionan para que este proceso sea mucho más fácil de administrar. 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 hace 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 comunitario de la IU abierta y WHATWG (Grupo de trabajo de tecnología de aplicaciones de hipertexto web).
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). Si bien parece sencillo en la superficie, 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, el diseño del usuario-agente y las propiedades CSS, y hasta los cambios en el código HTML.
Un menú desplegable consta de muchas partes y tiene muchos 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 para descartar
- Administración de ventanas emergentes activas (cierra otras ventanas emergentes cuando se abre una)
- Administración del enfoque de pestañas
- Visualización del valor de la opción seleccionada
- Estilo de interacción con flechas
- 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, dividimos esas piezas y enviamos algunas funciones primitivas que permitirán aplicar diseño a los menús desplegables, pero también harán 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.
Los elementos del cuadro emergente se ocultan con display: none
hasta que se abren con un llamador, como un botón o con JavaScript. Para crear un popover 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>
Ahora que el atributo popover está habilitado, el navegador controla muchos comportamientos clave sin ninguna secuencia de comandos adicional, incluidos los siguientes:
- Promoción a la capa superior: Una capa independiente sobre el resto de la página para que no tengas que jugar con
z-index
. - Funcionalidad de descarte de luz: Si haces clic fuera del área del cuadro emergente, este se cerrará y se restablecerá el enfoque.
- Administración predeterminada del enfoque de pestañas: Si abres el cuadro emergente, el siguiente punto de parada de pestaña se ubicará dentro de él.
- 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 predeterminadas. : El navegador conecta semánticamente un popover a su activador.
Es posible que incluso estés usando esta API de popover hoy sin darte cuenta. GitHub implementó el popover en el menú “Nuevo” de la página principal y en la descripción general de la revisión de solicitudes de extracción. Mejoraron esta función de forma progresiva con el polyfill de popover, creado por Oddbird con la asistencia significativa de Keith Cirkel de GitHub, para admitir navegadores más antiguos.
“Logramos dar de baja literalmente miles de líneas de código migrando a popover. Los pop-overs nos ayudan a eliminar la necesidad de luchar contra números de índice z mágicos… Tener la relación correcta del árbol de accesibilidad establecida con el comportamiento declarativo de los botones y los comportamientos de enfoque integrados facilita mucho que nuestro sistema de diseño implemente patrones de la manera correcta. -Keith Cirkel, ingeniero de software, GitHub”
Animación de efectos de entrada y salida
Cuando tengas ventanas emergentes, es probable que quieras agregar alguna interacción. El año pasado, se lanzaron cuatro nuevas funciones de interacción para admitir la animación de popovers. 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 transiciones de propiedades discretas, como display
.
La regla @starting-style
para animar los efectos de entrada desde display: none
y hacia la capa superior.
Es la propiedad de superposición para controlar el comportamiento de la capa superior durante una animación.
Estas propiedades funcionan para cualquier elemento que animes en la capa superior, ya sea un pop-up 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 de qué estilos animar este elemento en el DOM. Esto se hace para el diálogo y el fondo. Luego, aplica diseño al estado abierto para el diálogo y el fondo. Para un diálogo, se usa el atributo open
y, para un popover, el pseudoelemento ::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 se puede realizar la transición de propiedades discretas.
Posicionamiento de la ancla
El pop-up fue solo el comienzo de la historia. Una actualización muy interesante es que la compatibilidad con el posicionamiento de ancla ahora está disponible a partir de Chrome 125.
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.
Demostración visual
Demostración en directo
Para configurar una relación de posicionamiento de anclaje en CSS, usa 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 herramientas). Luego, aplica el posicionamiento absoluto o fijo en relación con el ancla con 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 ancla directamente en la función de ancla 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 ancla con el popover, este no es un requisito para usar el posicionamiento de ancla. El posicionamiento de ancla se puede usar con dos (o más) elementos para crear una relación visual. De hecho, en la siguiente demostración, inspirada en un artículo de Roman Komarov, se muestra un estilo de subrayado que se ancla a los elementos de la lista a medida que colocas el cursor sobre ellos o los seleccionas con la tecla Tab.
Imagen de demostración
Demostración en directo
En este ejemplo, se usa la función de ancla para configurar la posición de la ancla con las propiedades físicas de left
, right
y bottom
. Cuando colocas el cursor sobre uno de los vínculos, cambia el ancla de destino y el navegador cambia el destino para aplicar el posicionamiento y, al mismo tiempo, anima el color para crear un efecto atractivo.
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 absoluto direccional predeterminado que probablemente hayas usado antes, se incluye un nuevo mecanismo de diseño que se incorporó como parte de la API de posicionamiento de anclas llamado á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.
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 extensión para comenzar en la posición central y extenderse hacia la izquierda, hacia la derecha o abarcar todo para ocupar el conjunto completo de columnas o filas disponibles. También puedes usar propiedades lógicas. Para facilitar la visualización y la detección de 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 anclaje. Por lo tanto, en este caso, tenemos elementos de tarjeta con diseño de consulta de contenedor, que cambian de tamaño según su tamaño intrínseco (algo que no puedes hacer con las consultas de medios), y el menú anclado cambiará 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 de submenús son mucho más fáciles de crear con una combinación de posicionamiento de ventanas emergentes y anclas. Además, cuando llegas al borde de un viewport con tu elemento anclado, puedes permitir que el navegador controle el cambio de posición por ti.
Puedes hacerlo de varias maneras. La primera es crear tus propias reglas de posicionamiento. En este caso, el submenú se coloca inicialmente a la derecha del botón “tienda”. Sin embargo, puedes crear un bloque @position-try
para cuando no haya espacio suficiente 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 de anclaje, primero intentará la posición correcta y, luego, cambiará a la parte inferior. Y esto se puede hacer con una buena transición.
Elemento visual de demostración
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ícita, el navegador proporciona algunas palabras clave si deseas realizar interacciones básicas, como voltear el ancla en las direcciones del bloque o intercaladas.
position-try-options: flip-block, flip-inline;
Para obtener una experiencia de cambio simple, aprovecha estos valores de palabras clave de cambio y omite escribir una definición de position-try
por completo. Ahora puedes tener un elemento de posición de anclaje responsivo a la ubicación 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 ancla.
El futuro de la IU en capas
Vemos experiencias conectadas 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 de 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 al estilo de Wikipedia, un patrón que se ve en toda la plataforma web, debe ser posible interactuar con ellas y también activar un cuadro flotante desde un vínculo y desde el usuario que muestra interés sin tener que hacer clic, como un enfoque de desplazamiento o pestaña.
Como siguiente paso para la API de popover, 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 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 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 expandir aún más sus capacidades en el futuro.
Selección con diseño
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 se ha avanzado mucho. La mala noticia es que esta API aún se encuentra en estado experimental. Sin embargo, me complace compartir algunas demostraciones en vivo y actualizaciones sobre nuestro progreso, y espero recibir algunos de tus comentarios.
En primer lugar, se avanzó en la incorporación de los usuarios a la nueva experiencia de selección personalizable. La forma actual de hacerlo es usar una propiedad de apariencia en CSS, configurada en appearance: base-select
. Una vez que se configure la apariencia, aceptarás una nueva experiencia de selección personalizable.
select {
appearance: base-select;
}
Además de appearance: base-select
, hay algunas actualizaciones nuevas de HTML. 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 elemento nuevo, <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.
Elemento visual de demostración
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, 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
.
Demostración visual
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íses, puedes ver una IU personalizada con imágenes de banderas en las opciones para que el usuario analice el contenido con mayor facilidad. Debido a que los navegadores no compatibles ignorarán las líneas que no comprendan, como el botón personalizado, el datalist, la selectedoption y las imágenes dentro de las opciones, el resguardo será similar a la IU de selección predeterminada actual.
Con las selecciones personalizables, las posibilidades son infinitas. Me encanta este selector de países de estilo 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 adición muy necesaria a la plataforma web.
Elemento visual de demostración
Demostración en directo
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 componentes adicionales es la capacidad de crear acordeones exclusivos, en los que solo se puede abrir uno de los elementos a la vez.
Navegadores compatibles
Para habilitar esta función, debes aplicar el mismo valor de nombre a varios elementos de detalles, de modo que se cree un grupo conectado de detalles, similar a un grupo de botones de selecció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 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 un valor de formulario o si se volvió "no válido", lo que puede ser muy útil para proporcionar comentarios de los usuarios y reduce mucho la escritura de secuencias de comandos que sería necesaria para hacer esto en el pasado.
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 pseudelementos de validación de formularios user-*.
field-sizing: content
Otra actualización de componente ú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 disminuya) según su contenido. field-sizing: content
puede ser particularmente útil para los textareas, ya que ya no se resuelven a tamaños fijos en los que es posible que debas desplazarte hacia arriba para ver lo que escribiste en las partes anteriores de la instrucción en un cuadro de entrada demasiado pequeño.
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
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 de calidad de vida
Estamos iterando constantemente, y no se trata solo de interacciones y 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 nativo de CSS llegó a todos los navegadores el año pasado y, desde entonces, se mejoró para admitir la búsqueda anticipada, lo que significa que el &
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.
Uno de los aspectos que más me gusta de la anidación de CSS es que permite bloquear componentes visualmente, y dentro de ellos se incluyen estados y modificadores, como consultas de contenedores y de medios. Antes, tenía la costumbre de agrupar todas estas consultas en la parte inferior del archivo con fines de especificidad. Ahora, puedes escribirlos de una manera que tenga sentido, junto al resto del código.
.card {
/* card base styles */
h2 {
/* child element style */
}
&.highlight {
/* modifier style */
}
&:hover, &:focus {
/* state styles */
}
@container (width >= 300px) {
/* container query styles */
}
}
Align-content para el diseño de bloque
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 centrar verticalmente dentro de un div sin necesidad de aplicar un diseño flexible o de cuadrícula, y sin efectos secundarios, como evitar el colapso de márgenes, que tal vez no quieras de esos algoritmos de diseño.
Navegadores compatibles
Captura de pantalla
Demostración en directo
div {
align-content: center;
}
Text-wrap: equilibrio y belleza
A propósito del diseño, el diseño de texto tuvo una buena mejora 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.
Demo Screencast
Demostración en directo
h1 {
text-wrap: balance;
}
Obtén más información sobre text-wrap: balance.
Actualizaciones de tipografía internacional
Las actualizaciones de diseño tipográfico para componentes 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
Y text-spacing-trim
, que aplica el espacio entre caracteres de puntuación para mejorar la legibilidad de la tipografía china, japonesa y coreana y obtener resultados más atractivos a la vista.
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, 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 matiz, y ajusta los canales de luminosidad, croma y matiz para ajustar su valor. --i es el índice hermano en la lista para la gradación de valores, que muestra cómo puedes combinar el paso con propiedades personalizadas y sintaxis de color relativa para crear temas.
Demo Screencast
Demostración en directo
: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.
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 de forma muy 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()
.
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 un error 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 cambia las reglas del juego para escribir estilos lógicos.
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.
:has()
ya demostró ser particularmente útil para muchas empresas, como PolicyBazaar, que usan :has()
para aplicar diseño a bloques según su contenido interior, como en la sección de comparación, donde 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 con 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 incorporación clave a la Web que ahora está disponible y está aumentando su uso son las consultas de contenedor, que permiten consultar el tamaño intrínseco del elemento superior para aplicar estilos: un peine mucho más detallado que las consultas de medios, que solo consultan el tamaño del viewport.
Recientemente, Angular lanzó un nuevo y hermoso sitio de documentación en angular.dev que usa consultas de contenedor para aplicar 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 autoajustarse.
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 trivial aplicar diseño a un elemento según su tamaño superior.
Demo Screencast
Demostración en directo
@property
Por último, muy pronto, nos complacerá ver @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 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 de resguardo en CSS. Esto abre las puertas a funciones aún más sólidas, como las consultas de estilo de rango. Esta es una función que nunca antes fue posible y ahora le brinda mucha profundidad al lenguaje de CSS.
Demo Screencast
Demostración en directo
@property --card-bg {
syntax: "<color>";
inherits: false;
initial-value: #c0bae8;
}
Conclusión
Con todas estas nuevas y potentes funciones de la IU que se implementan en todos los navegadores, las posibilidades son infinitas. Las experiencias interactivas novedosas con animaciones impulsadas por el desplazamiento y transiciones de vista hacen que la Web sea más fluida e interactiva de formas que nunca antes habíamos visto. Además, los componentes de IU de otro nivel hacen que sea más fácil que nunca crear componentes sólidos y con gran belleza sin afectar la experiencia nativa por completo. Por último, las mejoras de calidad de vida en la arquitectura, el diseño, la tipografía y el diseño responsivo no solo resuelven los pequeños detalles, sino que también les brindan a los desarrolladores las herramientas que necesitan para crear interfaces complejas que funcionen en una variedad de dispositivos, factores de forma y necesidades de los usuarios.
Con estas nuevas funciones, deberías poder quitar las secuencias de comandos de terceros para funciones de alto rendimiento, como el relato de desplazamiento y la vinculación de elementos entre sí con el posicionamiento de anclas, la compilación de transiciones de páginas fluidas, la aplicación de diseño a los menús desplegables y la mejora de la estructura general de tu código de forma nativa.
Nunca antes hubo un momento tan propicio para ser desarrollador web. No había habido tanta energía y entusiasmo desde el anuncio de CSS3. Las funciones que necesitábamos, pero que solo soñábamos con lanzar en el pasado, finalmente se están convirtiendo en realidad y en parte de la plataforma. Y gracias a tu voz, podemos priorizar y, finalmente, dar vida a estas funciones. Estamos trabajando para que sea más fácil realizar 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 lanzan, visita developer.chrome.com y web.dev, donde nuestro equipo comparte las noticias más recientes sobre las 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 escucharte y ayudarte.