What's the best way to ensure uniform card height in Material-UI?

Is there a way to ensure consistent card height in Material-UI without setting a fixed height? I want the card heights to dynamically adjust based on content, with all cards matching the tallest one on the website. How can this be achieved while also adding space between the button and content?

The challenge you are encountering involves creating cards with varying content heights using Material-UI but requiring them to have uniform heights without specifying a fixed value. Additionally, you're looking to incorporate spacing between buttons and content.

https://i.stack.imgur.com/vcjGh.jpg

CODE SAND BOX


function ItemRow({ page_block }) {
    return page_block.map((page_block_item, index) => (
        <Grid
            justifyContent="space-between"
            alignItems="center"
            align="center"
            xs={12}
            sm={6}
            md={4}
            lg={4}
        >
            <Grid
                justifyContent="center"
                // alignItems="center"
                xs={10.5}
                sm={12}
                md={11}
                lg={12}
            >
                <Card page_block_item={page_block_item} key={index} />
            </Grid>
        </Grid>
    ));
}

const Card = ({ page_block_item: block_detail }) => {
    const [open, setOpen] = useState(false);
    const router = useRouter();
    const [cart, setCart] = useAtom(cartAtom);

    return (
        <Grid
            key={block_detail.id}
            justifyContent="center"
            display={'flex'}
            flexGrow={1}
            alignItems="stretch"
        >
            <Box
                sx={{
                    position: 'relative',
                    display: 'flex',
                    flexDirection: 'column',
                    height: '100%',
                    boxShadow: '0px 6px 12px -6px rgba(24, 39, 75, 0.12)',
                }}
                justifyContent="space-between"
                border="1px solid #E3E3E3"
                borderRadius="8px"
                overflow="hidden"
                margin={2}
                flexGrow={1}
                alignItems="stretch"
            >
                <Grid sx={{ position: 'relative' }}>
                    <Grid
                        item
                        position="relative"
                        sx={{ aspectRatio: '3/2', height: '100%' }}
                    >
                        <NextImage
                            className="image-cover"
                            media={block_detail.media}
                        />
                    </Grid>
                    <Box
                        sx={{
                            position: 'absolute',
                            right: 0,
                            bottom: 20,
                        }}
                    >
                        <ShareIcon
                            sx={{
                                background: '#FC916A',
                                marginRight: '15px',
                                padding: '5px',
                                height: '30px',
                                width: '30px',
                                borderRadius: '50%',
                                color: '#FFFFFF',
                                cursor: 'pointer',
                                '&:hover': {
                                    background: '#FFFFFF',
                                    color: '#FC916A',
                                },
                            }}
                        />
                        <BookmarkBorderIcon
                            sx={{
                                background: '#FC916A',
                                marginRight: '15px',
                                padding: '5px',
                                height: '30px',
                                width: '30px',
                                borderRadius: '50%',
                                color: '#FFFFFF',
                                cursor: 'pointer',
                                '&:hover': {
                                    background: '#FFFFFF',
                                    color: '#FC916A',
                                },
                            }}
                        />
                    </Box>
                </Grid>

                <Box
                    sx={{
                        flexGrow: 1,
                        display: 'flex',
                        flexDirection: 'column',
                        height: '100%',
                        maxHeight: 'fix-content',
                    }}
                    padding={2}
                >
                    <Grid item sx={{ textAlign: 'left' }}>
                        <StyledText
                            my={1}
                            variant="H_Regular_Tagline"
                            color="primary.main"
                            content={block_detail.info_title}
                        />
                    </Grid>
                    <Grid item sx={{ textAlign: 'left' }}>
                        <StyledText
                            my={1}
                            variant="H_Regular_Body"
                            color="secondary.dark"
                            content={block_detail.info_description}
                        />
                    </Grid>
                </Box>

                <Grid item sx={{ position: 'relative' }}>

                        <Link
                            href={`/${router.query.centerName}/post/donation/${block_detail?.slug}`}
                        >
                            <StyledButton
                                variant="H_Regular_H4"
                                sx={{ width: '90%' }}
                            >
                                {block_detail.info_action_button?.text}
                            </StyledButton>
                        </Link>
                </Grid>
            </Box>
        </Grid>
    );
};

Answer №1

Typically, each grid item has the same height, with the tallest one setting the standard. To customize the height, you can adjust it to be 100% for the component within the grid item.

For a visual example, check out this link: https://stackblitz.com/edit/react-8qnvck?file=demo.tsx,MediaControlCard.tsx

In the provided demonstration, the MediaControlCard component utilizes the Card with the sx prop to set its height to 100%.

If you remove the sx props, the result will resemble your current scenario.

Additionally, it may be unnecessary to employ display:flex in the Box component as it could interfere with achieving a height of 100%.

Answer №2

To achieve the desired layout, you can include the following CSS properties in your .MuiCard-root class:

.MuiCard-root{
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    height: 100%;
}

Alternatively, you can use the following method:

.MuiCard-root{
     display: flex;
     flex-direction: column;
}
.MuiCardActions-root{
     margin-top: auto;
}

Here's a helpful link on How to make Material-UI CardActions always stick to the bottom of parent

You may also find this guide on achieving Same Height Cards in Material UI useful

I found these solutions from the provided links. I hope they prove to be beneficial for your project.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Design a unique <Link> component within my React shared UI library by utilizing a monorepo approach

As a newcomer to application architecture, I am eager to experiment with building an app using a Monorepo structure. I have a query regarding a Next.js frontend app that utilizes my React-based UI package shared across multiple apps within the same Monore ...

How to handle an unexpected keyword 'true' error when using the `useState` hook in React?

Trying to set the open prop of the MUIDrawer component to true on user click is causing an error stating "Unexpected keyword 'true'" import React, { useState } from "react"; import { withRouter } from "react-router-dom"; impo ...

The input field is failing to capture the final character entered

Is there a way to store all input files in a single object and use the information in a graph? Currently, when I enter the first character, it creates an empty object, so the last character I enter is not captured in the object. Any suggestions on how to ...

Using -webkit-hyphens: auto in Safari does not function properly when the width is set to auto

I have a situation with an h3 element where I am unsure of its width. As a result, the width is set to auto by default. However, I need the text inside this element to have hyphenation applied to it. This h3 element is within a flex container along with an ...

The potential weakness that arises during the installation of react-scripts

After installing react-scripts, I discovered a total of 58 vulnerabilities, including 16 moderate, 40 high, and 2 critical threats. Here is a breakdown of my setup: Operating System: Linux Debian 10 Node.js version: v14.18.1 Npm version: 8.1.0 React versi ...

As a React developer, it's essential to understand how to trigger a callback event in a child

Hello there, I am just starting out with React and currently utilizing Fluent UI in my project. My aim is to create a reusable Panel component using Fluent UI. Below is the code snippet I have been working on: import * as React from 'react'; impo ...

Creating text input without borders using HTML and CSS

I have managed to create text inputs without borders using HTML and CSS, but I am facing an issue. Whenever I click on the input field, a yellow border appears instead of the one I removed. It seems like this is coming from the default stylesheets, and I&a ...

Experiencing problems with React createContext in Typescript?

I've encountered a strange issue with React Context and Typescript that I can't seem to figure out. Check out the working example here In the provided example, everything seems to be working as intended with managing state using the useContext ...

Encountering the error message "TypeError: Unable to access properties of null (reading 'get')" while utilizing useSearchParams within a Storybook file

Looking at the Next.js code in my component, I have the following: import { useSearchParams } from 'next/navigation'; const searchParams = useSearchParams(); const currentPage = parseInt(searchParams.get('page') || '', 10) || ...

What is the code to create a forward slash on a webpage using HTML/CSS?

I want to create a unique parallelogram/slash design on my website. While it's simple to place two rectangles side by side, achieving the slash effect is proving to be quite challenging. Can this be done using only CSS or HTML, or does it require SVGs ...

Display some text after a delay of 3 seconds using setTimeOut function in ReactJS

When using React JS, I encountered an issue where I am able to display text in the console after 2 seconds, but it is not appearing in the DOM. const items = document.getElementById("items"); const errorDisplay = () => { setTimeout(function () { item ...

React SVG not displaying on page

I am facing an issue with displaying an SVG in my React application. Below is the code snippet: <svg className="svg-arrow"> <use xlinkHref="#svg-arrow" /> </svg> //styling .user-quickview .svg-arrow { fill: #fff; position: ...

Tips on how to customize Material UI box component for overlay styling

I'm a beginner in the world of styling components and creating visual designs that meet my preferences. My goal is to design two overlapping box components that will showcase user statistics and daily targets in a sleek and professional manner. The ...

React-query: When looping through useMutation, only the data from the last request can be accessed

Iterating over an array and applying a mutation to each element array?.forEach((item, index) => { mutate( { ...item }, { onSuccess: ({ id }) => { console.log(id) }, } ); }); The n ...

Displaying unique array values in React.js without duplicates!

When printing a bill, I encounter an issue with the 'Products' array object. If I have 3 products in the array with identical product names, prices, and discounts, I want to display them as one line instead of three. Each product has a unique ser ...

Using styled-components to enhance an existing component by adding a new prop for customization of styles

I am currently using styled-components to customize the styling of an existing component, specifically ToggleButton from material ui. However, I want my new component to include an additional property (hasMargin) that will control the style: import {Toggle ...

Combining multiple PNG images onto a base image in PHP

I need assistance in merging 24 images with single dashes highlighted into a base circle image using PHP GD, JS or CSS. All images are in PNG format. Your help would be greatly appreciated. ...

Utilizing hooks to pass properties from a parent component to a child component

As someone who is new to react, I am currently facing an issue with passing props from a parent function to a child. It seems that the parameters "square_state" and "setSquare_state" are not being recognized in the useSquare or handle_square_click functi ...

Troubleshooting CSS Display Problem on Chrome and Firefox

While working on the design of a website offline, everything seemed to be running smoothly. However, upon uploading it to the server, various issues began to arise. Initially, the file loaded correctly upon first visit. Unfortunately, after reloading the ...

How can I customize a CSS media class?

In my project, I am using a CSS library that includes the following class: @media only screen and (max-width: 480px) { .nav-tabs>li { margin-bottom:3px; } .nav-tabs>li, .nav-tabs>li>a { display:block !important; ...