Marigold
v17.7.0
Marigold
v17.7.0
Component Principles
Accessibility
Design Tokens
Elevation
Layouts
Icons
Form Fields
Spacingalpha
Foundations

Layouts

Learn about how layouting is handled in Marigold

Having a comprehensive collection of reusable components for common tasks (like buttons, cards and form fields) is great but it's not enough to build a whole application. An essential part is missing: components to build layout for application pages.

A typically solution is to provide a <Flex> or <Grid> component for creating arbitrary layouts. However, in order to use those components efficiently developers need to have an intimate knowledge of flex-box and grid, including all their related properties.

Although this gives app developers incredible freedom, it will also leave the burden on them to research and implement necessary layout patterns, while at the same time make them reusable and responsive.

Atomic Layouts

Because layout patterns are such an essential part of building great applications, Marigold comes with a set of layout components that will cover almost, if not all, necessary patterns.

Stack
Columns
Tiles
import type { ReactNode } from 'react';import { Columns, Stack, Text, Tiles } from '@marigold/components';import { Rectangle } from '@/ui/Rectangle';const Annotation = ({ children }: { children: ReactNode }) => (  <Text fontSize="xs" align="center">    {children}  </Text>);export default () => (  <Columns columns={[1, 1, 1]} space={6} collapseAt="0em">    <>      <Stack space={2}>        <Rectangle height="2rem" />        <Rectangle height="2rem" />        <Rectangle height="2rem" />      </Stack>      <Annotation>Stack</Annotation>    </>    <>      <Columns columns={[3, 1, 2]} space={2} collapseAt="0em">        <Rectangle height="126px" />        <Rectangle height="126px" />        <Rectangle height="126px" />      </Columns>      <Annotation>Columns</Annotation>    </>    <>      <Tiles space={2} tilesWidth="32px">        <Rectangle height="30px" width="30px" />        <Rectangle height="30px" width="30px" />        <Rectangle height="30px" width="30px" />        <Rectangle height="30px" width="30px" />        <Rectangle height="30px" width="30px" />        <Rectangle height="30px" width="30px" />        <Rectangle height="30px" width="30px" />        <Rectangle height="30px" width="30px" />        <Rectangle height="30px" width="30px" />      </Tiles>      <Annotation>Tiles</Annotation>    </>  </Columns>);

The majority of layouts used on the web are not that unique. They often can be broken down into just a handful of layout patterns, which then can be combined to achieve more complex layout structures.

Each of Marigold's layout components is build to do one layout pattern well. Like all Marigold's component, they are composable so that they can be combined until the desired layout is achieved. This makes it possible to build more complex layouts from just the given set of atomic layout components.

Isolating Layouts

The move to component-based development has enabled a ton of incredible improvements when it comes to building digital user interfaces. It changed the way how we think about building applications entirely. In combination with the principles from Atomic Design we are no longer building applications page by page. Instead we are focusing on constructing applications by using reusable pieces of UI (a.k.a. components). This not only improves the overall user experience and quality, it also boosts the velocity and convenience of development with which digital products get build.

A majority of the CSS layout patterns unfortunately predate this way of developing applications and as a result breaks the modularity and composition assumptions of components. CSS properties like margin, flex-direction or align-self that affect, or are affected by, elements outside of a component boundary will cause them to not appear as intended. Because of this, some people go as far as considering margin as harmful and advice against its usage.

“Components shouldn't contain surrounding whitespace”

— Mark Dalgleish, Rethinking Design Practices

To avoid unexpected behavior and layout shifts, Marigold follows this principle. Managing whitespace, as well as positioning and arranging components is reserved for Marigold's layout components. This approach ensures that components are as composable as possible while keeping white space predictable.

Layout Components

The components listed below can be nested within each other any number of times to create a wide variety of common layouts. Being familiar with these components is an essential part of working effectively with Marigold.

  • Aside
  • Aspect
  • Breakout
  • Center
  • Columns
  • Container
  • Grid
  • Inline
  • Inset
  • Scrollable
  • Split
  • Stack
  • Tiles

Reach for a layout component only with two or more children

A layout component's whole job is to arrange elements in relation to one another. Just like Inline and Stack express the named intent "lay these out horizontally" or "stack these vertically", that intent only exists once there is more than one thing to arrange. A layout component therefore earns its place only when it arranges two or more children. With a single child there is nothing to arrange, so render the element directly instead of wrapping it.

// Don't: a layout component around a single child adds no intent
<Stack>
  <Card>…</Card>
</Stack>

// Do: render the element directly
<Card>…</Card>

This keeps the JSX tree honest: every layout component in the markup signals a real arrangement decision, not incidental nesting.

Padding and centering wrappers are different

Components whose intent is to wrap a single element — Inset for padding and Center for centering — legitimately take one child. The two-or-more rule applies to arrangement components like Stack, Inline, Columns, Grid and Tiles, where a single child carries no arrangement.

Table is for data, not layout

Table must never be used as a layout grid. It expresses tabular data with rows and columns of related values, not a way to align arbitrary elements. For arranging UI, reach for a layout component instead: form fields belong in Stack, Inline or Columns, never in Table.Cell, since putting inputs in table cells to line them up breaks the named-intent model and harms accessibility. See the Table component for its legitimate use, and the Forms pattern for laying out fields.

Last update: 6 days ago

Elevation

Learn how to use elevation with Marigold.

Icons

List of all icons from Marigold.

On this page

Atomic LayoutsIsolating LayoutsLayout ComponentsReach for a layout component only with two or more children