Pila

Stack pone espacio entre cosas. Es un contenedor flex con un solo cometido, y es la respuesta a casi todas las preguntas de «cómo separo esto»: en vertical por defecto, en horizontal con direction: 'row'.

Los huecos vienen de la escala de espaciado, así que el ritmo de una página se mantiene coherente sin que nadie elija valores en píxeles.

Pila básica

Primera
Segunda
Tercera
stack({ gap: 'md' },
  card(cardBody('Primera')),
  card(cardBody('Segunda')),
  card(cardBody('Tercera')),
)

Dirección

stack({ direction: 'row', gap: 'md' },
  button('Uno'),
  button({ variant: 'outline' }, 'Dos'),
  button({ variant: 'outline' }, 'Tres'),
)

Hueco

Un nombre de token ('xs' … '3xl'), un número de unidades de espaciado, o una longitud CSS tal cual.

xsxsxs
mdmdmd
6 unidades6 unidades
3rem3rem
stack({ gap: 'lg' },
  stack({ direction: 'row', gap: 'xs' }, chip('xs'), chip('xs'), chip('xs')),
  stack({ direction: 'row', gap: 'md' }, chip('md'), chip('md'), chip('md')),
  stack({ direction: 'row', gap: 6 }, chip('6 unidades'), chip('6 unidades')),
  stack({ direction: 'row', gap: '3rem' }, chip('3rem'), chip('3rem')),
)

Alineación

align y justify admiten valores de flexbox tal cual, así que sirve cualquier cosa que entienda CSS.

iniciofinal
y alineado
stack({ gap: 'md' },
  stack({ direction: 'row', gap: 'sm', justify: 'space-between', style: 'background: var(--su-surface-2); padding: 0.6rem; border-radius: 0.5rem' },
    chip('inicio'),
    chip('final'),
  ),
  stack({ direction: 'row', gap: 'sm', justify: 'center', align: 'center', style: 'background: var(--su-surface-2); padding: 0.6rem; border-radius: 0.5rem' },
    button({ size: 'sm' }, 'Centrado'),
    chip('y alineado'),
  ),
)

Salto de línea

Una fila de chips o botones que puede no caber necesita wrap: sin él se aplastan en vez de pasar a la línea siguiente.

routingdataislandsimagespagefindlighthousesitemaprss
stack({ direction: 'row', gap: 'sm', wrap: true },
  ...['routing', 'data', 'islands', 'images', 'pagefind', 'lighthouse', 'sitemap', 'rss'].map(
    (name) => chip({ color: 'neutral' }, name),
  ),
)

En línea

inline convierte la pila en un inline-flex, así que se sitúa dentro de una línea de texto en vez de ocupar todo el ancho.

Hecho con

sitelovite
y nada más.

text(
  'Hecho con ',
  stack({ direction: 'row', gap: 'xs', inline: true, align: 'center' },
    chip({ color: 'primary', size: 'sm' }, 'sitelo'),
    chip({ color: 'neutral', size: 'sm' }, 'vite'),
  ),
  ' y nada más.',
)

Como otro elemento

stack({ as: 'nav', direction: 'row', gap: 'sm' },
  navLink({ href: '/es/docs' }, 'Documentación'),
  navLink({ href: '/es/ui', current: true }, 'UI'),
  navLink({ href: '/es/examples' }, 'Ejemplos'),
)

Props

PropTipoPor defectoDescripción
direction'row' | 'column''column'Eje principal.
gapSpace'md'Espacio entre los hijos.
alignstring'stretch'Cualquier valor de align-items.
justifystring'flex-start'Cualquier valor de justify-content.
wrapboolean | stringfalsetrue significa envolver; una cadena se pasa tal cual como flex-wrap.
inlinebooleanfalseSe dibuja como inline-flex.
asstring'div'Elemento que se renderiza, por ejemplo nav o ul.