The Material-UI grid system
Tags: react, javascript, ui, webdev
Published: 2020-02-21 14:04:11

---
title: The Material-UI grid system
published: true
date: 2020-02-18 18:30:36 UTC
tags: react,javascript,ui,webdev
canonical_url: https://blog.logrocket.com/the-material-ui-grid-system/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/g7ui1ma18vpetulthqu1.png
---
**Written by [Gaurav Singhal](https://blog.logrocket.com/author/gauravsinghal/)**✏️

Material-UI is a popular design system developed by Google in 2014. Since then, it has been widely used by designers and developers across the globe.

In this guide, we’ll explore [Material-UI](https://material-ui.com/) and its grid system and show how you can use it to build applications with React.

## Material Design

Material Design is a visual language that synthesizes the classic principles of good design with the innovation of technology and science. Widely used in Android app development, it defines a set of principles and guidelines for designing UI components.

Material Design comes with prebuilt UI components, including buttons, navbars, navigation drawers, and, most importantly, the grid system.

Google and many other tech companies use Material Design extensively across their brand and products. In 2018, Google revamped the design system, making it more flexible for designers to create custom themes on top of Material-UI.

That’s Material Design in a nutshell. Next, we’ll dig into the grid system, it’s features and limitations, and implementation in React.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## Material-UI’s grid system

A grid system defines a set of measurements to place elements or components on the page based on successive columns and rows. The grid system in Material Design is visually balanced. It adapts to screen sizes and orientation, which ensures a consistent layout across pages.

The grid system consists of three components:

1. **Columns** — Elements on the page are placed within columns, which are defined by percentages rather than fixed values so that the elements can flexibly adapt to any screen size
2. **Gutters** — The spaces between the columns are defined by a fixed value at each breakpoint to better adapt the screen size
3. **Margins** — The spaces between the left and right sides of the screen are defined by a fixed value similar to gutters, at each breakpoint

## Implementation in React with the `material-ui` library

The `material-ui` library provides React components that implement Google’s Material Design.

### Installation

Run the following command to install `material-ui` as a dependency in your project.

```jsx
npm install @material-ui/core
```

Material-UI uses Roboto as the default font, so don’t forget to add it as well.

```jsx
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
```

### Basic use

All the components are isolated, self-supporting, and only inject styles that they need to present. Below is a quick example to get things going.

```jsx
import React from "react";
import Button from "@material-ui/core/Button";

function App() {
  return (
    <Button variant="contained" color="primary">
      Material Button Demo
    </Button>
  );
}

export default App;
```

## The grid component

The Material Design’s grid system is implemented in `material-ui` using the `<Grid />` component. Under the hood, the `<Grid />` component uses [Flexbox properties](https://blog.logrocket.com/flexing-with-css-flexbox-b7940b329a8a/) for high flexibility.

There are two types of grid components: containers and items. To make the layout fluid and adaptive to screen sizes, the item widths are set in percentages. Padding creates spacing between individual items. Finally, there are five types of grid breakpoints: `xs`, `sm`, `md`, `lg`, and `xl`.

### Import

To import the `<Grid />` component into the js file, use the following line.

```jsx
import Grid from "@material-ui/core/Grid";
```

### Containers and items

The `container` prop gives the `<Grid />` component the CSS properties of a `flex` container and the `item` prop gives the CSS properties of a `flex` item.

The `items` must be wrapped in a `container`, as shown below.

```jsx
<Grid
  container
  // ...
>
  <Grid
    item
    // ...
  >
    <Paper></Paper>
  </Grid>
</Grid>
```

## Features

Let’s look at the various props you can provide to the container and item to build a flexible layout.

### Spacing

You can apply the `spacing` prop to the grid container to create spaces between individual grid items. In the following example, we interactively change the `spacing` prop value by passing the value through a set of radio button components.

```jsx
import React from "react";
import Grid from "@material-ui/core/Grid";
import FormLabel from "@material-ui/core/FormLabel";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import RadioGroup from "@material-ui/core/RadioGroup";
import Radio from "@material-ui/core/Radio";
import Paper from "@material-ui/core/Paper";

const classes = {
  paper: {
    height: 140,
    width: 100
  },
  control: {
    padding: 20,
    marginTop: 15,
    background: "#fc3"
  }
};

export default function SpacingGridDemo() {
  const [spacing, setSpacing] = React.useState(2);

  const handleChange = event => {
    setSpacing(Number(event.target.value));
  };

  return (
    <div>
      <div>
        <Grid container justify="center" spacing={spacing}>
          {[0, 1, 2].map(value => (
            <Grid key={value} item>
              <Paper className={classes.paper} />
            </Grid>
          ))}
        </Grid>
      </div>
      <div>
        <Paper className={classes.control}>
          <div>
            <FormLabel>spacing</FormLabel>
            <RadioGroup
              name="spacing"
              aria-label="spacing"
              value={spacing.toString()}
              onChange={handleChange}
              row
            >
              {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(value => (
                <FormControlLabel
                  key={value}
                  value={value.toString()}
                  control={<Radio />}
                  label={value.toString()}
                />
              ))}
            </RadioGroup>
          </div>
        </Paper>
      </div>
    </div>
  );
}
```

### Fluid grids

We can create layouts for different screen sizes by using the breakpoint props (`xs`, `sm`, `md`, `lg`, `xl`) on the grid items. Fluid grids can scale the grid items and resize content within them.

```jsx
import React from "react";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";

const classes = {
  root: {
    flexGrow: 1
  },
  paper: {
    padding: 20,
    textAlign: "center",
    color: theme.palette.text.secondary,
    fontFamily: "Roboto"
  }
};

export default function BreakpointGridDemo() {
  return (
    <div className={classes.root}>
      <Grid container spacing={3}>
        <Grid item xs={12}>
          <Paper className={classes.paper}>xs=12</Paper>
        </Grid>
        <Grid item xs={12} sm={6}>
          <Paper className={classes.paper}>xs=12 sm=6</Paper>
        </Grid>
        <Grid item xs={12} sm={6}>
          <Paper className={classes.paper}>xs=12 sm=6</Paper>
        </Grid>
        <Grid item xs={6} sm={3}>
          <Paper className={classes.paper}>xs=6 sm=3</Paper>
        </Grid>
        <Grid item xs={6} sm={3}>
          <Paper className={classes.paper}>xs=6 sm=3</Paper>
        </Grid>
        <Grid item xs={6} sm={3}>
          <Paper className={classes.paper}>xs=6 sm=3</Paper>
        </Grid>
        <Grid item xs={6} sm={3}>
          <Paper className={classes.paper}>xs=6 sm=3</Paper>
        </Grid>
      </Grid>
    </div>
  );
}
```

### Auto-layout

The auto-layout feature allows the grid items to auto-resize and occupies the available space without having to specify the width of the item. If you set width on one of the items, the child items would automatically resize and share the available space.

In the following example, you can see that the items around the `xs={9}` item auto-resize, resulting in a perfect layout.

```jsx
import React from "react";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";

const classes = {
  root: {
    flexGrow: 1
  },
  paper: {
    padding: 20,
    textAlign: "center"
  }
};

export default function AutoGridDemo() {
  return (
    <div className={classes.root}>
      <Grid container spacing={2}>
        <Grid item xs>
          <Paper className={classes.paper}>xs</Paper>
        </Grid>
        <Grid item xs>
          <Paper className={classes.paper}>xs</Paper>
        </Grid>
        <Grid item xs>
          <Paper className={classes.paper}>xs</Paper>
        </Grid>
      </Grid>
      <Grid container spacing={2}>
        <Grid item xs>
          <Paper className={classes.paper}>xs</Paper>
        </Grid>
        <Grid item xs>
          <Paper className={classes.paper}>xs</Paper>
        </Grid>
        <Grid item xs={9}>
          <Paper className={classes.paper}>xs=9</Paper>
        </Grid>
      </Grid>
    </div>
  );
}
```

### Nested grids

We can use grids within each other. In the demo below, the `container` and `item` props are combined so the `<Grid />` component can act like both a container and an item. This allows us to have another set of the grid inside the grid item. In this case, it’s the `<InnerGrid />` component.

```jsx
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";

const classes = {
  root: {
    flexGrow: 1
  },
  paper: {
    padding: 20,
    textAlign: "center",
    color: "#777"
  }
};

export default function NestedGridDemo() {
  function InnerGrid() {
    return (
      <React.Fragment>
        <Grid item xs={4}>
          <Paper className={classes.paper}>item</Paper>
        </Grid>
        <Grid item xs={4}>
          <Paper className={classes.paper}>item</Paper>
        </Grid>
        <Grid item xs={4}>
          <Paper className={classes.paper}>item</Paper>
        </Grid>
      </React.Fragment>
    );
  }

  return (
    <div className={classes.root}>
      <Grid container spacing={1}>
        <Grid container item xs={12} spacing={3}>
          <InnerGrid />
        </Grid>
        <Grid container item xs={12} spacing={3}>
          <InnerGrid />
        </Grid>
        <Grid container item xs={12} spacing={3}>
          <InnerGrid />
        </Grid>
      </Grid>
    </div>
  );
}
```

## Limitations of Material-UI

### Negative margin

`material-ui` uses a negative margin to implement spaces between grid items. When the negative margin goes beyond the `<body>`, a horizontal scroll appears.

To fix this, the `material-ui` documentation suggests:

> 1. Not using the spacing feature and implementing it in userspace `spacing={0}` (default)
> 2. Applying padding to the parent with at least half the spacing value applied to the child
> 3. Adding `overflow-x: hidden;` to the parent

### `white-space no-wrap`

By default, the flex items have the `min-width` property set to `auto`. This causes a conflict in positioning when the child is using `white-space: nowrap;` property.

To fix this problem, we need to set the `min-width: 0` or `zeroMinWidth` property on the grid item.

### `column` and `column-reverse`

Some of the grid features are not supported for `direction: column` and `direction: column-reverse`. The breakpoints are focused on controlling the width and do not have a similar effects on height within the `column` and `column-reverse` containers.

## Conclusion

Despite the handful of drawbacks described above, Material-UI grids enable you to create innovative, responsive layouts. Hopefully, this guide will help you take full advantage of the numerous features we discussed. They’ll come in handy at some point or another when you’re working with the Material Design system.

* * * 
## Full visibility into production React apps 

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket.](https://www2.logrocket.com/react-performance-monitoring)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/eq752g8qhbffxt3hp9t4.png)

[LogRocket](https://www2.logrocket.com/react-performance-monitoring) is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — [start monitoring for free.](https://www2.logrocket.com/react-performance-monitoring)
* * *

The post [The Material-UI grid system](https://blog.logrocket.com/the-material-ui-grid-system/) appeared first on [LogRocket Blog](https://blog.logrocket.com).