Saltar al contenido principal

Core · Mostrar contenido

Tarjeta

Agrupa unos pocos datos sobre un elemento en una superficie con borde.

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

Dos tarjetas, cada una con un título y un dato sobre un servicio.

API gateway

1,204 requests per minute.

Database

48 active connections.

Problemas conocidos

En una tarjeta con enlace, no se puede seleccionar con el ratón el texto del cuerpo, incluido el precio: el enlace del título cubre toda la tarjeta, así que al arrastrar se sigue o se mueve el enlace. La búsqueda en la página, la selección con el teclado y los lectores de pantalla permiten acceder al texto con normalidad.

Código

Copiar el marcado

HTML
<article class="luz-card">
  <h3 class="luz-card__title">Database</h3>
  <p class="luz-card__body">48 active connections.</p>
</article>

Variantes y opciones

Una tarjeta, seis clases y dos modificadores. Un enlace en el título convierte toda la tarjeta en un enlace; cualquier otro enlace o botón queda por encima de él.

Clase o marcadoQué hace
.luz-card
La superficie: borde, esquinas redondeadas y relleno
.luz-card__title
Tamaño base, seminegrita y color de texto principal
.luz-card__body
Tamaño mediano y color de texto secundario
.luz-card__price
El precio: tamaño base, seminegrita, color de texto principal y cifras del mismo ancho. El precio anterior va dentro de <s>
.luz-card--featured
La tarjeta que destaca en el grupo: tiene un borde de 2 px del color de marca y la misma altura que las demás. Indica también el motivo con palabras, por ejemplo, con una etiqueta como «La más elegida»
.luz-card--media
Una imagen arriba, un cuerpo y las acciones al pie: una columna flex sin relleno propio, de modo que la imagen llega hasta el borde
.luz-card__media
El <img>, a todo el ancho, recortado a --luz-card-ratio (16 / 9 si no lo defines) y redondeado solo arriba
.luz-card__actions
Los enlaces o botones, empujados al pie, de modo que los de tarjetas contiguas queden alineados
<a> dentro de .luz-card__title
Tarjeta con enlace: el enlace cubre la tarjeta, el título pasa a sans, el borde se oscurece y aparece una sombra al pasar el puntero; un anillo de foco rodea la tarjeta

Combina una tarjeta con los objetos de maquetación y otros componentes sin añadir clases: crea una tarjeta con enlace, coloca un avatar o un icono junto al texto con .o-media, añade una imagen encima y una fila de acciones con .o-row.

Table

Rows of records that share the same attributes.

Carlos Díaz

Looks after billing and invoices.

Soft dunes in warm light under a clear blue sky

Dunes at sunset

A two-hour walk from the car park.

Database

48 active connections.

Running
  • Tarjeta con enlace: coloca <a> dentro del encabezado, rodeando su texto. Se permite añadir un segundo enlace o un botón, que quedará por encima del enlace del título: consulta la tarjeta de producto más abajo.
  • Avatar o icono: .o-media lo coloca junto a .o-media__body, que contiene el título y el cuerpo. Junto a un nombre, oculta el avatar con aria-hidden="true": repite el nombre.
  • Imagen encima: coloca el marco de imagen (.luz-image) dentro del relleno, con .u-mb-sm debajo. El texto alt describe la imagen; si solo repite el título, déjalo vacío (alt="").
  • Acciones: usa .o-row con botones pequeños (.luz-btn--sm) o etiquetas (.luz-tag) al final de la tarjeta. En una tarjeta con enlace, pon como máximo una acción en forma de botón después del título.

Tarjeta de producto

Una tarjeta de tienda incluye una imagen, un título con enlace, un precio y una acción. La acción es un botón dentro de un formulario, así que funciona sin JavaScript; está por encima del enlace del título y recibe sus propios clics.

Red wines
  • Malbec 2021

    Bodega Albar · 75 cl

    12,50 €

  • Tempranillo reserva 2019

    Bodega Albar · 75 cl

    Now 9,90 € Was 12,50 €

HTML
<article>
  <h4 id="red-wines">Red wines</h4>
  <ul class="o-grid o-grid--auto" aria-labelledby="red-wines">
    <li class="luz-card">
      <div class="luz-image luz-image--4x3 u-mb-sm">
        <picture>…<img src="malbec.jpg" alt="" width="640" height="480" loading="lazy" decoding="async"></picture>
      </div>
      <h5 class="luz-card__title"><a href="/wines/malbec-2021/">Malbec 2021</a></h5>
      <p class="luz-card__body">Bodega Albar · 75 cl</p>
      <p class="luz-card__price"><data value="12.50">12,50 €</data></p>
      <form action="/cart/add" method="post">
        <input type="hidden" name="product" value="malbec-2021">
        <button class="luz-btn luz-btn--primary luz-btn--block" type="submit">Add to cart<span class="u-sr-only"> Malbec 2021</span></button>
      </form>
    </li>
  </ul>
  <output class="u-sr-only" id="cart-status"></output>
</article>
  • El botón ocupa todo el ancho de la tarjeta con .luz-btn--block: es fácil pulsarlo con el pulgar y su etiqueta ocupa varias líneas sin salir de la tarjeta, sea cual sea el tamaño del texto.
  • Una acción y un enlace. El nombre es el enlace; el botón es la acción. Si una tarjeta necesita una segunda acción (añadir a una lista de deseos o comparar), ya no sirve una tarjeta: dirige al lector a la página del producto.
  • El nombre del botón es único. Primero va el texto visible y luego el nombre del producto en .u-sr-only, que repite exactamente el texto del enlace (mantén el espacio delante). Una lista de doce botones llamados «Añadir a la cesta» no dice nada a quien consulta los botones de la página o los dicta por voz.
  • El encabezado identifica la lista: aria-labelledby apunta al <h4> que hay encima y las tarjetas usan el siguiente nivel. Core no da estilo a las listas: elimina las viñetas y la sangría con una regla propia (list-style: none; margin: 0; padding: 0).
  • El precio anterior va en <s>; oculta visualmente las palabras «Ahora» y «Antes» para que el orden quede claro en el lector de pantalla; la línea que lo tacha no depende del color.
  • Confirma cuando un script añade el artículo: incluye desde el principio un <output> vacío (tiene el role status) en la página y escribe «Malbec 2021 añadido a la cesta» en él; el foco se mantiene en el botón. A menudo no se anuncia una región de estado que se crea a la vez que su texto. Sin scripts, se envía el formulario y la página de la cesta confirma la acción.
  • Agotado: sustituye el formulario por <span class="luz-tag">Sold out</span>; no desactives el botón.
  • Core no incluye un marco de imagen: usa un elemento <img> y define tus propias reglas de tamaño.

En un grupo de planes u ofertas, .luz-card--featured destaca la opción que conviene mirar primero. La clase no comunica nada al lector de pantalla, así que la tarjeta incluye una etiqueta de texto que explica el motivo.

One day

79 €

The talks and the workshops of one day.

Choose One day
Team

590 €

Two days for five people, with a shared table.

Choose Team
HTML
<article class="luz-card luz-card--featured">
  <h4 class="luz-card__title">Two days</h4>
  <p class="luz-card__price"><data value="149">149 €</data></p>
  <p class="luz-card__body">Both days, lunch and the recordings.
    <span class="luz-tag luz-tag--blue">Most chosen</span></p>
  <a class="luz-btn luz-btn--primary luz-btn--block" href="/register/?ticket=two-days">Choose Two days</a>
</article>
  • Una sola tarjeta destacada por grupo. Si todo destaca, nada destaca.
  • El texto es imprescindible. El borde de 2 px es una pista adicional para quienes pueden verlo y, en colores forzados, la única pista visual; una etiqueta como «La más elegida» o «La mejor relación calidad-precio» llega a todo el mundo. Ponla en el cuerpo o junto al título.
  • Conserva la misma altura que las demás tarjetas: el píxel adicional del borde se resta del relleno.

Tarjeta con imagen

Para un proyecto, un artículo o un lugar: una imagen, unas pocas palabras y una o más acciones. .luz-card--media convierte la tarjeta en una columna, la imagen llega hasta su borde y las acciones quedan al pie, de modo que en una cuadrícula los botones se alinean sea cual sea la longitud del texto.

Site
Dunes

A two-hour walk.

HTML
<article class="luz-card luz-card--media">
  <img class="luz-card__media" src="tides.webp" alt="" width="1200" height="675">
  <div class="luz-card__body o-stack">
    <h3 class="luz-card__title">Tide table</h3>
    <p>Tides for any harbour on the coast.</p>
  </div>
  <div class="luz-card__actions o-actions">
    <a class="luz-btn luz-btn--primary" href="/tides/demo/">Open the demo<span class="u-sr-only"> of Tide table</span></a>
    <a class="luz-btn luz-btn--secondary" href="/tides/code/">View the code<span class="u-sr-only"> of Tide table</span></a>
  </div>
</article>
  • Un solo destino: enlaza el título. Toda la tarjeta, imagen incluida, es el enlace, y una tarjeta sin __actions no necesita más. Varios destinos: ningún enlace en el título. Pon cada uno en __actions: un enlace alrededor del título cubriría la tarjeta y competiría con los botones.
  • Da a cada acción un nombre único en la página. Primero las palabras visibles y después el título de la tarjeta en .u-sr-only, para que una lista de enlaces diga qué proyecto abre cada uno.
  • La imagen es lo único que puede ser decoración. Si el título lo dice todo, deja alt=""; si no, di qué muestra la imagen. Da siempre width y height, para que la tarjeta no salte al cargar la imagen.
  • El recorte es una propiedad. --luz-card-ratio: 4 / 3 en la tarjeta, o en un contenedor, cambia la forma de todas sus tarjetas; la imagen se recorta, nunca se deforma.
  • Dos acciones como máximo, una junto a la otra cuando caben y apiladas a 640 px o menos (.o-actions).

Cómo funciona

Un contenedor al que da estilo components/card.css. No necesita JavaScript.

  • Usa el elemento que corresponda: <article> para un elemento autónomo, <div> para un grupo de datos y <li> dentro de una lista de tarjetas.
  • Aplica la clase del título al nivel de encabezado que corresponda a la estructura de la página.
  • Las esquinas se redondean con --luz-radius-md, como en una figura o un desplegable.
  • El último título o cuerpo no tiene espacio debajo: el relleno es el último espacio de la tarjeta.
  • .luz-card--media es display: flex en columna con padding: 0: la imagen no tiene relleno; el cuerpo y las acciones llevan --luz-space-md. Las acciones tienen margin-block-start: auto, que las empuja al pie de una tarjeta estirada a la altura de su fila. La imagen mantiene aspect-ratio: var(--luz-card-ratio, 16 / 9) con object-fit: cover, y sus esquinas superiores son el radio de la tarjeta menos el borde de 1 px; la tarjeta no recorta nada, de modo que el anillo de foco se ve entero.
  • En una tarjeta con enlace, el ::after del enlace se extiende por toda la tarjeta (position: absolute; inset: 0), de modo que al hacer clic en cualquier punto se abre el enlace. La tarjeta usa position: relative para contenerlo. Cualquier otro enlace o control dentro de ella (a, button, input, select, textarea, summary) usa position: relative con z-index: 1 para quedar por encima de esa capa y recibir sus propios clics; el enlace del título es el único que nunca se eleva. La etiqueta de un botón ocupa varias líneas dentro de una tarjeta (white-space: normal), así que una etiqueta larga o un texto ampliado no se sale. Al pasar el puntero, el borde cambia a --luz-input-border y aparece una pequeña sombra; al recibir el foco del teclado, un anillo rodea la tarjeta. El título de una tarjeta con enlace usa una fuente sans, como la navegación o una lista de enlaces; una tarjeta sin enlace conserva la tipografía de los encabezados. Ambos casos se detectan con :has(); una tarjeta sin enlace no cambia al pasar el puntero.
  • .luz-card--featured establece border-width: 2px con --luz-brand-primary y resta el píxel adicional del relleno, por lo que la tarjeta conserva la altura de las demás. En una tarjeta con enlace, el borde cambia a --luz-brand-hover al pasar el puntero y el anillo de foco del teclado queda a 4 px del borde, para que no parezca más grueso.
  • Para maquetar tarjetas, usa los objetos de cuadrícula, como la cuadrícula dividida para colocar dos tarjetas en paralelo.

Sin JavaScript

No cambia nada: una tarjeta, tenga enlace o no, incluida la tarjeta con imagen, usa HTML y CSS.

Teclado y ARIA

Una tarjeta no es interactiva ni recibe el foco.

  • En una tarjeta sin enlace, los enlaces y botones interiores conservan su propio comportamiento.
  • En una tarjeta con enlace, los enlaces y botones quedan por encima del enlace del título para que el puntero pueda alcanzarlos. Cada elemento tiene su propia posición en el orden de tabulación y su propio anillo; asígnales un nombre único en la página (consulta Tarjeta de producto).
  • Una tarjeta con enlace tiene una posición de tabulación para el enlace del título y otra para cada enlace o botón adicional. Enter abre el enlace del título; Enter o Espacio activa un botón. El anillo aparece alrededor del enlace del título y de toda la tarjeta; un botón solo muestra su propio anillo.
  • Una tarjeta con imagen y acciones tiene una posición de tabulación por acción, en el orden del código, y ninguna ni anillo propios: el título no es un enlace. Con un solo destino es una tarjeta con enlace, como arriba.
  • El lector de pantalla identifica el enlace con el título y, después, lee el cuerpo como texto. No añadas role, tabindex ni aria-label a la tarjeta.
  • Pon el enlace en el texto del título, nunca alrededor de la tarjeta: un enlace que la rodea usa todas sus palabras como nombre.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa una tarjeta para agrupar unos pocos datos que se entienden como una unidad, a menudo en una cuadrícula de elementos similares.

  • Usa una tarjeta destacada (.luz-card--featured) para la opción recomendada de un grupo de planes u ofertas.
  • Usa una tarjeta con imagen (.luz-card--media) para un proyecto, un artículo o un lugar con imagen, con un destino o dos acciones.

Cuándo no usarlo

No uses una tarjeta para encerrar contenido que no sea un elemento independiente.

  • Para mostrar filas de registros con los mismos atributos, usa una tabla.
  • Para mostrar un mensaje sobre la página, usa una alerta.
  • Para mostrar una lista de enlaces con una línea de descripción cada uno, usa una lista normal (<ul>): una tarjeta por enlace solo añade bordes.
  • Si una tarjeta tiene más de dos acciones, o un formulario, ya es una página: usa la página del elemento, no una tarjeta.
  • No pongas una tarjeta dentro de otra.
  • No destaques varias tarjetas de un grupo ni uses solo el borde como pista: explica también el motivo con palabras.

Qué hacer y qué no

Hazlo Pon el enlace en el título: se puede hacer clic en toda la tarjeta y el título identifica el enlace. Añade después la acción como un botón con su propio nombre.
Evítalo No pongas un enlace alrededor de toda la tarjeta ni un segundo enlace como «Leer más»: el primero usa cada palabra de la tarjeta como nombre; el segundo queda debajo del enlace del título y no se entiende fuera de contexto.
Hazlo Con dos destinos, deja el título sin enlace y pon ambos en las acciones, cada uno con el nombre de su tarjeta.
Evítalo Un título con enlace y acciones en la misma tarjeta: la tarjeta recibe un clic para un tercer destino y el enlace del título repite uno de los botones.
Hazlo Destaca una tarjeta y explica el motivo con palabras: el borde atrae la mirada y la etiqueta informa a todo el mundo.
Evítalo No destaques una tarjeta sin explicarlo con palabras: quien no vea el borde o el color no sabrá que es la opción que debe elegir.

Cómo escribir el contenido

Usa un sustantivo breve como título y añade después una o dos líneas.

  • No pongas un punto al final del título.
  • Mantén el paralelismo entre las tarjetas de un grupo: títulos del mismo tipo y cuerpos de longitud similar.
  • En una tarjeta con enlace, el título es el texto del enlace: indica adónde lleva, así que no hace falta «Leer más».
  • En una tarjeta destacada, una etiqueta de una a tres palabras explica el motivo: «La más elegida», «La mejor relación calidad-precio». Un botón indica el plan: «Elegir dos días».
  • En una tarjeta con imagen: un título de una a cuatro palabras, un cuerpo de dos líneas como máximo y acciones que empiezan con un verbo («Abrir la demo», «Ver el código»). Las mismas palabras en todas las tarjetas de un grupo.
  • Muestra el precio con su moneda, según el formato del idioma de la página. El botón indica qué hace y para qué: «Añadir a la cesta», seguido del nombre del producto para la tecnología de asistencia.

Contraste y foco

El título usa texto principal y el cuerpo texto secundario sobre la superficie de la tarjeta. En una tarjeta con enlace, el título es un enlace y el borde al pasar el puntero y el anillo de foco se sitúan entre la tarjeta y la página.

Una tarjeta destacada tiene un borde de marca respecto a ambos.

ParteColor sobre el fondoClaroOscuroAlto contrasteMínimo
Título
--luz-text-primary on --luz-surface
16.5:1
14.0:1
21.0:1
4.5:1
Precio
--luz-text-primary on --luz-surface
16.5:1
14.0:1
21.0:1
4.5:1
Cuerpo
--luz-text-secondary on --luz-surface
6.4:1
6.9:1
19.3:1
4.5:1
Enlace del título
--luz-brand-primary on --luz-surface
5.9:1
7.2:1
14.1:1
4.5:1
Borde de la tarjeta con enlace al pasar el puntero
--luz-input-border on --luz-surface
3.9:1
3.9:1
21.0:1
3:1
Borde de la tarjeta con enlace al pasar el puntero, respecto a la página
--luz-input-border on --luz-surface-page
3.7:1
4.2:1
21.0:1
3:1
Borde de la tarjeta destacada
--luz-brand-primary on --luz-surface
5.9:1
7.2:1
14.1:1
3:1
Borde de la tarjeta destacada respecto a la página
--luz-brand-primary on --luz-surface-page
5.6:1
7.7:1
14.1:1
3:1
Borde de la tarjeta destacada con enlace al pasar el puntero
--luz-brand-hover on --luz-surface-page
7.7:1
10.2:1
17.9:1
3:1
Anillo de foco alrededor de una tarjeta con enlace
--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 y redondeado hacia abajo. El mínimo requerido es el de WCAG 2.2 AA: 4,5:1 para texto y 3:1 para anillos de foco, bordes e iconos.

  • Foco: una tarjeta normal no lo recibe; los enlaces y botones interiores conservan su propio anillo. En una tarjeta con enlace, el enlace del título mantiene su anillo y otro de 2 px --luz-focus-ring rodea la tarjeta, a 2 px de su borde (a 4 px en una tarjeta destacada, cuyo borde tiene 2 px de grosor). Ambos son contornos y se mantienen en el modo de colores forzados.
  • Bordes: el borde (--luz-divider) es decorativo y no tiene un mínimo: el contenido y el espacio que lo rodea agrupan la tarjeta. En una tarjeta con enlace, el borde al pasar el puntero usa --luz-input-border, alcanza al menos 3:1 y va acompañado de una sombra.
  • No depende solo del color: una tarjeta destacada tiene un borde el doble de grueso (2 px en lugar de 1 px), que se conserva en colores forzados aunque desaparezca el color, y una etiqueta que indica el motivo. La etiqueta es la pista que no depende de la vista.

Tokens que usa

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

Spacing and sizing
--luz-space-2xs, --luz-space-md, --luz-space-sm
Radius
--luz-radius-md
Typography
--luz-font-sans, --luz-text-base, --luz-text-md
Shadows
--luz-shadow-sm
Motion
--luz-duration-base, --luz-duration-fast, --luz-easing-enter

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