I am trying to understand Material-UI#next grid layout system.
My goal is to have two papers that expand through the whole width screen and break whenever the screen gets smaller to just one paper. The documentation has the following code snippet:
<Container>
<Grid container spacing={24}>
<Grid item xs={12}>
<Paper>xs=12</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper>xs=6 sm=3</Paper>
</Grid>
</Grid>
</Container>
This results in the following:
I then modified the code to try to achieve my goal of just two papers, as this:
<Container>
<Grid container spacing={24}>
<Grid item xs={12} sm={6}>
<Paper>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper>xs=12 sm=6</Paper>
</Grid>
</Grid>
</Container>
But as you can see, this results into two papers which are not taking the whole screen:
Can someone point me to a working example snippet that allows me to have two elements that take the full width?
I suspect the Container component is causing you problems. Since you haven't linked its implementation, see below for a working example of what you want.
Since Material uses flexbox they make use of property flexGrow
The flex-grow CSS property specifies the flex grow factor of a flex item. It specifies what amount of space inside the flex container the item should take up. The flex grow factor of a flex item is relative to the size of the other children in the flex-container.
This is the property that governs the growth of elements in the grid.
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Paper from 'material-ui/Paper';
import Grid from 'material-ui/Grid';
const styles = theme => ({
root: {
flexGrow: 1,
},
paper: {
padding: theme.spacing.unit * 2,
textAlign: 'center',
color: theme.palette.text.secondary,
},
});
function CenteredGrid(props) {
const { classes } = props;
return (
<div className={classes.root}>
<Grid container spacing={24}>
<Grid item xs={12} sm={6}>
<Paper>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper>xs=12 sm=6</Paper>
</Grid>
</Grid>
</div>
);
}
CenteredGrid.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(CenteredGrid);
Best practice is to test out all break points and specify the allocation of space for each screen width.
<Grid item xs={12} sm={12} md={12} lg={6} xl={4}>
</Grid>
xs, extra small 0px
sm, small: 600px
md, medium: 960px
lg, large: 1280px.
xl,extra-large: 1920px
https://material-ui.com/customization/breakpoints/
xs Defines the number of grids the component is going to use. It's applied for all the screen sizes with the lowest priority.
sm Defines the number of grids the component is going to use. It's applied for the sm breakpoint and wider screens if not overridden.
md Defines the number of grids the component is going to use. It's applied for the md breakpoint and wider screens if not overridden.
(and so forth)
more here: https://material-ui.com/api/grid/
For those using Material UI with styled-components, here's how I was able to get the grid items to grow correctly:
import GridBase from "#material-ui/core/Grid";
const Grid = styled(GridBase)`
.MuiGrid-root {
flex-grow: 1;
}
`
Now you can use Grid normally in your components.
I know this is old question , but just want to share.
The problem from your code is spacing={24}
based on documentation Spacing . By default, the spacing between two grid items follows a linear function: output(spacing) = spacing * 8px
e.g. spacing={24} creates a 192px wide gap. so at the end , the space available for the content very small.
<Grid container spacing={2}> // usually 2 or 3 is quite enough for me
<Grid item xs={12} sm={6}>
<Paper>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper>xs=12 sm=6</Paper>
</Grid>
</Grid>
I was also experiencing this issue. What solved it for me is using the "sx" property to make the width of the parent grid = 100%. See code below:
<Box sx={{ width: '100%' }}>
<Button variant="contained" fullWidth> myButton </Button>
</Box>
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>
Here's what I am able to create
My UI
And here is what I want to achieve:
The aspiration
Here's my code:
<Grid container spacing={3}>
<Grid item md={4} xs={15}></Grid>
<Grid item md={4} xs={15}></Grid>
<Grid item md={4} xs={15}></Grid>
<Grid item md={3} xs={15}><TrashIcon> <AddIcon></Grid>
</Grid>
Additional (Edited)
How do I align the grid fields in the bottom to the ones on top rows?
new confusion but have a limit on questions per hour
You can use auto-layout feature of the Grid:
The Auto-layout makes the items equitably share the available space.
That also means you can set the width of one item and the others will
automatically resize around it.
<Grid container spacing={3}>
<Grid item md xs={12}>
<input style={{ width: "100%" }} />
</Grid>
<Grid item md xs={12}>
<input style={{ width: "100%" }} />
</Grid>
<Grid item md xs={12}>
<input style={{ width: "100%" }} />
</Grid>
<Grid item md="auto" xs={12}>
<TrashIcon /> <AddIcon />
</Grid>
</Grid>
Working example
I want to bring these grid items to the same height, but not to stretch them.
This is what it looks like:
This is how I want it:
But I can only do that by manually setting the image width therefore it's not responsive. The users are able to replace this image so setting fixed dimensions is not an option. Any help is appreciated. Here is the minimum code needed to reproduce (I have removed the content within the card to keep the code minimal):
Note: I have used material-ui v4
<Grid container spacing={3}>
<Grid item lg={12} md={12} sm={12} xs={12}>
<Grid container spacing={3} className="mb-3">
<Grid item xs={12} md={3}>
<Card
className="justify-between items-center p-sm-24 bg-paper dashboard-card"
elevation={6}
>
</Card>
</Grid>
<Grid item xs={12} md={3}>
<Card
className="justify-between items-center p-sm-24 bg-paper dashboard-card"
elevation={6}
>
</Card>
</Grid>
<Grid item xs={12} md={6}>
<Card className="bg-paper" elevation={6}>
<CardContent className="flex justify-center">
<img
src={this.state.logo}
alt="logo"
style={{ width: "100%" }}
/>
</CardContent>
</Card>
</Grid>
</Grid>
</Grid>
</Grid>
I'm not sure if this is the best way but it worked for me. So I'm answering my own question.
Instead of using an image tag, I used the CardMedia component which allows to set the height to match the other cards and it is also responsive.
you might want to display a video or a responsive image. Use the component prop for these use cases
<CardMedia
component="img"
alt="green iguana"
height="140"
image="/static/images/cards/contemplative-reptile.jpg"
/>
More info: https://mui.com/components/cards/#media
I want to align material-ui icon with text such that the icon's lowest drawn point starts exactly at baseline. We're using Material-UI Grid layout.
The problem is: if I allow the icon to align to 'baseline', it is too high. If I do alignSelf: 'center', it is too low. At this point, I'd be ok with some way of absolute positioning the icon to match text baseline, but I don't know if that's possible with flexbox.
<Grid container justify="space-between" xs={6}>
<Grid item>
<Button variant="outlined">Cancel</Button>
</Grid>
<Grid item>
<Grid container alignItems="baseline">
<Grid item>
<Grid container alignItems="baseline">
<Grid item style={{ alignSelf: "center" }}>
<Done />
</Grid>
<Grid item>
<Typography>Done!</Typography>
</Grid>
</Grid>
</Grid>
<Grid item>
<Button variant="outlined">Submit</Button>
</Grid>
</Grid>
</Grid>
</Grid>
</div>
As you can see, the icon is rendered below the baseline, while the text is properly aligned:
You can add a custom relative positioning to manually adjust the position of the checkmark, something like this:
<Done style={{ position: "relative", top: "-1px"}} />
You can change the top property until the checkmark is aligned. If you remove the alignSelf property, you might need to use top: "5px" instead.
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.