Material-UI (now MUI) has a variety of excellent layout components. The Stack component is new in version 5 and was created to easily handle one-dimensional vertical and horizontal layouts. Previously these were often handled with the Box component using a flex layout, or a Grid component, but Grids were intended for 2-d layouts.
One of the most important features of the Stack component is that it is a “CSS Utility Component”. This means that quick styling systems are available via simple props such as gap
, width
, and mt
(margin-top). I’ll demo several of these below.
We’ll also explore the classes available for styling the Stack component. A Code Sandbox link with full React code is available in the Resources section.
Here’s a YouTube version of this post or you can watch the video below:
Stack Props and API
The Stack component has lots of spacing and layout props available. It also has access to a styling prop called sx
, (Read a full guide to the new sx styling prop here). Understanding these props will allow you to use the Stack component to its fullest potential.

import * as React from "react";
import Paper from "@mui/material/Paper";
import Stack from "@mui/material/Stack";
import { styled } from "@mui/material/styles";
//import { makeStyles } from "@mui/styles";
//makeStyles method of styling. I used sx instead, code is almost the same
// const useStyles = makeStyles({
// root: {
// backgroundColor: "gray",
// //borderRadius: 5,
// "&.MuiPaper-root": {
// border: "1px solid black"
// },
// "& :first-child": {
// //backgroundColor: "red"
// }
// }
// });
const sxStyles = {
backgroundColor: "gray",
//borderRadius: 5,
"&.MuiPaper-root": {
border: "1px solid black"
},
"& :first-child": {
//backgroundColor: "red"
}
};
const Item = styled(Paper)(({ theme }) => ({
...theme.typography.body2,
padding: theme.spacing(1),
textAlign: "center",
color: theme.palette.text.secondary
}));
export default function ResponsiveStack() {
//const classes = useStyles();
return (
<div style={{ width: "50%", margin: "auto" }}>
<Stack
direction={{ xs: "column-reverse", md: "row" }}
component={Paper}
spacing={{ xs: 2, md: 4 }}
divider={
<div style={{ width: "100%", height: 1, backgroundColor: "black" }} />
}
//gap={2}
//width={120}
//className={classes.root}
sx={{
backgroundColor: "primary.main",
borderRadius: 1,
gap: { xs: 2, md: 4 },
...sxStyles
}}
>
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Item 3</Item>
</Stack>
<div style={{ marginTop: 24 }}>
<a
target="_blank"
href="https://smartdevpreneur.com/the-ultimate-guide-to-the-new-mui-stack-component/"
>
Here's how to use MUI's new Stack component
</a>
</div>
</div>
);
}
The direction prop may most commonly be used to set a row (horizontal) and column (vertical) layout. However, it has additional values such as column-reverse, which I use above. It also has a clever “built-in” way to use theme breakpoint values, which you can see in my code above. A list of possible values is pictured below. “Column” is the default.

The component
prop is used to change the root element rendered by the Stack component. The default is div
. I show an example of passing in a Paper
component later on in the styling section. It changes the root div
to Paper
, which means in the DOM MUI has rendered the element and classes that comprise a “Paper” component.
The divider
prop is similar to the component prop, except that it controls what element is rendered in the DOM between the Stack’s children components. In my code above I passed in a custom styled div. A common choice is to pass in a MUI Divider
component.
MUI Stack Spacing
The remaining prop listed in the docs is spacing
. It can be passed either inside the sx
prop or on its own. Additionally, I passed gap
and width
as their own props instead of inside sx
. These last two were not listed in the docs but are available.
- The
spacing
prop adds padding to the children items. It will automatically either be top and bottom padding or left and right padding depending on thedirection
prop value. - The gap prop adds a CSS row-gap or column-gap value (see the dev tools screenshot below).
- The width prop is simply a quick way to set width. You likely don’t want to add the width prop if the direction might flip to row based on breakpoints.

The spacing prop is clever enough to only add margin to child items after the first child . Take a look at the CSS in the DOM for the demo I made. My example uses value direction={{ xs: "column-reverse"}}
, so the third child item (highlighted below) is actually rendered at the top and MUI adds a marginBottom value.

This presents a challenge when we try to wrap items that overflow the Stack. Later in this post I have a solution for that issue.
Background Color and Border Radius with the Stack sx Prop
The sx prop is a quick way to pass any valid CSS. It can also be used with the MUI spacing system
to pass shorthand spacing props. It even has access to theme values that can be used with valid CSS attributes.
I used the sx prop to pass background color
and border radius: sx={{ backgroundColor: "primary.main", borderRadius: 2 }}
. Keep in mind that styling via className will override styling from the sx
prop.
MUI Stack Wrap
There is a known issue in the Stack component where it does not wrap by default when the items inside overflow the width of the component. The MUI team even created this github issue to track the ‘problem’. As far as I can tell, they decided to leave it with no wrap by default since this is an ambiguous area of web design.
If you want contents to wrap, here’s one solution
- flexWrap: “wrap” in the Stack
sx
prop spacing={0}
in the Stack- Manually add
marginLeft
on the items that don’t touch the left edge of the Stack

The challenge is: if you add spacing via the spacing
prop, you have to select the appropriate child items with a tricky nested selector and remove their marginLeft. In this case, that would have been the last item. It’s not impossible, but I think manually controlling margin might be easier.
Stack Styling and Classes
The Stack component by default has minimal styling applied. The styling focuses on flexing in a row or column direction. If you want to apply more default styling, set prop component={Paper}
and you’ll get a nice shadowing effect plus some borders.
A simple way to style the Stack component is by adding styling values with the sx
prop. You can also still use makeStyles and the className prop.
const sxStyles = {
backgroundColor: "gray",
//borderRadius: 5,
"&.MuiPaper-root": {
border: "1px solid black"
},
"& :first-child": {
backgroundColor: "red"
}
};
//JSX
<Stack
sx={{
backgroundColor: "primary.main",
borderRadius: 1,
gap: { xs: 2, md: 4 },
...sxStyles
}}
>
Here I’ve added a grey background color to Stack, plus styled the first child with a red background. In older minor versions of MUI v5, there was no .MuiStack class (see the screenshot below), but I think that newer minor versions have changed that.

A way to add a default class for styling purposes is to use the component
prop. For example, if I add component={Paper}
then the DOM updates to include Paper default classes:

MUI Stack vs MUI Grid
When choosing between the Stack component and the Grid component, there are several considerations. Do you need:
- One dimensional (row or column) or two dimensional (row and column) layout?
- A simple wrapper or one that has subcomponents and customizations?
- An extremely light DOM or can it be heavier on divs?
In each point above, the first benefit was for the Stack component, the second benefit was for the Grid.
Exploring these in depth, we learned in this post that the Stack handles 1D layouts. The Grid is meant for 2D layouts. That alone will help you choose which to use.
On the second point, the Stack renders as a simple div. The Grid potentially has several layers of divs. The Grid usually contains (at a minimum) a Grid Container component and Grid Item components that wrap the actual content.
It follows from this DOM heaviness that the Stack renders faster, but the Grid can position contents with more customization and flexibility. Take a look at this post to see exactly how to position contents within a Grid.