I'm making a blog app using React, Material UI and Tailwindcss.
I made a grid of posts, but every postcard has a different height.
The question is: how to make all cards have the same height and all children in the same line?
Like This:
My Code:
Posts.jsx:
function Posts({ posts }) {
return (
<div className="mt-10">
<Container maxWidth="lg">
<Grid
container
rowSpacing={8}
columnSpacing={8}
direction="row"
justifyContent="center"
>
{posts.map((post, index) => (
<Grid key={index} item xs={12} sm={12} md={6} lg={4}>
<Card>
<CardActionArea>
<div className="flex flex-col ">
<CardHeader
avatar={
<Avatar>{post?.username?.substring(0, 1)}</Avatar>
}
title={post?.username}
subheader={"date"}
subheaderTypographyProps={{
color: "primary.dark",
}}
color="primary.main"
/>
<CardMedia
component="img"
height="194"
image={post?.photoURL}
/>
<CardContent>
<Typography variant="h6" color="primary.main">
{post.description}
</Typography>
</CardContent>
<Divider variant="middle" className="bg-[#fcfcfc]" />
<CardActions>
<IconButton>
<MdFavorite className="text-red-500" />
</IconButton>
</CardActions>
</div>
</CardActionArea>
</Card>
</Grid>
))}
</Grid>
</Container>
</div>
);
}
export default Posts;
You could try targeting the root <img> element directly by using the sx property. <CardMedia> would be updated like this:
...
<CardMedia
component="img"
height="194"
image={post?.photoURL}
sx={ {
['&.MuiCardMedia-root.MuiCardMedia-media.MuiCardMedia-img']: {
maxHeight: '194px'
}
} }
/>
...
As for making all children in the same line, you could:
set a maxHeight on the <CardHeader> and <CardContent> components, and
if you do not have control over the character length of the text in the header and content, use overflow: 'hidden', and textOverflow: 'ellipsis' to prevent long text strings from vertically expanding the <CardHeader> and <CardContent> components.
Try adding a fixed height on your tag. Also if the size of the images vary for each card it might cause a difference in the height of the whole card. If it doesn't work, try changing the height on your image to height: '194' to height: '194px'. Maybe this is what is causing an error.
Related
I have a table of contents on the side of my page like so:
<Card>
<CardHeader title={TABLE OF CONTENTS}>
<CardContent>
<List>
<ListItem>General</ListItem>
<ListItem>Dashboard</ListItem>
<ListItem>Tables</ListItem>
<ListItem >Tables2</ListItem>
<ListItem >Statistics</ListItem>
<ListItem >Reports</ListItem>
<ListItem >User Settings</ListItem>
</List>
</CardContent>
</Card>
when clicking on either the first or any of the last three items on the list it scrolls me to them correctly. But any of the items inbetween (from dashbaord to tables2) do not work. This is how my sections are made. The box/div is within a parent div:
<Box>
<Card id="general" >
<CardHeader title={"General"} />
<CardContent> ... </CardContent>
</Card>
<Card id="dashboard" >
<CardHeader title={"Dashboard"} />
<CardContent> ... </CardContent>
</Card>
//...and so on
</Box>
Why are the middle anchors broken?
This post has been resolved
Hi, I'm using Material-UI in my React App, and I want to centre a Grid item that contains a Card and two more Grid items.
Here is the relevant code. The Cards do appear in the middle of the screen, but they aren't centred and it's really, really annoying me.
Screenshot:
Necessary code:
render() {
return (
<Grid container>
<Grid item xs={12}>
<Typography variant="h3" gutterBottom>
My Projects
</Typography>
</Grid>
<Grid item xs={6} justify="center">
<Grid item xs={12}>
<Card>
<CardMedia
component="img"
height="140"
image="https://github.com/dbarnes18/Portfolio/blob/master/assets/images/spotter.png?raw=true"
alt="Spotter"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
Spotter
</Typography>
<Typography variant="body2" color="text.secondary">
Spotter is an easy-to-use Spotify music controller with
functioning room and voting systems.
</Typography>
</CardContent>
<CardActions>
<Button
size="small"
color="primary"
to="/project/spotter"
component={Link}
>
Read More
</Button>
</CardActions>
</Card>
</Grid>
<Grid item xs={12}>
<br />
</Grid>
<Grid item xs={12}>
<Card>
<CardMedia
component="img"
height="140"
image="https://github.com/dbarnes18/Portfolio/blob/master/assets/images/impulse.png?raw=true"
alt="Spotter"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
Impulse
</Typography>
<Typography variant="body2" color="text.secondary">
Impulse is a macOS Virtual/Voice Assistant!{" "}
<i>Impulse is a little buggy and slow.</i>
</Typography>
</CardContent>
<CardActions>
<Button
size="small"
color="primary"
to="/project/impulse"
component={Link}
>
Read More
</Button>
</CardActions>
</Card>
</Grid>
</Grid>
</Grid>
);
}
Some system info:
Google Chrome: 93.0.4577.82 (Official Build) (x86_64)
Revision: e3a25d9b9e2d0b728e045ec87c0aa4942aa46e4e-refs/branch-heads/4577#{#1237}
OS: macOS Version 10.15.7 (Build 19H1417)
JavaScript: V8 9.3.345.19
Thanks!
As you say using material-ui
just add style to your code
material-ui v4.12.3
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles(() => ({
root: {
display: "flex",
justifyContent: "center",
alignItem: "center"
}
}));
and add it to your Grid
export default function App() {
const classes = useStyles();
return (
<Grid container className={classes.root}>
....
)}
check out here
The simpliest answer it's to a div with name of .container and give it width:100% and display:flex;justify-content:center;gap:20px and that's it.
here preview : https://codesandbox.io/s/vigilant-bird-ulpvm?file=/index.html
I have a paper element (div with A4 size), displaying informations enterred by the user (using Context API in Reactjs).
What I want is, in case the paper element is full of text, add another paper and display the remaining informations in it.
this is my code.
<Paper>
<div class="page" data-size="A4">
<Grid container xs={12} direction="column" justify="center" >
<Typography className={classes.title} variant="h5">Experiences </Typography>
<personalInfo.Consumer>
{( {experience} ) => (
experience.map((exp,i) => {
return(
<div key={i}>
<Grid container xs={12} spacing={false}>
<Grid xs={3}>
<Typography className={classes.dates}>
{exp.startdate}-{exp.enddate}<br/>
{exp.city},{exp.country}
</Typography>
</Grid>
<Grid xs={8}>
<Typography >
<h4>{exp.job}</h4>
{exp.employer}
<br/>
{exp.description}
</Typography>
</Grid>
</Grid>
</div>
)})
)}
<personalInfo.Consumer>
</Grid>
</div>
</Paper>```
I want to make a Paper component clickeable. How can I achieve this? I tried setting an id property in the tag like () and then using the DOM to add an event listener but it does not work. I'm stuck and out of ideas on how to add a click to the Paper component.
Please note that Paper is a div so I don't get why I can't add a click event. Thanks.
My code:
<span>
<Grid item xs={12} sm={12} md={6} lg={4} xl={4} spacing={5} key={something}>
<Paper className={classes.paper} onClick={}>
....
</Paper>
</Grid>
</span>
Try wrapping the paper component using IconButton:
<span>
<Grid item xs={12} sm={12} md={6} lg={4} xl={4} spacing={5} key={something}>
<IconButton>
<Paper className={classes.paper} onClick={}>
....
</Paper>
</IconButton>
</Grid>
</span>
As #TigranPetrosyan said, they're not intended to be displayed like buttons, but you can use Card components which look similar to Paper, but can be clickable.
<span>
<Grid item xs={12} sm={12} md={6} lg={4} xl={4} spacing={5} key={something}>
<Card sx={{ maxWidth: 345 }}>
<CardActionArea>
<CardContent onClick={() => console.log('Clicked!')}>
<Typography gutterBottom variant="h5" component="div">
Lizard
</Typography>
<Typography variant="body2" color="text.secondary">
Lizards are a widespread group of squamate reptiles, with over 6,000
species, ranging across all continents except Antarctica
</Typography>
</CardContent>
</CardActionArea>
</Card>
</Grid>
</span>
Example taken from the V5 docs, I just added the onClick event listener.
I'm using the menu/menu item from material ui. It seems to have an issue if I try to render it based on a condition. Refer below...
const AddSelectItemButton = () => {
return (
<>
<Fab
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
className={classes.addButton}
size="medium"
color="primary"
aria-label="add"
>
<AddIcon />
</Fab>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleDelete}>Delete Item</MenuItem>
<MenuItem onClick={handleAddNew}>Add Item</MenuItem>
</Menu>
</>
)
}
Inside the main container I have something like this
return (
<div className='my-5'>
<Paper className="pl-5 pr-5 pb-5 position-relative">
<Typography className="pt-4 mb-4 text-center" variant="h4">My Items</Typography>
{!isAuthMode &&
<AddSelectItemButton />
}
<Grid container spacing={3} justify="center">
{allItems.items.map(item=>
<Grid key={item.id} item xs={5} className={`mt-4`} style={{height: '200px'}}>
<Card className={`${classes.root} d-flex ${classes.packInner}`}>
<CardActionArea className="d-flex">
<CardMedia
className={`${classes.media} ${classes.cardImage}`}
image={item.image}
title={item.brand}
/>
<CardContent className={classes.textContainer}>
<Typography gutterBottom variant="subtitle1">
{item.brand}
</Typography>
<Typography variant="body2" color="textSecondary">
{item.name}
</Typography>
<Typography variant="body2" color="textSecondary">
Weight: {item.weight}
</Typography>
<Typography variant="body2" color="textSecondary" className={classes.itemDescription}>
{packInfo.description.length > 80 ?
(`${packInfo.description.substring(0, 77) + '...'}`)
:
packInfo.description
}
</Typography>
</CardContent>
</CardActionArea>
</Card>
</Grid>
)}
</Grid>
</Paper>
</div>
);
If I don't do the condition and include the code in the original rendering. The menu loads at the position of the button. With the condition, it renders far top left of the page and not at the button.
Anyone have an idea or need more info?
Thanks!
{!isAuthMode && (
<AddSelectItemButton />
)}