Foreword
This layout system is heavily based on material-ui Grid component. Which in turn is based on Material Design Responsive UI grid layout system.
Below is a modified version of above linked documentation, to fit our minimal grid and its functionality.
Grid
Responsive layout grid that adapts to screen size and orientation, ensuring consistency across layouts.
The grid creates visual consistency between layouts while allowing flexibility across a wide variety of designs. Material Design’s responsive UI is based on a 12-column grid layout.
How it works
The grid system is implemented with the Grid component:
- It uses CSS’s Flexible Box module for high flexibility.
- There are two types of layout: containers and items.
- Item widths are set in percentages, so they’re always fluid and sized relative to their parent element.
- Items have padding to create the spacing between individual items.
- There are six grid breakpoints: xs, sm, md, lg, xl, and xxl.
- Integer values can be given to each breakpoint, indicating how many of the 12 available columns are occupied by the component when the viewport width satisfies the breakpoint.
If you are new to or unfamiliar with flexbox, we encourage you to read this CSS-Tricks flexbox guide.
Fluid grids
Fluid grids use columns that scale and resize content. A fluid grid’s layout can use breakpoints to determine if the layout needs to change dramatically.
Basic grid
Column widths are integer values between 1 and 12; they apply at any breakpoint and indicate how many columns are occupied by the component.
A value given to a breakpoint applies to all the other breakpoints wider than it (unless overridden, as you can read later in this page). For example, xs={12} sizes a component to occupy the whole viewport width regardless of its size.
Grid with multiple breakpoints
Components may have multiple widths defined, causing the layout to change at the defined breakpoint. Width values given to larger breakpoints override those given to smaller breakpoints.
For example, xs={12} sm={6} sizes a component to occupy half of the viewport width (6 columns) when viewport width is 576 or more pixels. For smaller viewports, the component fills all 12 available columns.
Spacing
To control space between children, use the spacing prop. Spacing can also be made responsive by providing an object with breakpoint values.
Basic spacing```tsx
Responsive spacing
<Grid container spacing={{ xs: 'md', sm: 'lg', md: 'xl' }}>
<Grid>Item 1</Grid>
<Grid>Item 2</Grid>
</Grid>Alignment
There are two ways to control alignment of children in a container - items and justify. These correlate with the css properties align-items and justify-content and can have the same values. See examples and docs here.
Note that these values can also be responsive, just like Spacing.
Basic alignment
<Grid container items="center" justify="center">
<Grid>Item 1</Grid>
<Grid>Item 2</Grid>
</Grid>Responsive alignment
<Grid container items={{ xs: 'center', sm: 'flex-start' }} justify={{ xs: 'center', sm: 'flex-end' }}>
<Grid>Item 1</Grid>
<Grid>Item 2</Grid>
</Grid>Nested Grid
The container and item props are two independent booleans; they can be combined to allow a Grid component to be both a flex container and child.
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.
https://www.w3.org/TR/css-flexbox-1/#box-model
Example of Nested Grid
To nest grids, you can use the container and item props together. This is useful when you want a grid item to also act as a container for other grid items.
For example, the following code:
tsx
<Grid container>
<Grid item>
<Grid container>
<Grid item>
<p>Content 1</p>
</Grid>
<Grid item>
<p>Content 2</p>
</Grid>
</Grid>
</Grid>
</Grid>can be simplified using the shorthand:
<Grid container>
<Grid item container>
<Grid item>
<p>Content 1</p>
</Grid>
<Grid item>
<p>Content 2</p>
</Grid>
</Grid>
</Grid>When to use container and item
container: Use this prop to set spacing or direction on its children. It makes the element a flex container.item: Use this prop to make the element a flex item within a container.
A container by default takes up 100% width. To avoid this, you can use the shorthand <Grid item container> instead of nesting <Grid item> and <Grid container>.
This shorthand tells the container that it is also an item in another container, preventing it from taking up the full width.
Practical Example
A column with a title and a row with two columns
<Grid container direction="column">
<Grid item>
<p>Title</p>
</Grid>
<Grid item container direction="row">
<Grid item>
<p>Content 1</p>
</Grid>
<Grid item>
<p>Content 2</p>
</Grid>
</Grid>
</Grid>A row with difference in spacing
<Grid container direction="row" spacing="lg">
<Grid item container spacing="md">
<Grid item>
<p>Content 1</p>
</Grid>
<Grid item>
<p>Content 2</p>
</Grid>
</Grid>
<Grid item container spacing="lg">
<Grid item>
<p>Content 3</p>
</Grid>
<Grid item>
<p>Content 4</p>
</Grid>
</Grid>
</Grid>Limitations
white-space: nowrap
The initial setting on flex items is min-width: auto.
This causes a positioning conflict when children use white-space: nowrap;.
You can reproduce the issue with:
<Grid item xs>
<Typography nowrap>In order for the item to stay within the container you need to set min-width: 0.
<Grid xs style={{ minWidth: 0 }}>
<Typography nowrap>direction: column
The xs, sm, md, lg, and xl props are not supported within direction="column" containers.
They define the number of grids the component will use for a given breakpoint. They are intended to control width using flex-basis in row containers but they will impact height in column containers.
If used, these props may have undesirable effects on the height of the Grid item elements.