Saltar al contenido principal

Catálogo · Contenido

Línea de tiempo

Muestra eventos fechados en orden, una tarjeta cada vez sobre una línea de fechas o todos a la vez en una línea vertical; sin JavaScript, es una lista.

Encaja mejor en: blog, landing — eventos o pasos en orden cronológico, como una historia o una hoja de ruta

Esta traducción la ha escrito una IA y todavía no la ha revisado ninguna persona. Leer esta página en inglés

Ejemplo

Los lanzamientos de una aplicación como línea de tiempo, en sus diseños horizontal y vertical.

Horizontal, the default. Pick a date, or use Previous and Next, the arrow keys on the dates, or swipe.

  1. First beta

    Ten teams try the app.

  2. Public launch

    Sign-up opens to everyone.

  3. Offline mode

    Notes sync when the connection returns.

  4. Version 2

    A new editor and shared folders.

With autoplay: it moves on by itself while it is on screen. Pause stops it; it also waits while you point at it or use the keyboard in it.

  1. The idea

    Two people sketch the first screens.

  2. The team

    Five people work on it full time.

  3. The first customers

    Fifty schools use it every week.

With layout="vertical": scroll, and the item in the middle of the screen becomes active.

  1. Version 0.1

    Buttons, forms and tables.

  2. Version 0.2

    Dark mode and a print stylesheet.

  3. Version 0.3

    Right-to-left layouts.

  4. Version 1.0

    The API is stable.

Problemas conocidos

Hay tres cosas pendientes y ninguna se ha probado con un lector de pantalla.

  • Los botones Anterior y Siguiente solo se llaman «Anterior» y «Siguiente». El nombre no indica a qué fecha llevan.
  • No se ha probado si un lector de pantalla anuncia la tarjeta que aparece al cambiar de elemento.
  • La línea de tiempo no se ha probado con ningún lector de pantalla: no se afirma ningún resultado para NVDA, JAWS, VoiceOver, TalkBack ni Orca.

Código

Copiar el marcado

Bundler
import "@luz-ds/catalog/components/timeline.css";
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/components/timeline.min.css" integrity="sha384-WQ94ImVKUsNsMfgRFc24RdFDrzH/9Dc6HCz4FWlUsAcQHX63oP72OzxMchEcBH5g" crossorigin="anonymous">

Una lista ordenada dentro de <luz-timeline>. Asigna al elemento role="group" y un nombre con aria-label para que también se lea sin JavaScript.

HTML
<luz-timeline role="group" aria-label="Releases of the app">
  <ol class="luz-timeline">
    <li class="luz-timeline__item">
      <time class="luz-timeline__date" datetime="2025-03">March 2025</time>
      <p class="luz-timeline__title">First beta</p>
      <p class="luz-timeline__text">Ten teams try the app.</p>
    </li>
    <li class="luz-timeline__item">
      <time class="luz-timeline__date" datetime="2025-06">June 2025</time>
      <p class="luz-timeline__title">Public launch</p>
      <p class="luz-timeline__text">Sign-up opens to everyone.</p>
    </li>
  </ol>
</luz-timeline>

Con reproducción automática, cada cuatro segundos:

HTML
<luz-timeline role="group" aria-label="Milestones" autoplay interval="4000">
  <ol class="luz-timeline">
    <li class="luz-timeline__item">
      <time class="luz-timeline__date" datetime="2023">2023</time>
      <p class="luz-timeline__title">The idea</p>
      <p class="luz-timeline__text">Two people sketch the first screens.</p>
    </li>
    <li class="luz-timeline__item">
      <time class="luz-timeline__date" datetime="2024">2024</time>
      <p class="luz-timeline__title">The team</p>
      <p class="luz-timeline__text">Five people work on it full time.</p>
    </li>
    <li class="luz-timeline__item">
      <time class="luz-timeline__date" datetime="2025">2025</time>
      <p class="luz-timeline__title">The first customers</p>
      <p class="luz-timeline__text">Fifty schools use it every week.</p>
    </li>
  </ol>
</luz-timeline>

Diseño vertical:

HTML
<luz-timeline role="group" layout="vertical" aria-label="Versions of the library">
  <ol class="luz-timeline">
    <li class="luz-timeline__item">
      <time class="luz-timeline__date" datetime="2024-02">February 2024</time>
      <h3 class="luz-timeline__title">Version 0.1</h3>
      <p class="luz-timeline__text">Buttons, forms and tables.</p>
    </li>
    <li class="luz-timeline__item">
      <time class="luz-timeline__date" datetime="2024-09">September 2024</time>
      <h3 class="luz-timeline__title">Version 0.2</h3>
      <p class="luz-timeline__text">Dark mode and a print stylesheet.</p>
    </li>
    <li class="luz-timeline__item">
      <time class="luz-timeline__date" datetime="2025-05">May 2025</time>
      <h3 class="luz-timeline__title">Version 0.3</h3>
      <p class="luz-timeline__text">Right-to-left layouts.</p>
    </li>
  </ol>
</luz-timeline>

Si añades una línea de tiempo a la página después de que se haya cargado, importa el módulo una vez. Define el elemento; no hay que llamar a ningún init:

JS
import "@luz-ds/catalog/timeline";

Variantes y opciones

Las opciones son atributos de <luz-timeline>. Cada elemento tiene una fecha, un título y un texto.

Atributo o claseEfecto
aria-label
El nombre de la línea de tiempo. Escríbelo con role="group": un nombre en un elemento sin rol no se lee. Si omites el rol, el script lo añade.
layout="vertical"
Todos los elementos permanecen visibles en una línea. El elemento del centro de la pantalla está activo y los anteriores ya han pasado.
autoplay
Activa el avance automático con botones visibles de Pausa y Reproducir. Solo en horizontal; desactivado si no lo indicas.
interval
Milisegundos entre elementos con autoplay. El valor predeterminado es 5000; cualquier valor inferior a 2000 sube a 2000.
data-luz-label-previous, -next, -pause, -play
Los nombres de los botones, si LUZ no incluye el idioma de la página o quieres usar otras palabras.
--luz-timeline-paper
El color de fondo de la línea de tiempo, que se usa para la elevación del carril y los puntos vacíos. El valor predeterminado es --luz-surface-page; en una tarjeta, asígnalo al elemento con la superficie de la tarjeta: style="--luz-timeline-paper: var(--luz-surface)".
.luz-timeline__date
Un <time>. Su texto es la etiqueta del botón de fecha en el carril, así que debe ser distinto en cada elemento. Si no lo incluyes, el botón muestra el número del elemento.
.luz-timeline__title
Un <p> o un encabezado del nivel que necesite tu página: la clase no cambia.
.luz-timeline__text
Una o dos frases; se permite un enlace.
data-luz-state
El script lo escribe en los elementos de una línea de tiempo vertical: active o past. No lo asignes tú.

Cómo funciona

Un elemento personalizado alrededor de una lista ordenada nativa, con los estilos de components/timeline.css y un script, timeline.js. catalog.js solo carga el script en páginas que contienen <luz-timeline>.

El elemento busca dentro de sí el primer .luz-timeline; si no lo encuentra, no hace nada.

  • Horizontal. El script crea, solo con métodos del DOM, los botones Anterior y Siguiente a los lados de la tarjeta y un carril de fechas debajo: un botón por elemento, con el texto de su fecha. Las tarjetas comparten una celda de cuadrícula, así que la banda tiene la altura de la tarjeta más larga y no salta al cambiar de elemento. Las tarjetas que no están activas son inert y están ocultas. En la tarjeta activa, la fecha se oculta visualmente porque el carril ya la muestra.
  • Cambiar de elemento. Pulsa una fecha, usa Anterior o Siguiente, las teclas de flecha, Inicio y Fin en el carril, o desliza más de 40 px en horizontal con un dedo o el ratón. Hacia el inicio de la línea está el elemento siguiente. Al llegar a cualquiera de los extremos, vuelve al otro lado. Si el deslizamiento termina sobre un enlace, no se pulsa.
  • El carril. La fecha activa se desplaza hasta el centro con desplazamiento suave, salvo que la persona haya pedido reducir el movimiento. Al moverse con el teclado, el foco permanece en la nueva fecha activa; también lo hace si el cambio oculta la tarjeta que tenía el foco.
  • Vertical. El script marca como data-luz-state="active" el elemento que cruza el centro de la pantalla y como past los anteriores. La línea detrás de un elemento pasado adopta el color de marca y el punto activo se rellena y aumenta de tamaño. También funciona con el movimiento reducido, sin transición.
  • Reproducción automática. Con autoplay, el elemento cambia en bucle cada interval milisegundos. El botón Pausa bajo el carril lo detiene; entonces pasa a llamarse Reproducir y lo vuelve a iniciar. La línea de tiempo también espera sin cambiar el botón mientras el puntero está encima (reanuda tras 4 segundos o al apartarlo), mientras el foco del teclado esté dentro, mientras menos de la mitad esté en pantalla y mientras la pestaña esté oculta. Con movimiento reducido, nunca se inicia y el botón no se muestra.
  • Texto. «Anterior», «Siguiente», «Pausa» y «Reproducir» aparecen en el idioma de la página que incluye LUZ (inglés o español), según el lang más cercano, o el tuyo mediante data-luz-label-*. Se incluyen con el script, así que @luz-ds/catalog/timeline funciona por sí solo. Un idioma que añadas con registerLocale() no les llega: llama a initTimeline(document, t) con la t de core. Consulta los módulos de JavaScript.

Sin JavaScript

Una lista ordenada con todos los elementos visibles: una línea en el lado inicial en línea, con un punto en cada elemento; después, la fecha, el título y el texto. La lista tiene el mismo aspecto antes de que el script defina el elemento, así que no hay saltos cuando lo hace.

La reproducción automática, el carril, Anterior y Siguiente, el gesto de deslizamiento y la marca activa del diseño vertical necesitan JavaScript.

Teclado y ARIA

Tab recorre, en este orden: Anterior, los enlaces de la tarjeta activa, Siguiente, la fecha activa del carril y el botón Pausa o Reproducir. Las demás fechas quedan fuera del orden de Tab; las teclas de flecha permiten moverse entre ellas.

  • Izquierda y Derecha en el carril van a la fecha anterior o siguiente, y el foco las acompaña. En texto de derecha a izquierda, se intercambian. Al pasar cualquiera de los extremos, se vuelve al otro lado.
  • Inicio y Fin van a la primera y la última fecha.
  • Enter o Espacio pulsa una fecha, Anterior, Siguiente o Pausa: son botones nativos.
  • El elemento tiene role="group" y tu aria-label. La fecha activa tiene aria-current="true"; solo esa fecha se puede recorrer con Tab (usa un tabindex itinerante).
  • Las tarjetas forman una sola región dinámica. Tiene aria-live="polite" cuando la persona cambia el elemento y off durante la reproducción automática, para que no se anuncie una tarjeta que cambia sola.
  • El nombre del botón Pausa o Reproducir indica su acción. Los botones de flecha se llaman «Anterior» y «Siguiente»: consulta los problemas conocidos.
  • Las tarjetas que no están activas son inert: no reciben el foco ni se leen. Si el foco estaba en la tarjeta que desaparece, pasa a la nueva fecha activa.
  • Cada tarjeta tiene aria-posinset y aria-setsize, para que el lector de pantalla pueda decir «2 de 4» cuando solo se muestra una tarjeta.

Contraste y foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa una línea de tiempo para una serie breve de eventos fechados cuyo orden sea importante: lanzamientos, hitos o la historia de una empresa.

  • Horizontal, cuando cada evento necesita una tarjeta y la persona los recorre uno a uno.
  • Vertical, cuando se deben ver todos los eventos al desplazarse.
  • De 4 a 10 elementos. A partir de ahí, el carril necesita mucho desplazamiento.

Cuándo no usarlo

No uses una línea de tiempo para pasos que haya que seguir en orden ni para eventos sin fecha.

  • Para un proceso, usa una lista numerada.
  • Para comparar eventos según varios atributos, usa una tabla.
  • Si se deben ver todos los elementos a la vez, usa el diseño vertical: el horizontal muestra una sola tarjeta.
  • No actives la reproducción automática en contenido que no se deba pasar por alto. Nadie tiene que esperar a la tarjeta siguiente.

Qué hacer y qué no

Sí Un título que explique qué ha pasado, con la fecha en un formato uniforme.
No Un título impreciso y fechas en formatos distintos: hay que abrir la tarjeta para saber qué ha pasado y no se pueden comparar las fechas.
Sí Un <time> con un texto diferente en cada elemento: es el nombre del botón del carril.
No Omitir la fecha: el carril muestra botones llamados «1» y «2», que no se distinguen.

Cómo escribir el contenido

Pon primero la fecha y, después, qué ha pasado, con pocas palabras.

  • La fecha: usa el mismo formato en todos los elementos y un texto distinto en cada uno. Es el nombre de un botón.
  • El título: de dos a cinco palabras, con mayúscula inicial y sin punto final. Indica el evento: «Lanzamiento público», no «Novedades».
  • El texto: una frase, de unas pocas líneas como máximo. En el diseño horizontal, la banda tiene la altura de la tarjeta más larga, así que procura que todas tengan una longitud parecida.
  • Usa el atributo datetime para que las máquinas puedan leer la fecha, por ejemplo, 2025-06.

Contraste y foco

El texto usa el color de texto principal o secundario, sobre la página o la tarjeta. Las marcas (línea, puntos, elevación y flechas) son bordes y trazos.

ParteColor sobre el fondoClaroOscuroAlto contrasteNecesita
Fecha y texto de la lista, fechas del carril
--luz-text-secondary on --luz-surface-page
6.2:1
7.5:1
19.3:1
4.5:1
Título de la lista, fecha del carril al pasar el puntero
--luz-text-primary on --luz-surface-page
15.8:1
15.1:1
21.0:1
4.5:1
Título de una tarjeta, flechas Anterior y Siguiente
--luz-text-primary on --luz-surface
16.5:1
14.0:1
21.0:1
4.5:1
Texto de una tarjeta
--luz-text-secondary on --luz-surface
6.4:1
6.9:1
19.3:1
4.5:1
Fecha activa, Pausa y Reproducir
--luz-brand-primary on --luz-surface-page
5.6:1
7.7:1
14.1:1
4.5:1
Borde de las flechas, línea y puntos
--luz-outline on --luz-surface-page
4.3:1
3.6:1
21.0:1
3:1
Línea pasada, punto activo y elevación
--luz-brand-primary on --luz-surface-page
5.6:1
7.7:1
14.1:1
3:1
Anillo de foco
--luz-focus-ring on --luz-surface-page
5.6:1
7.7:1
21.0:1
3:1

Medido a partir de los valores de los tokens de cada modo, redondeado hacia abajo. «Necesita» indica el mínimo AA de WCAG 2.2: 4,5:1 para texto y 3:1 para anillos de foco, bordes e iconos.

  • Foco: las fechas y los botones Anterior y Siguiente tienen un contorno de --luz-focus-ring de 2 px, a 2 px por fuera. Pausa y Reproducir son botones fantasma y tienen el anillo de foco propio de los botones.
  • No solo el color: la fecha activa también es más grande y gruesa, y lleva aria-current. En el diseño vertical, el punto activo está relleno y es más grande, además de que la línea pasada usa el color de marca.
  • Colores forzados: las marcas son bordes y la elevación adopta el color de texto del sistema, así que la línea, los puntos y el estado activo siguen visibles.
  • Área interactiva: Anterior y Siguiente son botones redondos de 44 px; cada fecha es un botón del ancho de su espacio: 7 rem (10 rem en una banda de 600 px de ancho o más).

Tokens que usa

Los 26 tokens que lee components/timeline.css, por familia. Cada familia enlaza a su página, con los valores de todos los modos. En Figma son variables con los mismos nombres: consulta Tokens en Figma.

Spacing and sizing
--luz-control-lg, --luz-space-2xs, --luz-space-3xs, --luz-space-lg, --luz-space-md, --luz-space-sm, --luz-space-xl, --luz-space-xs
Motion
--luz-duration-base, --luz-duration-fast
Typography
--luz-font-heading, --luz-font-sans, --luz-text-lg, --luz-text-md, --luz-text-sm, --luz-text-xl
Radius
--luz-radius-full, --luz-radius-md

Teclado y ARIA están en la pestaña Código.