Box
The Box component can be used for simple flex and grid layouts that have
spacing between each item. This should be the go-to component for creating
layouts or spacing items on the page.
Most of these examples are only available on desktop due to limited demo preview
Flex Example
The Box defaults to using display: flex, align-items: center,
justify-content: center, padding: 1rem, and gap: 1rem.
The padding and gap can be configured globally by changing the
core.$box-gap and core.$box-padding Sass variables.
import { Box } from "@react-md/core/box/Box";
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { type ReactElement } from "react";
export default function FlexExample(): ReactElement {
return (
<Box>
{Array.from({ length: 20 }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
);
}
Disable Flex Wrap
Enable the disableWrap prop to prevent line wrapping and instead attempt to
shrink each item to fit on a single line.
Here is some long text that should be truncated
import { Box } from "@react-md/core/box/Box";
import { Typography } from "@react-md/core/typography/Typography";
import FavoriteIcon from "@react-md/material-icons/FavoriteIcon";
import { type ReactElement } from "react";
export default function DisableFlexWrap(): ReactElement {
return (
<Box style={{ width: "12rem" }} disableWrap>
<FavoriteIcon />
<Typography textOverflow="ellipsis">
Here is some long text that should be truncated
</Typography>
</Box>
);
}
Additional Flex Options
The following flex options can be configured by props:
align-"start" | "center" | "end" | "stretch"justify-"start" | "center" | "end" | "stretch" | "space-around" | "space-between" | "space-evenly"fullWidth- applywidth: 100%disablePadding- do not apply the default paddingstacked- setflex-direction: columnreversed- setflex-direction: row-reverseorflex-direction: column-reversewhenstackedis enabled
See the example below to see how these props can be used.
No Default Padding
Stacked, Align Stretch, Full Width
Align Start
Reversed, Justify Space Between
import { Box } from "@react-md/core/box/Box";
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { Divider } from "@react-md/core/divider/Divider";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
export default function AdditionalFlexOptions(): ReactElement {
return (
<>
<Typography>No Default Padding</Typography>
<Box disablePadding>
{Array.from({ length: 8 }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
<Typography>Stacked, Align Stretch, Full Width</Typography>
<Box stacked align="stretch" fullWidth>
{Array.from({ length: 4 }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
<Divider />
<Typography>Align Start</Typography>
<Box align="start">
<Card>
<CardContent>First</CardContent>
</Card>
<Card>
<CardContent>Second</CardContent>
<CardContent>Some additional content.</CardContent>
</Card>
</Box>
<Divider />
<Typography>Reversed, Justify Space Between</Typography>
<Box align="start" reversed justify="space-between">
<Card>
<CardContent>First</CardContent>
</Card>
<Card>
<CardContent>Second</CardContent>
<CardContent>Some additional content.</CardContent>
</Card>
</Box>
</>
);
}
Grid Example
Enable the grid prop to render equal width dynamic columns that will be at
least 8rem wide.
The min width can be configured globally by changing the core.$box-item-min-size Sass variable.
import { Box } from "@react-md/core/box/Box";
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { type ReactElement } from "react";
export default function GridExample(): ReactElement {
return (
<Box grid>
{Array.from({ length: 20 }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
);
}
Custom Grid Name
As the app grows it might be useful to define different grid variants that
provide different min item size, gap, and/or padding. The variants can be
configured by setting the core.$box-grids variable when @forward-ing or
@use-ing @react-md/core. Each mapped name will be available as a gridName
on the Box component.
Variant 1
Variant 2
Variant 3
Customizing Gap, Padding, and Min Item Size
The gap, padding, and min item size for part of the DOM using the
core.box-set-var mixin or a custom class name on the Box component.
The gap and padding are also available for the flex version
of the Box.
Auto-fill Grid Columns
The grid defaults to using auto-fit but can be configured to auto-fill
by setting gridColumns="fill". To help explain the difference between the two:
auto-fit- fill the entire width with columns and stretch columns to fill the remaining spaceauto-fill- fill the entire width with columns and add empty columns to fill the remaining space
Try changing the ITEMS value below to see the difference.
auto-fit (default)
auto-fill
import { Box } from "@react-md/core/box/Box";
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
// Change this value to see the difference between fit and fill
const ITEMS = 3;
export default function AutoFillGridColumnsExample(): ReactElement {
return (
<>
<Typography>auto-fit (default)</Typography>
<Box grid gridColumns="fit">
{Array.from({ length: ITEMS }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
<Typography>auto-fill</Typography>
<Box grid gridColumns="fill">
{Array.from({ length: ITEMS }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
</>
);
}
Custom Grid Columns
If a specific number of columns should be enforced, set the gridColumns prop
to that number.
import { Box } from "@react-md/core/box/Box";
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { type ReactElement } from "react";
export default function CustomGridColumnsExample(): ReactElement {
return (
<Box grid gridColumns={4}>
{Array.from({ length: 16 }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
);
}
Grid Column Media Queries
The gridColumns prop also supports setting different column behavior based on the
defined media queries:
phone- core.phone-mediatablet- core.tablet-mediadesktop- core.desktop-medialargeDesktop- core.large-desktop-media
Each of the breakpoints can be "fit", "fill", or a number of columns.
Using desktop: "fit"
import { Box } from "@react-md/core/box/Box";
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { useAppSize } from "@react-md/core/media-queries/AppSizeProvider";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
export default function GridColumnMediaQueries(): ReactElement {
return (
<>
<AppSize />
<Box
grid
gridColumns={{
phone: 1,
tablet: "fill",
desktop: "fit",
largeDesktop: 6,
}}
>
{Array.from({ length: 7 }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
</>
);
}
function AppSize(): ReactElement {
const appSize = useAppSize();
let current: string;
if (appSize.isPhone) {
current = "phone: 1";
} else if (appSize.isTablet) {
current = 'tablet: "fill"';
} else if (appSize.isLargeDesktop) {
current = "largeDesktop: 6";
} else {
current = 'desktop: "fit"';
}
return <Typography>Using {current}</Typography>;
}
Grid Auto Rows
To create rows with an equal height, enable the gridAutoRows restrict
the height through CSS. This is most useful when handling unknown sized items
(like file uploads).
Check out the useFileUpload for another example using auto rows.
Additional Grid Options
The following grid options can be configured by props:
align-"start" | "center" | "end" | "stretch"fullWidth- applywidth: 100%disablePadding- do not apply the default padding
See the example below to see how these props can be used.
No Default Padding
Align Stretch, Full Width
Align Start
import { Box } from "@react-md/core/box/Box";
import { Card } from "@react-md/core/card/Card";
import { CardContent } from "@react-md/core/card/CardContent";
import { Divider } from "@react-md/core/divider/Divider";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement } from "react";
export default function AdditionalGridOptions(): ReactElement {
return (
<>
<Typography>No Default Padding</Typography>
<Box grid disablePadding>
{Array.from({ length: 8 }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
<Typography>Align Stretch, Full Width</Typography>
<Box grid align="stretch" fullWidth>
{Array.from({ length: 4 }, (_, i) => (
<Card key={i}>
<CardContent>{`Item ${i + 1}`}</CardContent>
</Card>
))}
</Box>
<Divider />
<Typography>Align Start</Typography>
<Box align="start" grid>
<Card>
<CardContent>First</CardContent>
</Card>
<Card>
<CardContent>Second</CardContent>
<CardContent>Some additional content.</CardContent>
</Card>
</Box>
</>
);
}
Material Grid Example
The material design grid system is defined as:
- 4 columns on mobile
- 8 columns on tablet
- 12 columns on desktop
The material grid is no longer supported out of the box (ha) anymore but can be
re-created using the gridColumns prop and setting the grid-column CSS
property on cells to span multiple columns.
import { Box } from "@react-md/core/box/Box";
import { type BoxGridBreakpointColumns } from "@react-md/core/box/styles";
import { Card } from "@react-md/core/card/Card";
import { cssUtils } from "@react-md/core/cssUtils";
import { type CSSProperties, type ReactElement } from "react";
const GRID_COLUMNS: BoxGridBreakpointColumns = {
phone: 4,
tablet: 8,
desktop: 12,
};
export default function MaterialGridExample(): ReactElement {
return (
<>
<Box grid gridColumns={GRID_COLUMNS} align="stretch">
{Array.from({ length: 12 }, (_, i) => (
<Cell key={i} index={i} />
))}
</Box>
<Box grid gridColumns={GRID_COLUMNS} align="stretch">
{Array.from({ length: 6 }, (_, i) => (
<Cell key={i} index={i} style={{ gridColumn: "span 2" }} />
))}
</Box>
<Box grid gridColumns={GRID_COLUMNS} align="stretch">
{Array.from({ length: 8 }, (_, i) => (
<Cell key={i} index={i} style={{ gridColumn: "span 3" }} />
))}
</Box>
</>
);
}
interface CellProps {
style?: CSSProperties;
index: number;
}
function Cell({ index, style }: CellProps): ReactElement {
return (
<Card
align="center"
justify="center"
style={{ minHeight: "4rem", ...style }}
className={cssUtils({ textAlign: "center" })}
>
{`Cell ${index + 1}`}
</Card>
);
}
Material Grid Customization
If the material grid system is actually still useful, it is recommended to create a few utility classes to help position grid items.
This is not natively supported by react-md since I've never needed
to create layouts that could not be solved with the non-material design grid
system.
Here's an example:
Box Class Name Function
The box styles can also be applied using the box class name function. It
supports all the box styling options and can be applied to any element that
supports display: flex or display: grid.
Setting the gridColumns to a number with the box class name
function does not enforce the provided number of columns like the Box
component. It will only update the --rmd-box-item-min-size to 0.
Use the boxStyles utility if the number of columns must be enforced.
import { box } from "@react-md/core/box/styles";
import { Fieldset } from "@react-md/core/form/Fieldset";
import { Form } from "@react-md/core/form/Form";
import { Legend } from "@react-md/core/form/Legend";
import { TextField } from "@react-md/core/form/TextField";
import { type ReactElement } from "react";
export default function BoxClassNameFunctionExample(): ReactElement {
return (
<Form>
<Fieldset className={box({ grid: true, gridColumns: 3 })}>
<Legend style={{ marginBottom: "1em" }}>Name</Legend>
<TextField label="First Name" autoCompleteValue="given-name" required />
<TextField label="Middle Name" autoCompleteValue="additional-name" />
<TextField label="Last Name" autoCompleteValue="family-name" required />
</Fieldset>
</Form>
);
}
Box Styles Utility Function
If the number of columns or item size need to be controlled, use the
boxStyles utility function instead. It returns a style object with CSS
variables and the corresponding class names.
import { boxStyles } from "@react-md/core/box/styles";
import { Fieldset } from "@react-md/core/form/Fieldset";
import { Form } from "@react-md/core/form/Form";
import { Legend } from "@react-md/core/form/Legend";
import { TextField } from "@react-md/core/form/TextField";
import { type ReactElement } from "react";
export default function BoxStylesUtilityFunctionExample(): ReactElement {
return (
<Form>
<Fieldset
{...boxStyles({
grid: true,
gridColumns: { phone: 1, desktop: 3 },
gridItemSize: { tablet: "12rem" },
})}
>
<Legend style={{ marginBottom: "1em" }}>Name</Legend>
<TextField label="First Name" autoCompleteValue="given-name" required />
<TextField label="Middle Name" autoCompleteValue="additional-name" />
<TextField label="Last Name" autoCompleteValue="family-name" required />
</Fieldset>
</Form>
);
}