Layout

AI Tip Want to skip the docs? Use the MCP Server

Learn how to build application layouts with Hopper using Flex or Grid.

Introduction

Hopper includes layout components to help build applications. The Flex and Grid components are containers responsible for the layout of their children. Flex follows the the CSS flexbox algorithm, while Grid implements CSS grid.

These components provide props with predefined Hopper tokens for sizing, spacing, and other layout options. You can use Flex and Grid together to build different parts of your application, and even nest them to create more complex layouts.

You should prefer using flex and grid over other CSS layout models. Spacing between components should be managed by parent layout components rather than added directly to the children. This ensures components are composable when reused in different places and that spacing remains consistent.

In addition to Flex and Grid, some Hopper components include prebuilt layouts which you can insert your content into via slots. You can read more about slots in the slots concept page.

Flex

The flexbox layout model is a simple yet versatile method of laying out components in rows and columns. Use it to build vertical or horizontal stacks, simple wrapping grids, and more. The Flex component can be used to create flexbox containers. Any Hopper component can be used as a child within these containers. Flex layouts can be nested to create more complex layouts.

The gap, rowGap and columnGap can be defined with Hopper space tokens to ensure consistency across applications, and allow the layout to adapt to different devices automatically.

Example

A simple vertical stack, with a gap between each item defined using a Hopper space token.

Learn more

You can learn more about Flex and see more examples on the Flex page. There are many great resources on the web for learning flexbox as well.

Grid

CSS grid is a powerful way to lay out elements in two dimensions. It can be used to to build full page application layouts, or smaller user interface elements. It is especially powerful because it allows you to build many types of layouts without extra presentational elements, keeping your code clean and semantic. In addition, grid layouts are automatically mirrored in right-to-left languages.

The Grid component can be used as a container to define a grid layout. Any Hopper component can be used as a child of a Grid. The Grid component extends the CSS syntax to support defining grids using Hopper-defined dimension tokens. This ensures that sizing and spacing is consistent between applications, and allows the layout to adapt to different devices automatically.

Defining grids

There are many ways to define grids, but the simplest is to use the areas prop to declaratively specify your layout using named areas. This prop accepts an array of strings which represent rows. Within the rows, you specify space separated names for grid areas. The children of the Grid can declare the gridArea prop, which places them into these named regions.

In addition, you can define the columns and rows props on the Grid container to specify the widths and heights of the columns and rows respectively. This can be done using Hopper-defined dimension tokens to ensure they are adaptive on various devices.

The following example shows how you could use Grid to declare a common application layout, with a header, sidebar, content area, and footer. Notice how there are no nested layout elements — the layout is entirely declared in the Grid and the children simply declare where they should be placed.

Learn more

You can learn more about Grid and see more examples on the Grid page. There are many great resources on the web for learning CSS grid as well.

Choosing Inline, Stack, or Flex

Use Inline or Stack by default when your layout matches their intent. They are opinionated Flex presets that keep code shorter and more consistent:

Important: Inline and Stack do not support the raw justifyContent or alignItems props. Instead they expose semantic aliases:

/** An alias for the CSS justify-content property. */ alignX?: FlexProps["justifyContent"]; /** An alias for the CSS align-items property. */ alignY?: FlexProps["alignItems"];

Use alignX where you would normally use justifyContent, and alignY where you would use alignItems when working with Inline or Stack. The underlying Flex component still uses justifyContent and alignItems directly.

  • Inline is Flex with flex-direction: row, align-items: center, and a default gap token for horizontal spacing (exposed as alignY="center").
  • Stack is Flex with flex-direction: column and a default gap token for vertical spacing.

When to use Inline

You have items in a single horizontal row and shared cross axis alignment: Typical header actions, icon plus label, button groups. It is fine to tweak one thing such as gap, alignX (was justifyContent in raw flex), or wrap. If you also need a different cross axis alignment (alignY) and another structural change, prefer Flex.

Example:

<Inline gap="inline-sm" alignX="space-between"> <Title /> <Actions /> </Inline>

When to use Stack

You are arranging elements vertically with consistent spacing: Forms, card content, dialog body. It is fine to tweak one thing such as gap or alignY (alias for alignItems). If you also need direction to flip at a breakpoint or multiple alignment rules, prefer Flex.

Example:

<Stack gap="stack-md"> <Field /> <Field /> <HelpText /> </Stack>

When to use Flex

You are doing more than a light tweak or you need per child control. Any two or more of the following is a good signal to switch:

  • Changing alignItems and justifyContent together (for Inline/Stack this would be changing both alignX and alignY),
  • Mixing wrap with custom alignment,
  • Using order, flex grow or shrink on children,
  • Flipping flex-direction responsively,
  • Aligning some children differently from others,
  • Asymmetric or breakpoint specific gaps,
  • Baseline alignment for text heavy rows.

Example:

<Flex alignItems="flex-start" justifyContent="space-between" gap="inline-lg"> <Avatar size="lg" name="Alexandre" /> <Stack gap="stack-sm" flex={1}> <H3>Alexandre Asselin</H3> <Text variant="body-sm" color="text-secondary"> Staff Software Engineer </Text> </Stack> <Inline gap="inline-sm"> <Button variant="secondary">Message</Button> <Button variant="primary">Connect</Button> </Inline> </Flex>

Practical Rule Start with Inline for horizontal rows and Stack for vertical stacks. If you find yourself changing more than one core knob or applying flex properties to individual children, move to Flex. One override is fine. Two or more usually means Flex.

Responsive layout

All props of the Flex and Grid components support object syntax to specify different values for the prop depending on a responsive breakpoint. You can learn more about responsive styles on the Responsive Styles page.