Stack
Available from version 0.6.0
Stack is a container component for arranging elements vertically or horizontally.
Basics
import { Stack } from 'tailwind-joy/components';
The Stack component acts as a generic container, wrapping around the elements to be arranged.
Use the spacing
prop to control the space between children.
The spacing value can be any number, including decimals, or a string.
import type { ReactNode } from 'react';
import { Box, Sheet, Stack } from 'tailwind-joy/components';
function Item({ children }: { children?: ReactNode }) {
return (
<Sheet
className="
text-joy-neutral-700 border-joy-neutral-500/20 dark:border-joy-neutral-500/[.16]
dark:text-joy-neutral-300 rounded-[8px] border border-solid p-2 text-center
text-[length:var(--joy-fontSize-sm,0.875rem)] font-medium leading-[var(--joy-lineHeight-md,1.5)]
"
>
{children}
</Sheet>
);
}
export function StackBasics() {
return (
<Box className="w-full">
<Stack spacing="16px">
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Item 3</Item>
</Stack>
</Box>
);
}
Customization
Direction
By default, Stack arranges items vertically in a column.
Use the direction
prop to position items horizontally in a row:
import type { ReactNode } from 'react';
import { Sheet, Stack } from 'tailwind-joy/components';
function Item({ children }: { children?: ReactNode }) {
return (
<Sheet
className="
text-joy-neutral-700 border-joy-neutral-500/20 dark:border-joy-neutral-500/[.16]
dark:text-joy-neutral-300 rounded-[8px] border border-solid p-2 text-center
text-[length:var(--joy-fontSize-sm,0.875rem)] font-medium leading-[var(--joy-lineHeight-md,1.5)]
"
>
{children}
</Sheet>
);
}
export function StackDirection() {
return (
<div>
<Stack direction="row" spacing="8px">
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Item 3</Item>
</Stack>
</div>
);
}
Dividers
Use the divider
prop to insert an element between each child.
This works particularly well with the Divider component, as shown below:
import type { ReactNode } from 'react';
import { Box, Divider, Sheet, Stack } from 'tailwind-joy/components';
function Item({ children }: { children?: ReactNode }) {
return (
<Sheet
className="
text-joy-neutral-700 border-joy-neutral-500/20 dark:border-joy-neutral-500/[.16]
dark:text-joy-neutral-300 rounded-[8px] border border-solid p-2 text-center
text-[length:var(--joy-fontSize-sm,0.875rem)] font-medium leading-[var(--joy-lineHeight-md,1.5)]
"
>
{children}
</Sheet>
);
}
export function StackDividers() {
return (
<Box className="w-full">
<Stack
direction="row"
divider={<Divider orientation="vertical" />}
spacing="16px"
className="justify-center"
>
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Item 3</Item>
</Stack>
</Box>
);
}
Flexbox gap
To use flexbox gap
for the spacing implementation, set the useFlexGap
prop to true.
It removes the known limitations of the default implementation that uses a CSS nested selector.
import type { ReactNode } from 'react';
import { Box, Sheet, Stack } from 'tailwind-joy/components';
function Item({ children }: { children?: ReactNode }) {
return (
<Sheet
className="
text-joy-neutral-700 border-joy-neutral-500/20 dark:border-joy-neutral-500/[.16]
dark:text-joy-neutral-300 grow rounded-[8px] border border-solid p-2 text-center
text-[length:var(--joy-fontSize-sm,0.875rem)] font-medium leading-[var(--joy-lineHeight-md,1.5)]
"
>
{children}
</Sheet>
);
}
export function StackFlexboxGap() {
return (
<Box className="w-[200px]">
<Stack direction="row" spacing="8px" useFlexGap className="flex-wrap">
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Long content</Item>
</Stack>
</Box>
);
}
Limitations
Margin on the children
Customizing the margin on the children is not supported by default.
For instance, the top-margin on the Button
component below will be ignored.
<Stack>
<Button className="mt-[30px]">...</Button>
</Stack>
To overcome this limitation, set useFlexGap
prop to true to switch to CSS flexbox gap implementation.
white-space: nowrap
The initial setting on flex items is min-width: auto
.
This causes a positioning conflict when children use white-space: nowrap
.
In order for the item to stay within the container you need to set min-width: 0
.
<Stack direction="row" className="min-w-0">
<Typography noWrap>
Anatomy
The Stack component is composed of a single root <div>
element:
<div class="tj-stack-root ...">
<!-- Stack contents -->
</div>
API
See the documentation below for a complete reference to all of the props available to the components mentioned here.