Stack
Overview
The Stack component lays its children out in a column, with Bulma's block spacing between them and the margins Bulma gives them zeroed.
Reach for it for a column of cards, notifications or form sections. Bulma gives its blocks a bottom
margin to space them, and some a top one beside a sibling (one Media after another, a Divider).
In a flex container those margins add to the gap, so a Stack zeroes its children's top and bottom
margins: the gap is the only space, and there are no margins to undo with mb="0". A spacing
helper such as mt="2" on a child still adds to it. The default gap is Bulma's block spacing, so a Stack of Boxes looks like Bulma's own
stacked blocks.
It's always a column, top to bottom. For a row, use Group, and for a flex container
with no defaults of its own, Flex.
Bulma has no stack, so Stack brings its own styles, in bestax.css and its variants, or in
extras.css next to your own Bulma. The layout is in those styles, so it holds in
bestax-no-helpers.css too, where the gap, alignItems and justifyContent props have no helper
class to add and the defaults stay.
Import
import { Stack } from '@allxsmith/bestax-bulma';
Usage
Basic Usage
A column of Bulma blocks, each spaced from the next by the gap alone.
<Stack> <Notification color="info">Your changes are saved.</Notification> <Box>A Box, with no margin to undo.</Box> <Card> <Card.Content>A Card, last.</Card.Content> </Card> </Stack>
Gap
A gap step replaces the default spacing. Each whole step is 0.5rem, so gap="2" is 1rem, and
gapless puts the children flush. Unset, the gap is --bulma-stack-gap, which follows Bulma's
--bulma-block-spacing. Of the two variables below, that's the Stack's; the other is Group's.
<Group alignItems="flex-start" gap="6"> <Stack gap="1"> <Box p="3">gap="1"</Box> <Box p="3">gap="1"</Box> </Stack> <Stack gap="4"> <Box p="3">gap="4"</Box> <Box p="3">gap="4"</Box> </Stack> </Group>
Forms
A form's fields, spaced evenly. Bulma spaces fields more closely than blocks, 0.75rem apart, which is
gap="1.5". With as="form", the Stack takes a form's attributes, such as action and onSubmit.
<Stack as="form" gap="1.5" aria-label="Profile"> <Field label="Name"> <Input placeholder="Ada Lovelace" /> </Field> <Field label="Email"> <Input type="email" placeholder="[email protected]" /> </Field> <Group justifyContent="flex-end" gap="1"> <Button>Cancel</Button> <Button color="primary">Save</Button> </Group> </Stack>
Alignment
Children stretch across the column by default. alignItems sizes each to its content instead and
places it, and justifyContent places the children down a Stack that's taller than they are.
<Stack alignItems="flex-start" gap="2"> <Button color="primary">Sized to its text</Button> <Button>So is this one</Button> </Stack>
Dividers
A Stack draws no dividers of its own. Put a Divider between the children, and it sits in the
middle of the space.
<Stack gap="3"> <Box>Profile</Box> <Divider /> <Box>Billing</Box> </Stack>
With Columns
A Columns child keeps the negative top and side margins Bulma gives it, and takes at the bottom
the one Bulma gives the last Columns in a container: the column gap pulled back in, or none when
it's gapless. Its columns then line up with the blocks around it and sit the gap away from them, as
they would between Bulma's own blocks. A Pagination child keeps its negative margins too, so its
links line up the same way.
<Stack> <Box>Above</Box> <Columns> <Column> <Box>One</Box> </Column> <Column> <Box>Two</Box> </Column> </Columns> <Box>Below</Box> </Stack>
A Title and Its SubTitle
Bulma sets a SubTitle right under its Title. In a Stack, the gap would come between them, so put
the pair in one element of its own.
<Stack> <div> <Title>Account</Title> <SubTitle>Your profile and how you pay.</SubTitle> </div> <Box>Profile</Box> </Stack>
As a List
With as="ul" or as="ol", give it li children. It restates role="list", which Safari drops
from a list once Bulma's reset hides its markers.
<Stack as="ul" gap="2" aria-label="Recent invoices"> <li> <Box>Invoice 1042, paid</Box> </li> <li> <Box>Invoice 1043, due Friday</Box> </li> </Stack>
Accessibility
- No role of its own: a Stack adds nothing to the accessibility tree, apart from
role="list"on aulorol, which Safari otherwise drops once Bulma's reset hides the markers. - Order: it's always a column in the children's own order, so what's seen, the reading order and the Tab order agree.
- Landmarks: with
as="nav","aside","section"or"main", the Stack is the landmark. Asectionis a region only once it has a name, fromaria-labeloraria-labelledby. - Lists:
as="ul"oras="ol"withlichildren is announced as a list with its count. - Hidden: the
hiddenattribute hides a Stack, as it does any element, so one can be a closed panel or an inactive tab's content.
Related Components
Group: A row of children, which wraps and can stack on a phone.Flex: A flex container with CSS's own defaults and every flex property as a prop.Center: Centers its content on both axes.Grid: Children in a grid of cells rather than one column.Divider: A line between two children.- Helper Props: Bulma helper props for spacing, color, etc.
Additional Resources
- Storybook: Stack Stories
- The Flex guide: The flex helper props, and gap.
- Bulma: Gap helpers
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as | LayoutElement | 'div' | The element to render. With ul or ol, give it li children: it restates role="list", which Bulma's list reset takes away in Safari. |
gap | BulmaGapStep | — | Space between children, a step of Bulma's gap scale ('2' is 1rem). Unset, it's --bulma-stack-gap, Bulma's block spacing. Needs Bulma's helper classes: under bestax-no-helpers.css the default stays. |
alignItems | (typeof validAlignItems)[number] | 'stretch' | How each child sits across the column. 'stretch' makes each as wide as the Stack. Needs Bulma's helper classes: under bestax-no-helpers.css the default stays. |
justifyContent | (typeof validJustifyContents)[number] | — | Where the children sit down the column, when it's taller than they are. Needs Bulma's helper classes: under bestax-no-helpers.css the default stays. |
className | string | — | Additional CSS classes. |
children | React.ReactNode | — | What it lays out. The top and bottom margins Bulma gives them are zeroed, so gap is the only space between them, and a spacing helper such as mt="2" still adds to it. A Columns child keeps its own top and side margins, and takes at the bottom the one Bulma gives the last Columns in a container, the column gap pulled back in (none when gapless), so its columns line up. A Pagination child keeps its negative margins too, so its links line up. |
textColor | Bulma color | 'inherit' | 'current' | — | Text color helper. |
bgColor | Bulma color | 'inherit' | 'current' | — | Background color helper. |
ref | PolymorphicRef<LayoutElement> | — | Ref forwarded to the element as renders. |
... | Remaining props of the element selected by as and Bulma helper props | — | See Helper Props |
Types:
BulmaGapStep:'0'|'0.5'|'1'|'1.5'|'2'|'2.5'|'3'|'3.5'|'4'|'4.5'|'5'|'5.5'|'6'|'6.5'|'7'|'7.5'|'8'|0|0.5|1|1.5|2|2.5|3|3.5|4|4.5|5|5.5|6|6.5|7|7.5|8— A gap step asgap,columnGapandrowGaptake it: a value fromvalidGaps, or the same step written as a number (gap={2},gap={1.5}).Gridtook its gaps as numbers before the gap helpers were shared, so every gap prop still does.LayoutElement:'div'|'main'|'section'|'article'|'aside'|'header'|'footer'|'nav'|'ul'|'ol'|'form'|'fieldset'— The elements Stack, Group, Center and Flex can render as: Container's landmarks and sections, a list, a form or a fieldset.
CSS & Sass Variables
Stack registers these variables on its own .stack element. Override them there (or via className) — a value set on an ancestor is only inherited, and loses to the component-level declaration. See Theme.
| CSS Variable | Sass Variable | Default |
|---|---|---|
--bulma-stack-gap | $stack-gap | var(--bulma-block-spacing) |
--bulma-stack-horizontal-gap | $stack-horizontal-gap | calc(var(--bulma-block-spacing) * 0.5) |