Foundational container for creating structured layouts

import { CdrLayout } from '@rei/cedar'

The layout component helps you organize content in rows and columns while allowing responsiveness across different screen sizes. It incorporates Cedar breakpoints to handle responsive structures and Cedar spacing tokens for cell gaps.

Because layout acts as a styling layer on top of a component, you can use it in conjunction with surface, or any other component. Use it to create side-by-side configurations and multi column or row grids, all while maintaining the flexibility of container or media queries.

When to use

  • Allowing the layout to dictate the content size
  • Determining the layout structure ahead of time or when it has a consistent nature

When not to use

  • Requiring an automatic wrapping of items
  • A flexbox is better suited

When using CdrLayout, make sure that:

  • A parent element has the CSS property container-size applied. This property enables container queries to work
  • There isn't a more refined option that will already fit the need, like media object
  • The content placed inside of layout is flexible. This means it can respond to changing widths and heights of its container. If not, structures can break when content bleeds outside of the layout
  • If using responsive structures like columns or widths, be sure to include all breakpoint options (xs, sm, md, lg)
  • When using with surface, use the as prop to pass in CdrSurface and pass any surface props directly onto the layout component
  • If you need responsive gaps, use the fluid spacing options to create gaps that respond to container widths (Example: scale-3--5)
  • If you need to use media queries, pass a queryType prop of media. The default query type for layout is container queries

Responsive structures

Make sure you know the structure at each screen size and plan accordingly.

A structure can be:

  • A number specifying the split equal columns or rows
  • An array that specifies values for each column or row
  • An object of responsive breakpoints (xs, sm, md, lg) that specifies a number or array for each column and row

Gaps

Use gap, rowGap, or columnGap to specify space between grid cells. We recommend using fluid spacing options when gaps should change based on the container size. Note: the gap prop will be overriden by the more specific row or column gap props, due to CSS priorities.

Flow

When creating a grid that allows X number of cells, it's important to specify in which direction the grid should expand.

Using flow, a shorthand prop for the CSS property grid-auto-flow, either row or column will specify which direction to expand the layout's grid. The flowValue prop will specify how the responsive cells will be sized. Only use these properties when it isn't clear how many, say, columns, a grid will need.

What is CdrLayout? And using the "as" prop

By default, the CdrLayout will render as a div and place content within. For example, when working in conjunction with surface to apply a background color, use the as prop with a value of CdrSurface.

Make sure to import the CdrSurface component into the file you're working on. Any non-layout props will be passed along, allowing any surface props to be applied directly to layout. Layout is more of a styling layer than an actual component.

Equal columns or rows

To create a set number of columns of all equal width, passing in a single number will do the trick. This sets all columns to use the 1fr measurement.

<CdrLayout :columns="2">
  <div>First column with 1fr width</div>
  <div>Second column with 1fr width</div>
</div>

Different columns or rows

In order to create columns with different widths, pass in an array with the specified sizes. Each value can be a number, which is mapped to an fr value, or a CSS value.

<CdrLayout :columns="[1, '200px']">
  <div>This column is 1fr width</div>
  <div>This column is fixed at 200px</div>
</div>

Responsive columns or rows

To create structures for various sized screens, pass in an object into the columns or rows prop. Each key aligns with a Cedar breakpoint (xs, sm, md, lg). Each value is either a number (for equal sized columns or rows) or an array of CSS values (for different sized columns or rows).

<CdrLayout :columns="{ xs: 1, sm: [2, 1], md: [1, '200px'], lg: [1, '500px'] }">
  <div>This column is either 1fr, 2fr, 1fr, or 1fr (depending on breakpoint)</div>
  <div>This column is either 1fr, 1fr, 200px, or 500px (depending on breakpoint)</div>
</div>

When using CdrLayout in a TypeScript application, we recommend importing the Layout interface from the library if you want fine-grained control over the options passed to the component.

ParentComponent.vue

<script setup lang="ts">
import { CdrLayout, type Layout } from '@rei/cedar'

const example: Layout = {
  gap: 'one-x',
  columns: 2,
};

</script>

<template>
  <main>
    <CdrLayout v-bind="example">
      ...
    </CdrLayout>
  </main>
</template>

CdrLayout

Props

NameTypeDefault
queryType

Determines if the layout is in horizontal or vertical mode. Possible values: container, media

QueryType'container'
flow

Specifies the auto-placement behavior. This is translated to `grid-auto-flow`. Possible values: row, column

Flow
flowValue

Specifies how auto-generated tracks will be created. This is translated to either `grid-auto-columns` or `grid-auto-rows`, depending on flow.

string'auto'
columns

Determines the number of columns at various breakpoints

StructureOption
rows

Determines the number of rows at various breakpoints

StructureOption
gap

Specifies a gap based on the token options within Cedar. Possible values: zero, one-x, two-x, scale-4, scale-3--5

Space'zero'
rowGap

Specifies a row gap based on the token options within Cedar. Possible values: zero, one-x, two-x, scale-4, scale-3--5

Space'zero'
columnGap

Specifies a column gap based on the token options within Cedar. Possible values: zero, one-x, two-x, scale-4, scale-3--5

Space'zero'
as

The component or HTML tag to render at the root level. Note: The component "CdrSurface" has special treatment and may be used in quotes.

union'div'

Slots

Name
default

Where all default content should be placed.