Material UI's Grid layout system is mostly a wrapper around the "CSS Flexible Box module", also known as Flexbox. See the official spec for Flexbox here.
This particular library is an example of why you should read the source code of libraries to understand how they work at a deeper level. Without an understanding of Flexbox, you won't understand what most of the props are doing here. Similarly, if you've mastered Flexbox or CSS Grid already, you may find it more comfortable to implement your own grid with your own CSS.
So while it's not required to use Material UI's Grid to build grids in your application, using it does have some advantages (and disadvantanges).
A Brief Explanation of Flexbox
Let's refer to the W3 spec on the exact terms we'll be using.
A flex container is the box generated by an element with a computed display of flex or inline-flex. In-flow children of a flex container are called flex items and are laid out using the flex layout model. So to keep the definition really simple, a flex container is an element with CSS
display: flex
. That's it, by that one CSS property, that element becomes a flex container and the children of that element magically become flex items. Check out Example 1 below for a simple example of a pure flexbox with no other CSS properties other than a border on the items so you can see how they are laid out by default.
Properties of Flexbox
Of course there is no better site than CSS Tricks for the complete visual guide of flexbox.
As Material UI uses Flexbox under the hood for their Grid, you should at least know a few key properties. Using the flex-grow
property, you can specify
a unitless value (like 2,2,4,4) to proportionally scale the widths of the items or have one item take up the remaining space. flex-basis
accepts more normal width values (33%, 100px) to use as the default column width before applying flex-grow
properties. Material UI uses flex-basis
and max-width
to set the
widths of the columns this way with the below breakpoint properties. In all honesty, Flexbox is just more confusing than CSS Grid properties, which can specify column widths a bit more expressively with the grid-template-columns
prop.
So how does Material UI Grid compare to Flexbox?
Material UI Grid's grid uses Flexbox under the hood. The properties of Flexbox are used as properties of the Grid, so you can control the component as if it were a flexbox. Additionally, Material UI's Grid also provides helpers for spacing, responsive design, and fitting a 12 column layout. To see all the properites of Grid, check out the Grid API or look at the bottom of the Grid source code to see prop types.
Now for the tricky part: using breakpoints as props to the Grid, we can specify how many columns we want that component to take up, for each of the breakpoints. We'll explain this in our responsive design section. First let's look at the breakpoint values.
Material UI Breakpoints
Looking at Material UI's default breakpoints, we can see these are the horizontal screen sizes we will use as props to the Grid component. These are also used elsewhere in Material UI.
xs, extra-small: 0px
sm, small: 600px
md, medium: 900px
lg, large: 1200px
xl, extra-large: 1536px
Material UI Grid Responsive Design
So how do we implement responsive design with Material UI's Grid? As you can see in our Example 4 component to the right.
Observe the comments in the GridItem to get a feel for how this works. We are specifying multiple breakpoints to progressively use 4 columns on desktop, 2 columns on tablet, and 1 column on phones. This level of customization is usually only found on apps like landing pages, where multi-media components need special handling on each device. Most often, you'll find yourself collapsing 2 column layouts on desktop into 1 column layouts on mobile phones.
import React from "react"; import ReactDOM from "react-dom"; import Example1 from "./examples/Example1"; import Example2 from "./examples/Example2"; import Example3 from "./examples/Example3"; import Example4 from "./examples/Example4"; function App() { return ( <div> <Example1 /> <Example2 /> <Example3 /> <Example4 /> </div> ); } export default App;