I am using MUI Grid structure in ReactJs to display 5 columns like this:
In smaller screens the columns are moving in the next row. But In smaller screens I also want all the columns to show in one row only and I can access other columns by scrolling horizontally.
<Grid
container
spacing={2}
style={{
maxHeight: "100vh",
overflowY: "auto",
overflowX: "hidden",
height: "440px",
overflow: "auto",
}}
>
<Grid item xs={2.1}>
{cards.map((card) => <Card props={card} /> )}
</Grid>
</Grid>
Because Grid uses flexbox under the hood. You can simply set the wrap value to nowrap in your Grid container, you can see the full API of Grid component here.
<Grid
container
wrap="nowrap" // --> add this line to disable wrap
sx={{ overflow: "auto" }} // --> add scrollbar when the content inside is overflowed
spacing={8}
>
{...}
</Grid>
Live Demo
The Grid is based on a 12-column grid layout. Therefore xs accepts only the following values:
'auto' | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12.
I would recommend you to place an empty grid with an xs size equal to 1 at the beginning and end. That brings you to a total size of xs equal to 12.
<Grid
container
spacing={2}
style={{
maxHeight: "100vh",
overflowY: "auto",
overflowX: "hidden",
height: "440px",
overflow: "auto",
}}
>
<Grid item xs={1}/>
{cards.map((card) => (
<Grid item xs={2}>
<Card props={card} />
</Grid>
))}
<Grid item xs={1}/>
</Grid>
Related
I've been stuck on this part, and I've been struggling how can I manage to make it row, I tried to make it flexWrap, but it's going down instead of going its side.
<Box sx={{display: {xs: 'flex'},
gap: {xs: '0px', md:'20px',
flexWrap: 'wrap',
alignItems: 'center' }}}
>
{products.map((product) => (
<CardProduct key={product._id} product={product}/>
))}
</Box>
outcome
this is I want to achieve, the first and second product must be align, and then have a gap between or spacing, then the 3rd product will automatically wrap... I tried to call the
flexWrap:'wrap'
but it failed. should I just the height ? or is it because the button is too big?
want to achieve
This is what it looks like when it only have two products
two images
Try using a Grid:
<Grid container spacing={2}>
{products.map((product) => (
<Grid item xs={6} key={product._id}>
<CardProduct product={product} />
</Grid>
))}
</Grid>;
To make 2 columns you can use flex-basis property, flex-basis: 50%; , do remove any padding or margin before.
with flex-basis property you can set any width or get number of columns.
<Box sx={{display: {xs: 'flex'},
gap: {xs: '0px', md:'20px',
flex-basis: '50%',
alignItems: 'center' }}}
>
{products.map((product) => (
<CardProduct key={product._id} product={product}/>
))}
There is on more property in css that helps us to achieve any number of coumns without using flexbox.
.div {
column-count: 2;
}
you can try Grid. Material-UI has a very good and clear example exactly as you want.
link
<Grid container spacing={2}>
<Grid item xs={12}>
<Grid container justifyContent="center" spacing={spacing}>
{[0, 1, 2].map((value) => (
<Grid key={value} item>
<Paper className={classes.paper} />
</Grid>
))}
</Grid>
</Grid>
I am trying to create a grid with a bunch of elements but there seems to be a problem when I add spacing to the elements. Here's a picture with spacing={0} on the Grid container:
Grid container with no spacing
Here's the result when adding spacing :
Grid container with spacing = 3
I am trying to keep the grid the same width as the buttons above (see picture). I tried different solutions but it does not seem to work on my side. Here is my code :
return (
<Grid
sx={{
width: "100vw",
overflowX: "hidden",
padding: { xs: "20px", md: "50px" },
margin: 0,
background: "hsl(0, 0%, 98%)",
}}
container
>
<Grid
sx={{ width: "100%", marginBottom: "30px" }}
item
display="flex"
flexWrap={"wrap"}
justifyContent={"space-between"}
gap={"25px"}
>
<SearchInput />
<FilterMenu />
</Grid>
<Grid container spacing={3} xs={12}>
{countries?.map((country, idx) => (
<Grid item xs={3}>
<CountryCard key={idx} country={country} />
</Grid>
))}
</Grid>
</Grid>
The easiest and correct way in my opinion based on your images, would be to separate your Grid containers. One Grid containing the Search and Filter inputs and another to contain your flags. In this way you can keep a better control of your spacing and use let css customisations in the Grid items. Have a look in this codesandbox where i have left a few comments and let me know it it helps.
Here is the code:
<Grid
container
justify="space-between"
alignItems="flex-start"
direction="column"
xs
spacing={5}
style={{
padding: 10,
}}>
<ParamSelection/>
{
state.selected != -1 && <Grid
container
item
justify="space-between"
alignItems="left"
direction="column"
spacing={5}
style={{width:'350px', marginLeft: '10px'}}>
<DatePickerView/>
}
Inside Param selection again a grid.
<Grid
item
container
justify="flex-start"
alignItems="left"
direction="column"
xs
style={{width: '350px', marginLeft: '10px'}}
>
<Grid item >
<Typography variant="subtitle1" align="left">Select parameter for graph: </Typography>
</Grid>
Currently it's showing like this:
I want select date to be on the same line as select parameter for graph, side by side.
Put both gird-elements in a div and add display:flex to the new-div.
<div class="parent"> <gird>element1</grid><grid>element2</grid>
style:
.parent{display:flex;};
I am designing a page that needs to be rendered in large, medium and small screens responsively. I am using Material ui Grid container and inside that displaying Chips with style={{ marginLeft: 60 }} from second chip onward to keep a distance between first-second,second-third and so on but as soon as my screen size changes, these chips are getting overlapped on each other but no responsive behavior. Below is my code
<Grid container item xs={12}>
<Grid container item xs={11}>
<Grid item xs={2}>
<Chip/>
</Grid>
<Grid item xs={2} style={{ marginLeft: 60 }}>
<Chip/>
</Grid>
<Grid item xs={2} style={{ marginLeft: 60 }}>
<Chip/>
</Grid>
<Grid item xs={2} style={{ marginLeft: 60 }}>
<Chip/>
</Grid>
<Grid item xs={2} style={{ marginLeft: 57 }}>
<Chip/>
</Grid>
</Grid>
</Grid>
How to get my design correct? Please suggest. Thanks..
You're declaring static margin sizes in pixels which will not shrink with the screen size. Either change them to relative sizes (e.g., style={{ marginLeft: '5%' }}), or assign the grids a className property and use media queries in your CSS file to set breakpoints at the required screen sizes.
The latter option will provide you with much more control if responsiveness is a requirement.
I have a problem with the order of stacking of grid items whenever browser shrinks.
This is what I want on the normal desktop screen(lg):
---------------------------------------------
| col 1 | col 2 | col 3 |
---------------------------------------------
But After Shrinking the browser I am getting the following result:
-------------------------
| col 1 |
-------------------------
-------------------------
| col 2 |
-------------------------
-------------------------
| col 3 |
-------------------------
Can I with material ui Grid layout achieve this on a mobile screen:
-------------------------
| col 1 |
-------------------------
-------------------------
| col 3 |
-------------------------
-------------------------
| col 2 |
-------------------------
I have read articles on changing the order of CSS-grids for the same topic but how to achieve this using material-ui Grid layout.
Edit: I have revised the answer for MUI Core v5
<Grid container spacing={16} justify="flex-start">
<Grid item xs={12} sm={6} md={4} lg={4}>
<Paper>
<h1>{1}</h1>
</Paper>
</Grid>
<Grid item xs={12} sm={6} md={4} lg={4} order={{ xs: 3, sm: 2 }}>
<Paper>
<h1>{2}</h1>
</Paper>
</Grid>
<Grid item xs={12} sm={6} md={4} lg={4} order={{ xs: 2, sm: 3 }}>
<Paper>
<h1>{3}</h1>
</Paper>
</Grid>
</Grid>
https://codesandbox.io/s/xvv7o07614?file=/src/GridStacking.js
Extending to Olivier's answer Material-UI heavily uses the CSS flexbox layout within its implementation. As the documentation quotes
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 Grid items are flex items and Grid Container is flexbox container in laymans language. Hence we can use the order property on Grid items to change their relative order of appearance when the Box or Grid Container resizes. So passing the style in the following manner to the grid item should work out
itemStyle: {
order: ${Desired_order_before_Shrinking},
[theme.breakpoints.up(`${DesiredScreenSize}`)]: {
order: ${Desired_order_after_Shrinking},
},
}
Finally doing <Grid item xs={12} md={6} className={this.props.classes.itemStyle}> will reorder that item. Hope it creates better understanding.
UPDATE:
Material UI V5. Thanks to #Adam Cooper's answer below
<Grid container spacing={2}>
<Grid item md={12} lg={4} order={{ md: 1, lg: 1 }}>col 1</Grid>
<Grid item md={12} lg={4} order={{ md: 3, lg: 2 }}>col 2</Grid>
<Grid item md={12} lg={4} order={{ md: 2, lg: 3 }}>col 3</Grid>
</Grid>
With material-ui v5 this can be achieved more elegantly using the order prop together with the new responsive style system:
<Grid container spacing={2}>
<Grid item md={12} lg={4} order={{ md: 1, lg: 1 }}>col 1</Grid>
<Grid item md={12} lg={4} order={{ md: 3, lg: 2 }}>col 2</Grid>
<Grid item md={12} lg={4} order={{ md: 2, lg: 3 }}>col 3</Grid>
</Grid>