Tarjeta

Una tarjeta agrupa contenido relacionado en su propia superficie. Las partes — cardHeader(), cardMedia(), cardBody(), cardFooter() — son funciones separadas y no props, así que usas solo las que necesitas y las pones en el orden que pida el diseño.

Tarjeta básica

Rutas basadas en archivos

src/about.ht.js → /about

Las carpetas pasan a ser rutas. Los corchetes, parámetros. No hay router que configurar.

card(
  cardHeader({ title: 'Rutas basadas en archivos', subtitle: 'src/about.ht.js → /about' }),
  cardBody(text({ variant: 'small', tone: 'muted' }, 'Las carpetas pasan a ser rutas. Los corchetes, parámetros. No hay router que configurar.')),
)

Variantes

Outlined es la opción por defecto. Elevated cambia el borde por una sombra, y flat tiñe la superficie en lugar de cualquiera de las dos.

Outlined

Elevated

Flat

grid({ min: '13rem' },
  card({ variant: 'outlined' }, cardBody(text({ variant: 'small' }, 'Outlined'))),
  card({ variant: 'elevated' }, cardBody(text({ variant: 'small' }, 'Elevated'))),
  card({ variant: 'flat' }, cardBody(text({ variant: 'small' }, 'Flat'))),
)

Con pie

divided añade la línea fina sobre el pie. El pie se empuja abajo, así que unas tarjetas en fila alinean sus acciones aunque el texto de arriba tenga longitudes distintas.

Sitio básico

Un proyecto mínimo más configuraciones de despliegue.

Blog en Markdown

Una carpeta de archivos .md renderizados a páginas estáticas, con feed RSS y sin nada de JavaScript en el cliente.

grid({ min: '14rem' },
  card(
    cardHeader({ title: 'Sitio básico' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'Un proyecto mínimo más configuraciones de despliegue.')),
    cardFooter({ divided: true }, button({ size: 'sm', variant: 'soft' }, 'Abrir')),
  ),
  card(
    cardHeader({ title: 'Blog en Markdown' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'Una carpeta de archivos .md renderizados a páginas estáticas, con feed RSS y sin nada de JavaScript en el cliente.')),
    cardFooter({ divided: true }, button({ size: 'sm', variant: 'soft' }, 'Abrir')),
  ),
)

Medios

cardMedia() llena la parte superior de la tarjeta con una relación de aspecto fija, así que una fila de tarjetas queda pareja midan lo que midan las imágenes de origen.

Por defecto 16 / 9

ratio: 4 / 3

grid({ min: '13rem' },
  card(
    cardMedia({ src: '/logo.svg', alt: '', style: 'background: var(--su-surface-2); object-fit: contain; padding: 1rem' }),
    cardBody(text({ variant: 'small' }, 'Por defecto 16 / 9')),
  ),
  card(
    cardMedia({ src: '/logo.svg', alt: '', ratio: '4 / 3', style: 'background: var(--su-surface-2); object-fit: contain; padding: 1rem' }),
    cardBody(text({ variant: 'small' }, 'ratio: 4 / 3')),
  ),
)

Una tarjeta entera como enlace

Dale a la tarjeta un href y toda la superficie pasa a ser un enlace, con la elevación al pasar por encima que lo acompaña. No pongas botones ni otros enlaces dentro de una tarjeta así: el contenido interactivo no puede anidarse dentro de un enlace. Usa un botón en el pie de una tarjeta normal.

grid({ min: '14rem' },
  card({ href: '/es/docs/routing' },
    cardHeader({ title: 'Rutas', subtitle: 'Leer la guía' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'Rutas dinámicas, comodines y grupos de rutas.')),
  ),
  card({ href: '/es/docs/data' },
    cardHeader({ title: 'Carga de datos', subtitle: 'Leer la guía' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'data() se ejecuta en la compilación, con caché de fetch.')),
  ),
)

Relleno

Una sola prop fija el relleno de todas las partes de la tarjeta a la vez.

padding: sm

padding: xl

stack({ gap: 'md' },
  card({ padding: 'sm' }, cardBody(text({ variant: 'small' }, 'padding: sm'))),
  card({ padding: 'xl' }, cardBody(text({ variant: 'small' }, 'padding: xl'))),
)

Contenido libre

Las partes son una comodidad, no una obligación: una tarjeta admite cualquier hijo, y cardHeader() acepta hijos propios junto al título, para un avatar o un botón de menú a la derecha.

Paul Browne

Desplegado hace 4 minutos

PB
Compilación correcta12 páginas4,1 kB
card(
  cardHeader(
    { title: 'Paul Browne', subtitle: 'Desplegado hace 4 minutos' },
    avatar({ name: 'Paul Browne', size: 'sm' }),
  ),
  cardBody(
    stack({ direction: 'row', gap: 'sm', wrap: true },
      chip({ color: 'success', dot: true }, 'Compilación correcta'),
      chip({ color: 'neutral' }, '12 páginas'),
      chip({ color: 'neutral' }, '4,1 kB'),
    ),
  ),
)

Props

card():

PropTipoPor defectoDescripción
variant'outlined' | 'elevated' | 'flat''outlined'Cómo se separa la superficie de la página.
hrefstring—Dibuja la tarjeta entera como un enlace.
paddingSpace'lg'Relleno que usan todas las partes de la tarjeta.

Las partes:

PartePropsPor defectoDescripción
cardHeadertitle, subtitle—Título y subtítulo, más cualquier hijo junto a ellos.
cardTitleas'h3'El título por su cuenta, cuando la cabecera se construye a mano.
cardSubtitle—La línea atenuada bajo un título.
cardMediasrc, alt, ratio'16 / 9'Una imagen de portada con relación de aspecto fija.
cardBody—La región principal de contenido.
cardFooterdividedfalseFila inferior de acciones; divided añade la línea fina encima.