Stack

Stack is a layout utility to group elements and manage spacing between them.
Supports horizontal and vertical directions
Supports custom gap values
Supports 12-column vertical grid layout
Supports rendering as custom HTML tags
Supports changing property values responsively based on the viewport size
Items can be detached for better control over the children layout
Automatically integrates with Hidden utility


Usage

Stack component is the foundation for the most layouts you would have in your applications. It starts with a simple API for the most popular scenarios as well as it provides techniques to cover more advanced use-cases.

To simply group multiple components with a gap between them – wrap them with Stack.

Direction

Stack works not just for vertical groups of components but also lets you to stack them horizontally by using direction property. In this case, child elements will get their width defined based on their content.

One of the reasons for having this utility exists is to solve horizontal stacking when components don't fit into their parent width and should be rendered as multiline. In the future this problem will be solved with the CSS gap property, while currently it's implemented using negative margins.

Stack items can be rendered in the reversed order for both, vertical and horizontal stacks.

Detaching items

Stack doesn't add any additional wrappers to its children wrappers to leverage the flexbox gap property. That works for the most of the cases correctly out-of-the-box. However, there are use cases when you want to have an additional wrapper around the item because of its internal styles. For example, <Button fullWidth /> will behave still try to take full-width.

We provide Stack.Item component to serve as a wrapper:

Item sizes

In addition to just serving as a wrapper, you can use it to achieve flex-grow behavior. Calling Stack.Item with grow property on it will stretch it to take all the space left in that line.

Note: When used in inline stack - this approach will keep all the children displayed in the same line.

When building multi-column layouts you can also use Stack.Item as columns by passing size value to it. Stack supports 12-column layout, so you can pass it any number from 1 to 12.

Splitting items

To avoid having multiple nested stacks when you just need to push one or multiple items to the end, you can use gap property on the Stack.Item set to auto.

Item order

By default, all Stack items have order equal to 0. With order property you can control swap the items inside their flex container, which becomes especially handy for responsive layouts. You can read more about responsive properties' syntax further in this article.

Wrapping

Stack defines its default flex-wrap value based on its direction and on the presence of items with grow flag. This approach should work in the majority of the use cases, but we also allow opt-out from it and control it manually with a wrap flag. You can see how it can be used in the previous order example.

Gap sizes

You can control gap size of the Stack with gap property going from 0 to 6 or removed completely. These values are using corresponding token values, like arcade-unit-x1.

Dividers

Stack supports separating items with a Divider component with the help of divided property.

Alignment

Stack children can be aligned vertically or horizontally using the flexbox approach with align and justify that are representing align-items and justify-content CSS properties.

Responsive properties

Stack can change some of its properties values dynamically based on the viewport size by passing an array of values. First value is for small viewport size (mobile), second on is for medium (tablet) and third is for large viewport (desktop).

You can either pass the values for all screen sizes, or just for some of them and let it automatically fill the rest according to the mobile first approach. This means that if you pass { s: "column", l: "row" } in the example above, Stack will use column direction for small and medium screen. For large and extra large, it will use row direction.

Properties supporting responsive values:

  • Stack: gap, align, justify, direction, wrap
  • Stack.Item: size, grow, order, gap (non-auto)

Hiding items

Since Stack wraps every child with a wrapper, passing a child hidden with css will still apply margin to it. To avoid that, Stack works together with a Hidden utility that will keep css display value on the stack item wrapper and display the margins correctly.

Accessibility

Stack can be used in many contexts and therefore might require to be rendered using specific HTML tags, like ul or ol for lists of items. It can be achieved by using as property on both, Stack and Stack.Item.

Properties

Stack properties:

NameTypeDefaultRequiredComment
directionResponsive(column, row, column-reverse, row-reverse)columnfalse
dividedboolean-falseSeparate items with divider?
gapResponsive(number), auto3falseGap multiplier
alignResponsive(start, end, center)-falseFlex align-items
justifyResponsive(start, end, center)-falseFlex justify-content
wrapResponsive(boolean)-falseEnable flex wrap?
asstringdivfalseTag used for render
childrenReactNode-false
classNamestring-falseclassName for the root element
attributesobject-falseAttributes for the root element

Stack.Item properties:

NameTypeDefaultRequiredComment
growResponsive(boolean)-falseApplies nowrap to Stack
sizeResponsive(1-12, auto)-falseItem column width
orderResponsive(number)-falseItem order in flex container
asstringdivfalseTag used for rendering
childrenReactNode-false
classNamestring-falseclassName for the root element
attributesobject-falseAttributes for the root element
Previous