When I am presented with a design to implement using Material UI there is invariably some vertical space between section headers, form labels, input fields, etc. There seem to be a few ways to achieve this:
- Wrap each
<Typography />
,<Checkbox />
, etc. in a<Box paddingBottom={2} />
. - Create a class for each element with the spacing, e.g.
const useStyles = makeStyles(theme => ({ subHeader: { marginBottom: theme.spacing(2) } }));
...
const classes = useStyles();
...
<Typography className={classes.subHeader} />
- Use inline styles, e.g.
const theme = useTheme();
<Typography style={{ marginBottom: theme.spacing(2) }} />
Each of these approaches doesn't seem right to me.
The first adds a lot of extra div
s to your HTML code and guarantees that adjacent conceptual elements are never adjacent; they are always nested.
<div class="MuiBox-root">
<span class="MuiTypography-root" />
</div>
<div class="MuiBox-root">
<span class="MuiTypography-root" />
</div>
With the second you end up creating lots of fairly meaningless classes to accommodate needing different spacing below each element for purely design/aesthetic reasons, not semantic reasons, such as a class with marginBottom: 2
, and one with marginBottom: 3
.
The third option seems to make sense as extracting out spacing logic into reusable code seems overkill, but inline styles are generally frowned upon, and having to call const theme = useTheme()
in every component doesn't seem right.
TLDR; What is the recommended way for spacing components vertically in Material UI?