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.
MUI Stack Horizontal Layout
If you need a horizontal layout, simply set the direction
prop to “row”. The default direction
value is “column” which produces the vertical layout seen in the last section.
Here is a screenshot of the Stack with a horizontal layout:

Here is example code that sets direction to column on the smallest screens and row on all other sizes:
direction={{ xs: "column", sm: "row" }}
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.
MUI Stack vs MUI Box
The Material-UI Stack component has replaced the Box component, in my opinion.
The Box is described as a wrapper component for CSS utility needs by the MUI docs. However, all the styling properties and shortcuts available on the Box are also available for the Stack. The Box is equivalent to a Stack with default prop values.
Additionally, the Stack component is designed specifically to control 1-dimensional layouts. This means it can do everything the Box can, plus it has functionality to easily control vertical and horizontal layouts.
FAQs
Some MUI components have a spacing
prop that adds margin or padding. The screenshot below shows the resulting margin-top from <Stack spacing={2}/>
.
You can add spacing to any component using margin or padding. Here’s example code: <Button sx={{margin: '2px', padding: '2px'}}>Spaced Button</Button>
Some components have a special spacing
prop. The spacing
prop behaves differently on different components. For example, on the Stack component spacing
adds margin-top, while Grid spacing
adds padding-top and padding-left.
Here are a few different methods to right align content in MUI:
1. Use justify-content: “flex-end”
2. Use margin-left: “auto”
3. Use the display
and justifyContent
props – depends on the component
The first two options above can be used inside the sx
prop or with the styled
API. Be sure to use JSX syntax.
Here is an example of the third option where the MUI Stack component uses alignment props:<S
tack display="flex" justifyContent="flex-end"/>