Grid version 2
The responsive layout grid adapts to screen size and orientation, ensuring consistency across layouts.
The Grid
component works well for a layout with a known number of columns. The columns can be configured with multiple breakpoints to specify the column span of each child.
What's changed
We built the Grid
component from scratch in order to:
- Fix known issues introduced in Material UI v5.
- Simplify the logic with CSS variables, removing the unnecessary
item
prop and reducing CSS specificity. - Introduce a proper fix for preventing a scrollbar by switching between negative margin approaches.
- Set negative margins of equal size on all sides of the grid container by default.
Since the new implementation is considered a breaking change, we introduced it as Unstable_Grid2
to gather feedbacks from the community before making it stable in the next major release of Material UI.
We encourage everyone to try the new version of the Grid
by visiting the Grid v2 migration guide.
How it works
The grid system is implemented with the Grid
component:
- It uses CSS Flexbox (rather than CSS Grid) for high flexibility.
- The grid is always a flex item. Use the
container
prop to add a flex container. - Item widths are set in percentages, so they're always fluid and sized relative to their parent element.
- There are five default grid breakpoints: xs, sm, md, lg, and xl. If you need custom breakpoints, check out custom breakpoints grid.
- You can give integer values for each breakpoint, to indicate how many of the 12 available columns are occupied by the component when the viewport width satisfies the breakpoint constraints.
- It uses negative margins and padding to create gaps between children, which behave similarly to the
gap
CSS property. - It does not support row spanning. Children elements cannot span multiple rows. We recommend using CSS Grid if you need this functionality.
- It does not automatically place children. It will try to fit the children one by one, and if there is not enough space, the rest of the children will start on the next line, and so on. If you need auto-placement, we recommend using CSS Grid instead.
Fluid grids
Fluid grids use columns that scale and resize content. A fluid grid's layout can use breakpoints to determine if the layout needs to change dramatically.
Basic grid
In order to create a grid layout, you need a container. Use the container
prop to create a grid container that wraps the grid items (the Grid
is always an item).
Column widths are integer values between 1 and 12. They can be applied at any breakpoint to indicate how many columns are occupied by the component.
A value given to a breakpoint applies to all the other wider breakpoints unless overridden—see Multiple breakpoints for details. For example, a component with xs={12}
occupies the whole viewport width regardless of its size.
<Grid container spacing={2}>
<Grid xs={8}>
<Item>xs=8</Item>
</Grid>
<Grid xs={4}>
<Item>xs=4</Item>
</Grid>
<Grid xs={4}>
<Item>xs=4</Item>
</Grid>
<Grid xs={8}>
<Item>xs=8</Item>
</Grid>
</Grid>
Multiple breakpoints
Components may have multiple widths defined, causing the layout to change at the defined breakpoint. Width values given to larger breakpoints override those given to smaller breakpoints.
For example, a component with xs={12} sm={6}
occupies the entire viewport width when the viewport is less than 600 pixels wide. When the viewport grows beyond this size, the component occupies half of the total width—six columns rather than 12.
<Grid container spacing={2}>
<Grid xs={6} md={8}>
<Item>xs=6 md=8</Item>
</Grid>
<Grid xs={6} md={4}>
<Item>xs=6 md=4</Item>
</Grid>
<Grid xs={6} md={4}>
<Item>xs=6 md=4</Item>
</Grid>
<Grid xs={6} md={8}>
<Item>xs=6 md=8</Item>
</Grid>
</Grid>
Spacing
Use the spacing
prop to control the space between children. The spacing value can be any positive number (including decimals) or a string. The prop is converted into a CSS property using the theme.spacing()
helper.
The following demo illustrates the use of the spacing
prop:
<Grid container spacing={2}>
Row and column spacing
The rowSpacing
and columnSpacing
props let you specify row and column gaps independently of one another. They behave similarly to the row-gap
and column-gap
properties of CSS Grid.
<Grid container rowSpacing={1} columnSpacing={{ xs: 1, sm: 2, md: 3 }}>
<Grid xs={6}>
<Item>1</Item>
</Grid>
<Grid xs={6}>
<Item>2</Item>
</Grid>
<Grid xs={6}>
<Item>3</Item>
</Grid>
<Grid xs={6}>
<Item>4</Item>
</Grid>
</Grid>
Responsive values
You can set prop values to change when a given breakpoint is active. For instance, we can implement Material Design's recommended responsive layout grid, as seen in the following demo:
<Grid container spacing={{ xs: 2, md: 3 }} columns={{ xs: 4, sm: 8, md: 12 }}>
{Array.from(Array(6)).map((_, index) => (
<Grid xs={2} sm={4} md={4} key={index}>
<Item>xs=2</Item>
</Grid>
))}
</Grid>
Responsive values are supported by:
columns
columnSpacing
direction
rowSpacing
spacing
- all other MUI System props
Auto-layout
The auto-layout feature gives equal space to all items present. When you set the width of one item, the others will automatically resize to match it.
<Grid container spacing={3}>
<Grid xs>
<Item>xs</Item>
</Grid>
<Grid xs={6}>
<Item>xs=6</Item>
</Grid>
<Grid xs>
<Item>xs</Item>
</Grid>
</Grid>
Variable width content
When a breakpoint's value is given as "auto"
instead of true
or a number, then a column's size will automatically adjust to match the width of its content. The demo below shows how this works:
<Grid container spacing={3}>
<Grid xs="auto">
<Item>variable width content</Item>
</Grid>
<Grid xs={6}>
<Item>xs=6</Item>
</Grid>
<Grid xs>
<Item>xs</Item>
</Grid>
</Grid>
Nested grid
The grid container that renders inside another grid container is a nested grid that inherits its columns
and spacing
from the top level. It will also inherit the props of the top-level grid if it receives those props.
Check out the demo below to see what this looks like:
- Link 1.1
- Link 1.2
- Link 1.3
- Link 2.1
- Link 2.2
- Link 2.3
- Link 3.1
- Link 3.2
- Link 3.3
- Link 4.1
- Link 4.2
- Link 4.3
Columns
Use the columns
prop to change the default number of columns (12) in the grid, as shown below:
<Grid container spacing={2} columns={16}>
<Grid xs={8}>
<Item>xs=8</Item>
</Grid>
<Grid xs={8}>
<Item>xs=8</Item>
</Grid>
</Grid>
Offset
Offset props (such as smOffset
, mdOffset
) push an item to the right side of the grid. These props accept:
- numbers—for example,
mdOffset={2}
pushes an item two columns to the right when the viewport size is equal to or greater than themd
breakpoint. "auto"
—this pushes the item to the far right side of the grid container.
The demo below illustrates how to use the offset props:
<Grid container spacing={3} sx={{ flexGrow: 1 }}>
<Grid xs={6} xsOffset={3} md={2} mdOffset={0}>
<Item>1</Item>
</Grid>
<Grid xs={4} md={2} mdOffset="auto">
<Item>2</Item>
</Grid>
<Grid xs={4} xsOffset={4} md={2} mdOffset={0}>
<Item>3</Item>
</Grid>
<Grid xs md={6} mdOffset={2}>
<Item>4</Item>
</Grid>
</Grid>
Custom breakpoints
If you specify custom breakpoints in the theme, you can use those names as grid item props in responsive values:
import { ThemeProvider, createTheme } from '@mui/material/styles';
function Demo() {
return (
<ThemeProvider
theme={createTheme({
breakpoints: {
values: {
laptop: 1024,
tablet: 640,
mobile: 0,
desktop: 1280,
},
},
})}
>
<Grid container spacing={{ mobile: 1, tablet: 2, laptop: 3 }}>
{Array.from(Array(4)).map((_, index) => (
<Grid mobile={6} tablet={4} laptop={3} key={index}>
<div>{index + 1}</div>
</Grid>
))}
</Grid>
</ThemeProvider>
);
}
TypeScript
You have to set module augmentation on the theme breakpoints interface. Properties set to true
will appear as {key}
(size prop) and {key}Offset
(offset prop).
declare module '@mui/system' {
interface BreakpointOverrides {
// Your custom breakpoints
laptop: true;
tablet: true;
mobile: true;
desktop: true;
// Remove default breakpoints
xs: false;
sm: false;
md: false;
lg: false;
xl: false;
}
}
Disable the scrollbar
If you use grid as a container in a small viewport, you might see a horizontal scrollbar because the negative margin is applied on all sides of the grid container.
To disable this scrollbar, set the disableEqualOverflow
prop to true
. This removes the negative margins from the bottom and right sides of the grid to prevent overflow.
The demo below shows how this works:
<div>
<Grid container spacing={3}>
<Grid xs={12}>
<Item>Scroll bar appears</Item>
</Grid>
</Grid>
</div>
<div>
<Grid container spacing={3} disableEqualOverflow>
<Grid xs={12}>
<Item>`disableEqualOverflow` prevents scrollbar</Item>
</Grid>
</Grid>
</div>
Customization
Centered elements
To center a grid item's content, specify display="flex"
directly on the item. Then use justifyContent
and/or alignItems
to adjust the position of the content, as shown below:
<Grid container spacing={2} minHeight={160}>
<Grid xs display="flex" justifyContent="center" alignItems="center">
<Avatar src="/static/images/avatar/1.jpg" />
</Grid>
<Grid display="flex" justifyContent="center" alignItems="center">
<Avatar src="/static/images/avatar/2.jpg" />
</Grid>
<Grid xs display="flex" justifyContent="center" alignItems="center">
<Avatar src="/static/images/avatar/3.jpg" />
</Grid>
</Grid>
Limitations
Column direction and reversing
The column width (xs
, ..., xl
) and offset props are not supported within containers that use direction="column"
or direction="column-reverse"
.
Size and offset props define the number of columns the component will use for a given breakpoint. They are intended to control the width using flex-basis
in row
containers, but they will impact the height in column
containers. If used, these props may have undesirable effects on the height of the Grid
item elements.