I need to vertically center text inside grid item, which has minHeigh attribute set, here's short codesandbox example of the problem i'm facing, justify, alignItems, does not seem to be working.
<Grid container className={classes.root}>
<Grid item xs={12}>
<Grid
container
spacing={16}
className={classes.demo}
alignItems={alignItems}
direction={direction}
justify={justify}
>
{[0, 1, 2].map(value => (
<Grid
key={value}
item
style={{
padding: "0 12px",
minHeight: 48,
borderStyle: "solid"
}}
>
{`Cell ${value + 2}`}
</Grid>
))}
</Grid>
</Grid>
When style={{ minHeight: 48 }} is applied to <Grid item /> children of grid item is not being aligned, justify, alignItems, does not have any effect on it.
You need to add two other properties to the element as well.
display: inline-flex;
align-items: center;
If this is the result that you are expecting
<Grid
container
spacing={16}
className={classes.demo}
alignItems={alignItems}
direction={direction}
justify={justify}
>
{[0, 1, 2].map(value => (
<Grid
key={value}
item
style={{
display: "inline-flex", // <--
alignItems: "center", // <--
padding: "0 12px",
minHeight: 48,
borderStyle: "solid"
}}
>
<p>{`Cell ${value + 2}`}</p>
</Grid>
))}
</Grid>
Try vertical-align: middle, and see if that works? Or if the box is a fixed height you could always add margin to the top of it. Hope that helps!
here is how you can do it. Wrap your text inside div and use alignItems:
https://codesandbox.io/s/8nw8v9yv02
Related
SO im using a MUI dialog, and MUI grid together. I took this code directly from the website. The only changes are the box wrapping the dialog, and the slight change in the dialog functions IE 'openDialog' instead of 'open'. No matter what size I change the dialog to, the grid items remain in a three-column layout, when at 'xs' for example, they should stack to 12. I have no idea why, the code looks right to me.
<Box sx={{flexGrow: 1}}>
<Dialog
fullWidth={fullWidth}
maxWidth={maxWidth}
open={openDialog}
onClose={handleCloseDialog}
>
<DialogTitle>Optional sizes</DialogTitle>
<DialogContent>
<DialogContentText>
You can set my maximum width and whether to adapt or not.
</DialogContentText>
<Box
noValidate
component="form"
sx={{
display: 'flex',
flexDirection: 'column',
m: 'auto',
width: 'fit-content',
}}
>
<FormControl sx={{ mt: 2, minWidth: 120 }}>
<InputLabel htmlFor="max-width">maxWidth</InputLabel>
<Select
autoFocus
value={maxWidth}
onChange={handleMaxWidthChange}
label="maxWidth"
inputProps={{
name: 'max-width',
id: 'max-width',
}}
>
<MenuItem value={false}>false</MenuItem>
<MenuItem value="xs">xs</MenuItem>
<MenuItem value="sm">sm</MenuItem>
<MenuItem value="md">md</MenuItem>
<MenuItem value="lg">lg</MenuItem>
<MenuItem value="xl">xl</MenuItem>
</Select>
</FormControl>
<FormControlLabel
sx={{ mt: 1 }}
control={
<Switch checked={fullWidth} onChange={handleFullWidthChange} />
}
label="Full width"
/>
</Box>
<Grid container>
<Box sx={{ flexGrow: 1 }}>
<Grid container spacing={{ xs: 2, md: 3 }}>
{Array.from(Array(6)).map((_, index) => (
<Grid item xs={12} sm={4} md={4} key={index}>
<Item>xs=2</Item>
</Grid>
))}
</Grid>
</Box>
</Grid>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDialog}>Close</Button>
</DialogActions>
</Dialog>
It seems that this is because the Grid is changing layout based on responsive breakpoints of the viewport, instead of the container width. In the posted code, the Grid should change to just 1 column when the window is actually resized below sm, which is 600px.
If the purpose is to mock the responsive sizes, perhaps for a demo, consider to have Grid take value on conditions calculated from the selected maxWidth and fullWidth, instead of the actual viewport width.
Minimized demo on: stackblitz (might need to view in new tab for changes).
<Grid container spacing={{ xs: 2, md: 3 }}>
{Array.from(Array(6)).map((_, index) => {
const responsive = { xs: 12, sm: 4, md: 4, lg: 2, xl: 2 };
const selected = responsive[`${maxWidth}`] || 0;
const mockedResponsive = Object.keys(responsive).reduce(
(acc, cur) =>
!fullWidth
? {
...acc,
[cur]: Math.max(
responsive[cur],
Math.max(selected, responsive["md"])
),
}
: { ...acc, [cur]: Math.max(responsive[cur], selected) },
{}
);
return (
<Grid item key={index} {...mockedResponsive}>
<Typography>xs=2</Typography>
</Grid>
);
})}
</Grid>
I'm using MUI on React and want to make the image responsive and above the text when I use a smaller screen but I want the image on the left and text on the right when I'm using a bigger screen. I'm still new and I don't know how to make it work please help.
<Grid container spacing={1} direction={{ xs: 'column', sm: 'column', md: 'row', lg: 'row', xl: 'row'}} textAlign='center' justifyContent='center' alignItems='center'>
<Grid item xs={9} s={7} md={7} lg={7}>
<Box fontSize={21}>
<Parallax speed={10}>
<Box p={6} className='aboutmebox' id='aboutme'>
<p data-aos="fade-left"> **description here** </p>
</Box>
</Parallax>
</Box>
</Grid>
<Grid item xs={3} md={5} lg={5} display='flex' justifyContent='center'>
<img src='./images/me.jpg' height='60%' width='60%'
data-aos="fade-up"
data-aos-duration="8000"
data-aos-offset="350"
data-aos-anchor-placement="center-bottom"
/>
</Grid>
</Grid>
I tried using
direction={{ xs: 'column', sm: 'column', md: 'row', lg: 'row', xl: 'row'}}
but all it does is put the image on the bottom when the screen is xs or sm.
I also tried typing the image first before the text but I want the image on the left side when i'm using a bigger screen.
When using mui Stack I get weird side effect of geting all the background shapes of Skeleton Avatar and background area smeared to oval|elipsoid shapes. I tried setting equal width and height for Avatar but id does not help.
How can I fix it throguh sx mui component property or css?
code fragment
<Box
noValidate autoComplete="off"
sx={{ marginLeft: '15%','& .MuiTextField-root': { m: 2, width: '25ch' }}}>
<div>
<form onSubmit={onSubmit} >
{formFields.map((form, index) => {
return (
<Fade in={true} sx = {{width: '95%'}} {...{ timeout: 500 }}>
<Stack direction="row" borderRadius="0" spacing={2} key={index} style ={{marginLeft: '-50px', }}>
{form.img? <Avatar alt="release img" src={form.img} sx={{ width: 56, height: 56 }} /> : <Skeleton animation={false} variant ='circular'> <Avatar sx={{ width: 56, height: 56}} /> </Skeleton>}
<TextField {/* ... */}/>
<IconButton onClick={() => removeFields(index)}><DeleteIcon /</IconButton>
</Stack>
</Fade>
)
})}
</form>
<IconButton onClick={addFields} color={'warning'}> <AddCircleOutlineOutlinedIcon /></IconButton>
<br></br><br></br>
<Button onClick={onSubmit} color={'warning'} variant="contained" endIcon= {<SendIcon/>} > Search links </Button>
Normally, the default value of align-items for flex items will be stretch, that's why you see your icon is stretched in the cross axis
The solution is simple, set alignItems prop in Stack to a different value rather than normal/stretch. Here I use center
<Stack
direction="row"
borderRadius="0"
spacing={2}
alignItems="center" // this line
style={{ marginLeft: "-50px" }}
>
Demo
References
CSS align-items
PostsList component renders list of posts, I want to make it such that when clicked over the div item of a post it gets redirected to that specific post's link
const PostsListView = ({ posts, setError, isloggedin }) => {
const [redirectCreatePost, setRedirectCreatePost] = React.useState(false)
if (redirectCreatePost) return (<Navigate to='createPost' />)
return (
<Grid container
align="center"
alignItems="center"
justify="center"
direction="column"
>
{
posts.map(({ category, username, postHeading, createdAt, postid }) => {
return (
<Link to={`post/${postid}`} style={{ textDecoration: 'none', color: 'black' }}>
<Grid
key={postid}
item container
alignItems="center"
style={{
width: 600,
borderRadius: 10,
margin: 5,
backgroundColor: '#D3D3D3'
}}>
<Grid container direction="column">
<Grid item container justify="flex-end">
<Grid item style={{ marginTop: 5, marginLeft: 20 }}> <b>{`c/${category}`}</b> </Grid>
<Grid item style={{ marginTop: 5, marginLeft: 5 }}> {` posted by u/${username} ${getTime(createdAt)}`} </Grid>
</Grid>
</Grid>
<Grid item container alignItems="center" align="left">
<Typography variant="h6" style={{ width: 600, marginLeft: 20, marginRight: 20 }}>{postHeading}</Typography>
</Grid>
</Grid>
</Link>
)
})
}
</Grid>
)
}
Although this seems to create an <a> tag around the grid item <div> in the DOM it is not clickable. I have tried giving the <Link> as component prop to the Grid item and yet no luck. Weirdly enough, it works fine when I replace the <Link> with <a>, but on doing so on clicking the link it refreshes the entire page losing all the state of the App. Appreciate any help. Thanks!
I'm having a very difficult time trying to achieve something simple with the Grid Component from MaterialUI. Specifically, I'd like to align one item to the left, and another to the right on one layout row.
I've searched extensively, and have not found any solutions that work. I've tried many suggestions, including the use of justifyContent and alignContent within a Grid component, and within JSS, and the flex: 1 technique of 'pushing' content.
Relevant Code Snippets
Trying to put the <Typography> element on the left, and the <FormGroup> on the right:
<Container>
<Grid container spacing={3}>
<Grid className={classes.rowLayout}>
// Goal is to align this to the LEFT
<Grid item xs={6}>
<Typography variant="h6" gutterBottom>Some Text</Typography>
</Grid>
// Goal is to align this to the RIGHT
<Grid item xs={3}>
<FormGroup>
// Simple `Switch` button goes here
</FormGroup>
</Grid>
</Grid>
</Grid>
</Container>
MaterialUI JSS styling:
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
width: '100%'
},
rowLayout: {
display: 'flex',
alignItems: 'baseline'
},
}));
I'm also finding that, generally speaking, this is requiring the use of many Grid components, and I'd love to write cleaner code if possible.
Do you have any tips or fixes to this problem?
Thanks a million,
Davis
I'm using this at the moment and it works well to align one to the far left, and one to the far right.
Inspired from: How to align flexbox columns left and right?
const useStyles = makeStyles((theme) => ({
right: {
marginLeft: 'auto'
}
}));
<Grid container alignItems="center">
<Grid>
<Typography variant="h4" component="h4">Left</Typography>
</Grid>
<Grid className={classes.right}>
<Button variant="contained" color="primary">Right</Button>
</Grid>
</Grid>
I used a different approach to list one grid item to right. Similar approach can be use to show grid items to right and one at left.
<Grid container>
<Grid item>Left</Grid>
<Grid item xs>
<Grid container direction="row-reverse">
<Grid item>Right</Grid>
</Grid>
</Grid>
</Grid>
I think the best option here is to use flex like this:
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
width: '100%'
},
rowLayout: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center' // To be vertically aligned
},
}));
As a second choice (and for me the best since you are using Material UI at its fullest expression which if you are using it, it's the best thing to do. Use the library as much as you can) you could do something like this:
<Container>
<Grid container spacing={3}>
<Grid container direction="row" justify="space-between" alignItems="center">
// Goal is to align this to the LEFT
<Grid item xs={6}>
<Typography variant="h6" gutterBottom>Some Text</Typography>
</Grid>
// Goal is to align this to the RIGHT
<Grid item xs={3}>
<FormGroup>
// Simple `Switch` button goes here
</FormGroup>
</Grid>
</Grid>
</Grid>
</Container>
I have solved a similar issue using justifyContent on each of the Grid items.
<Container>
<Grid container spacing={3} alignItems="baseline">
<Grid item xs={6} sx={{
justifyContent: "flex-start"
}}>
<Typography variant="h6" gutterBottom>Some Text</Typography>
</Grid>
<Grid item xs={3} sx={{
display: "flex",
justifyContent: "flex-end"
}}>
<FormGroup>
<Typography variant="h6" gutterBottom>Some Switch</Typography>
</FormGroup>
</Grid>
</Grid>
</Container>
This page gives you a really good visually interpretation of how flex works: https://css-tricks.com/snippets/css/a-guide-to-flexbox/