how to align a grid item center in material-ui in react? - css

I have a grid element with maxWidth so that it has horizontal margin when displayed in a big screen. I want the grid element to be centered and a long paragraph should be aligned to the left side. How would you do? I'm using MUI v5. Thank you.
<Box
style={{
backgroundColor:"rgb(234, 237, 242)"
}}
>
<Grid container alignItems='center' justifyContent='center' maxWidth='md'>
<Grid item xs={12} md={12} justifyContent="center">
<Typography align="center" variant="h4" style={{ fontWeight: 800 }} sx={{mb:4}}>
Nice title
</Typography>
<Typography sx={{ px: 4 }} paragraph>very very long line. very very long line. very very long line. very very long line. very very long line. very very long line. very very long line. very very long line. very very long line. very very long line. very very long line.</Typography>
</Grid>
</Grid>
</Box>

It's simple enough using system properties.
<Box
display="flex"
justifyContent="center"
style={{
backgroundColor:"rgb(234, 237, 242)"
}}
>
...

You can try the following code. I have checked this code it is working perfectly.
import * as React from 'react';
import { styled } from '#mui/material/styles';
import Box from '#mui/material/Box';
import Paper from '#mui/material/Paper';
import Grid from '#mui/material/Grid';
import Typography from '#mui/material/Typography';
const Item = styled(Paper)(({ theme }) => ({
...theme.typography.body2,
padding: theme.spacing(1),
textAlign: 'center',
color: theme.palette.text.secondary,
}));
export default function BasicGrid() {
return (
<Box sx={{ flexGrow: 1, backgroundColor: 'rgb(234, 237, 242)' }}>
<Grid container spacing={2}>
<Grid item xs={12}>
<Item>
<Typography align="center" variant="h4" style={{ fontWeight: 800 }} sx={{ mb: 4 }}>
Hello
</Typography>
<Typography align="center" sx={{ px: 4 }} paragraph>
very very long line
</Typography>
</Item>
</Grid>
</Grid>
</Box>
);
}

Related

MUI: how to align text side by side?

I want the numbers and text to line up side-by-side like this picture.
But there is a margin to the right of that text(MASTER I 406), so the numbers don't come in the right place. Currently I'm using transform: 'translateY()' to force the number into position. In this way, the position of the number is broken when the size of the screen is changed.
Please tell me how to solve this.
https://codesandbox.io/s/still-morning-0q92mh?file=/src/App.js
MUI Grid layout is a very powerful system you can use for your customized UI.
You need one Grid container with 2 Grid items inside.
Your code should be like this:
import { Card, CardContent, Typography, Grid } from "#mui/material";
import RiceBowlIcon from "#mui/icons-material/RiceBowl";
export default function App() {
return (
<Card
sx={{
borderRadius: 7,
marginTop: 3
}}
>
<CardContent>
<Grid container sx={{ alignItems: "center" }}>
<Grid item xs={10}>
<RiceBowlIcon />
<Typography
component="span"
sx={{
fontSize: 20,
fontWeight: 600
}}
>
JohnDoe
</Typography>
<Typography
sx={{
fontSize: 10,
color: "#909090",
ml: 4
}}
>
MASTER I 100
</Typography>
</Grid>
<Grid item xs={2} sx={{ textAlign: "center" }}>
<Typography
sx={{
fontSize: 20,
fontWeight: 540,
mr: 2
}}
>
(+10.00%)
</Typography>
<Typography
component="span"
sx={{
fontSize: 20,
fontWeight: 540
}}
>
10,000
</Typography>
</Grid>
</Grid>
</CardContent>
</Card>
);
}
You can use the Grid system like the solution below:
import { Card, CardContent, Typography, Grid } from "#mui/material";
import RiceBowlIcon from "#mui/icons-material/RiceBowl";
export default function App() {
return (
<Card
sx={{
borderRadius: 7,
marginTop: 3
}}
>
<CardContent>
<Grid container spacing={2}>
<Grid item xs={6}>
<RiceBowlIcon />
<Typography
component="span"
sx={{
fontSize: 20,
marginLeft: 1,
fontWeight: 600
}}
>
JohnDoe
</Typography>
<Typography
sx={{
fontSize: 10,
ml: 4,
color: "#909090",
// width: "20%" // You don't need to specify the width as it wil break the text in two lines
}}
>
MASTER I 100
</Typography>
</Grid>
<Grid item xs={6}>
<Typography
sx={{
float: "right",
fontSize: 20,
fontWeight: 540
}}
>
(+10.00%)
</Typography>
<Typography
component="span"
sx={{
float: "right",
fontSize: 20,
fontWeight: 540
}}
>
10,000
</Typography>
</Grid>
</Grid>
</CardContent>
</Card>
);
}
To explain a little more, you can create a Grid with two Grid Items. In the left Grid item you have the icon with the texts so it will work as a container and on the right one, the numbers '10.000'. With that way the content of the left Grid shouldn't affect the content of the right one.
Here is the updated sandbox based on your code.
<ListItemText
primary={
<div>
<span>{comment.UserName}</span>
<span style={{ float: "right" }}>10.10.2022</span>
</div>
}
secondary={comment.Comment}
/>

Material UI Paper won't render the correct background color?

I have seen numerous methods in other stackoverflow questions related to how to change the background color of a Material UI Paper component. However, I'm having a strange issue in that the color will change, but not to the correct color?
Here I am trying to make some grids that I will place widgets in. The background is a Paper component which has the same issue. All the paper components rendered do not match the color requested in the code. I have tried changing it with makeStyles() as well as directly with the style attribute:
const useStyles = makeStyles((theme) => ({
widgetPaper: {
backgroundColor: "#233044",
borderRadius: 25
},
}));
...
<Grid container spacing={0} sx={{ mt: "auto", ml: 1, width: "auto" }}>
<Grid
item
container
spacing={0}
xs={3}
align="center"
sx={{ ml: `${props.dw}px`, mt: 2 }}
>
<Grid item xs={6} align="left">
<Paper
sx={{ height: "95%", width: "99%" }}
className={classes.widgetPaper}
>
<Typography> Test1 </Typography>
</Paper>
</Grid>
<Grid item xs={6} align="right">
<Paper
style={{ backgroundColor: "#233044" }}
sx={{ height: "95%", width: "99%", borderRadius: 1 }}
>
<Typography> Test </Typography>
</Paper>
</Grid>
<Grid item xs={6} align="left">
<Paper
style={{ backgroundColor: "#233044" }}
sx={{ height: "95%", width: "99%", borderRadius: 1 }}
>
<Typography> Test </Typography>
</Paper>
</Grid>
<Grid item xs={6} align="right">
<Paper
style={{ backgroundColor: "#233044" }}
sx={{ height: "95%", width: "99%", borderRadius: 1 }}
>
<Typography> Test </Typography>
</Paper>
</Grid>
</Grid>
<Grid
item
xs={7}
align="left"
sx={{ mt: 2, ml: 1, borderRadius: 1 }}
style={{ backgroundColor: "#233044" }}
></Grid>
</Grid>
The layout renders as expected, however the colors of the paper elements are wrong. I know it is the color of the paper elements specifically, because the last grid item doesn't have Paper and it's color is correct:
In case it is relevant; at the App.js level I am using:
const darkTheme = createTheme({ palette: { mode: 'dark' } });
What is it about Paper elements specifically which is causing this? Am I making a really obvious mistake?
Thank you.

React Material UI responsive Grid with Card

I am trying to create a responsive grid layout using cards that should have the same height including an image. I am using React and Material-UI.
I am fiddling around now for hours and cannot come up with a solution. The "flex" part seems super unintuitive to me. Please help.
It is a very small and simple code piece:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
cardGrid: {
flexGrow: 1,
paddingTop: 16,
},
card: {
flex: 1,
height: '100%',
backgroundColor: 'red',
},
cardActionArea: {
flex: 1,
height: '100%',
backgroundColor: 'green',
},
cardMedia: {
height: '0',
paddingTop: '56.25%', // 16:9
},
cardContent: {
flex: 1,
backgroundColor: blue[600],
},
cardContentTitle: {
flex: 1,
backgroundColor: blue[400],
},
cardContentRating: {
backgroundColor: blue[300],
},
cardContentDistance: {
backgroundColor: blue[200],
}
}),
);
// ...
<Container className={classes.cardGrid} maxWidth="xl">
<Grid
container
direction="row"
justify="space-evenly"
alignItems="stretch"
spacing={2}
>
{
dataList.map(data => (
<Grid item
key={`GridItem-${data.id}`} xs={12} sm={6} md={4} lg={2} xl={1}
>
<Card className={classes.card}
onClick={handleCardClick}
key={`OverviewItem-${data.id}`}
>
<CardActionArea className={classes.cardActionArea}>
{
data.previewURL &&
<CardMedia
className={classes.cardMedia}
image={data.previewURL}
title={data.title}
/>
}
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5" className={classes.cardContentTitle}>
{data.title}
</Typography>
<Typography className={classes.cardContentRating}>
Some text
</Typography>
<Typography className={classes.cardContentDistance}>
Some other text
</Typography>
</CardContent>
</CardActionArea>
</Card>
</Grid>
))
}
</Grid>
</Container>
What I am trying to achieve:
Image should be at the top of each card
"Some text" and "Some other text" should get moved to the bottom
It seems like I have to write "flex:1" and "height:'100%'" multiple times when going down the tree and at some point it breaks completely like in following screenshot:
With the code snippet from above it looks like this:
What is the magic to simply expand the childs of a Grid Item to its maximum height and to still be able to align them as I want.
E.g. the entire card should stretch over the area of the Grid Item and the title part below the image should expand to move the image to the top and "Some text" and "Some other text" to the bottom.
Any hints/ideas are appreciated!
I was able to achieve what I wanted without a Card and without the image. But making the tree bigger and therefore the nesting deeper, breaks everything and I don't understand why.
Here is the simple snippet and the result:
<Container className={classes.cardGrid} maxWidth="xl">
<Grid
container
direction="row"
justify="space-evenly"
alignItems="stretch"
spacing={2}
>
{
toiletOverviews.map(data => (
<Grid item
key={`GridItem-${data.id}`} xs={12} sm={6} md={4} lg={2} xl={1}
>
<Box
display="flex"
flexDirection="column"
style={{height: '100%', backgroundColor: 'purple'}}
>
<Typography
variant="h5"
style={{flex:1, backgroundColor: blue[800]}}
>
{data.title}
</Typography>
<Typography
style={{backgroundColor: blue[600]}}
>
Some text
</Typography>
<Typography
style={{backgroundColor: blue[400]}}
>
Some other text
</Typography>
</Box>
</Grid>
))
}
</Grid>
</Container>
I figured it out! The important part that I did not know is that display:"flex" is only applied to the current element and its direct children. For childrens of its childrens it will not be applied.
The solution now is to correctly apply it to all necessary elements. The sideeffect was that the image was no longer displayed. It had a width/height of zero. The fix here is to add width:"100%" to the CardMedia element.

How do you align a title to the left-most object within a Grid with justify="space-between" in Material UI?

I have a Grid container containing four Grid items. The first Grid item is full width and contains a title. The other three Grid items contain avatars. I want to align the avatars to the right of the page and I would like the title to align with the left-most avatar. However, it is currently further to the left than the avatars. The other issue is that the number of avatars can vary (likely between 1 and 3 but possibly more). How can I ensure the left-most avatar and title align?
Here is the result I am getting:
And here is what I would like to achieve:
Here is my code:
import React from "react";
import { Grid, makeStyles, Typography, Divider, Avatar } from "#material-ui/core";
const useStyles = makeStyles((theme) => ({
header: {
paddingTop: theme.spacing(3),
paddingBottom: theme.spacing(3),
flexGrow: 1,
},
}));
const Header = ({ padding }) => {
const classes = useStyles();
return (
<>
<Grid
container
item
direction="row"
justify="space-between"
align-items="center"
xs={12}
className={`${padding} ${classes.header}`}
>
{/*Page title and description*/}
<Grid item xs>
<Typography variant="h1" component="h1">
Page Title
</Typography>
<Typography variant="body1">
This is a description of what the page is about
</Typography>
</Grid>
{/*People container*/}
<Grid item xs className={classes.smeSection} alignItems="bottom">
{/*People profiles*/}
<Grid container item justify="flex-end" alignItems="bottom">
<Grid item xs={12}>
<Typography variant="h5">People</Typography>
</Grid>
<Grid item>
<Avatar/>
</Grid>
<Grid item>
<Avatar/>
</Grid>
<Grid item>
<Avatar />
</Grid>
</Grid>
</Grid>
</Grid>
<Divider />
</>
);
};
export default Header;
Many thanks!
Katie
By continuously nesting flexbox components it is very easy to make mistakes and get lost in the code.
If it was that I understood your requirement well, here is the code with which I managed to get that layout:
import React from "react";
import { Grid, Typography, Divider, Avatar } from "#material-ui/core";
const Header = () => {
return (
<>
<Grid container direction="row" align-items="center">
{/*Page title and description*/}
<Grid item xs={9}>
<Typography variant="h1" component="h1">
Page Title
</Typography>
<Typography variant="body1">
This is a description of what the page is about
</Typography>
</Grid>
{/*People container*/}
<Grid container item xs={3}>
{/*People profiles*/}
<Grid container item>
<Grid item>
<Typography variant="h5">People</Typography>
</Grid>
<Grid container>
<Grid item>
<Avatar />
</Grid>
<Grid item>
<Avatar />
</Grid>
<Grid item>
<Avatar />
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Divider />
</>
);
};
export default Header;
A grid can be "container", "item" or both. The most important changes I made to your code was to make all grid parents "containers" and add a width size to the first two grid items (xs={9} and xs={3}).
Here's a CodeSandbox with a working example: https://codesandbox.io/s/upbeat-banzai-0gp10?file=/src/Header.js:0-1119
In my opinion, I think a better alternative is to use a combination of Grid (for general layout) and Flexbox to align the nested elements.
UPDATE:
With the new data you added as a reference I made the layout again using flexbox.
import React from "react";
import {
Typography,
makeStyles,
Avatar,
Card,
CardHeader,
Divider
} from "#material-ui/core";
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
justifyContent: "space-between"
},
usersHeader: {
marginLeft: theme.spacing(2)
},
personCards: {
display: "flex"
}
}));
const Header = () => {
const classes = useStyles();
return (
<>
<div className={classes.root}>
<div>
<Typography variant="h3" component="h1">
Page Title
</Typography>
<Typography variant="body1">
This is a description of what the page is about
</Typography>
</div>
<div>
<Typography className={classes.usersHeader} variant="subtitle">
Users
</Typography>
<div className={classes.personCards}>
<Card elevation={0}>
<CardHeader
avatar={<Avatar />}
title="Person name"
subheader="Person role"
/>
</Card>
<Card elevation={0}>
<CardHeader
avatar={<Avatar />}
title="Person name"
subheader="Person role"
/>
</Card>
<Card elevation={0}>
<CardHeader
avatar={<Avatar />}
title="Person name"
subheader="Person role"
/>
</Card>
</div>
</div>
</div>
<Divider />
</>
);
};
export default Header;
CodeSandbox reproduction: https://codesandbox.io/s/condescending-cartwright-grxhj?file=/src/Header.js

Material UI - React - Place Grid items in a column

I need some help with positioning my Grid Items while using Material UI.
Codesandbox is where I am so far (roughly).
And my question is quite simple - how do I get 2 & 3 to go to the right of 1? I kinda do it but there are all those weird spaces to the left and down that, I cannot figure out how to deal with.
That's the end result I'm after:
Thank you.
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Typography from "#material-ui/core/Typography";
import Paper from "#material-ui/core/Paper";
import Divider from "#material-ui/core/Divider";
import Grid from "#material-ui/core/Grid";
const useStyles = makeStyles(theme => ({
container: {
// display: "grid",
gridTemplateColumns: "repeat(12, 1fr)",
gridGap: theme.spacing(3)
},
paper: {
padding: theme.spacing(1),
textAlign: "center",
color: theme.palette.text.secondary,
whiteSpace: "nowrap",
marginBottom: theme.spacing(1)
},
w: {
height: "100px"
},
divider: {
margin: theme.spacing(2, 0)
}
}));
export default function CSSGrid() {
const classes = useStyles();
return (
<div>
<Grid container spacing={3}>
<Grid container direction="column">
<Grid item xs={8}>
<Paper className={classes.paper + " " + classes.w}>xs=8</Paper>
</Grid>
</Grid>
<Grid
container
style={{ display: "table", height: "100%" }}
direction="row"
>
<Grid item xs={4}>
<Paper className={classes.paper}>xs=4</Paper>
</Grid>
<Grid item xs={4}>
<Paper className={classes.paper}>xs=4</Paper>
</Grid>
</Grid>
</Grid>
<Divider className={classes.divider} />
</div>
);
}
Some notice points from your code
use one container for one grid field structure
remove direction setting direction="column"
xs sum needs to lower or equal to 12 if you want to set them in one row.
Kindly check the material-ui grid document for better understanding
<Grid container spacing={3}>
<Grid item xs={8}>
<Paper className={classes.paper + " " + classes.w}>xs=8</Paper>
</Grid>
<Grid item xs={2}>
<Paper className={classes.paper}>xs=2</Paper>
</Grid>
<Grid item xs={2}>
<Paper className={classes.paper}>xs=2</Paper>
</Grid>
</Grid>
<Divider className={classes.divider} />
Update:
<Grid container spacing={3}>
<Grid item xs={8}>
<Paper className={classes.paper + " " + classes.w}>xs=8</Paper>
</Grid>
<Grid item xs={4}>
<Grid container>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=4</Paper>
</Grid>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=4</Paper>
</Grid>
</Grid>
</Grid>
</Grid>
<Divider className={classes.divider} />
Try it online:

Resources