How to make the whole Card component clickable in Material UI using React JS?

68,456

Solution 1

Update for v3 — 29 of August 2018

A specific CardActionArea component has been added to cover specifically this case in version 3.0.0 of Material UI.

Please use the following solution only if you are stuck with v1.

What you probably want to achieve is a Card Action (see specification) on the top part of the card.

The Material Components for Web library has this as its first usage example for the Card Component.

You can easily reproduce that exact behaviour by composing MUI Card* components with the mighty ButtonBase component. A running example can be found here on CodeSandbox: https://codesandbox.io/s/q9wnzv7684.

The relevant code is this:

import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Typography from '@material-ui/core/Typography';
import ButtonBase from '@material-ui/core/ButtonBase';

const styles = {
  cardAction: {
    display: 'block',
    textAlign: 'initial'
  }
}

function MyCard(props) {
  return (
    <Card>
      <ButtonBase
          className={props.classes.cardAction}
          onClick={event => { ... }}
      >
        <CardMedia ... />
        <CardContent>...</CardContent>
      </ButtonBase>
    </Card>
  );
}

export default withStyles(styles)(MyCard)

Also I strongly suggest to keep the CardActions component outside of the ButtonBase.

Solution 2

With Material UI 4.9.10, this works.

<Card>
    <CardActionArea href="https://google.com">
        <CardContent>
            <Typography>Click me!</Typography>
        </CardContent>
    </CardActionArea>
</Card>

If you're using react router, this also works.

<Card>
    <CardActionArea component={RouterLink} to="/questions">
        <CardContent>
            <Typography>Click me!</Typography>
        </CardContent>
    </CardActionArea>
</Card>

Solution 3

We can also use Link tag to make the whole Card component clickable and for navigation

import { Link } from 'react-router-dom';
function myCard() {
  return (
    <Link to={'/give_your_path'}>
     <Card>
      <Card text="This is text"/>
     </Card>
    </Link>
  );
}

Solution 4

You could add an onClick={clickFunction} to the containing div of the card that links to the same function as the button.

Solution 5

Here is the solution that worked for us, thanks to https://stackoverflow.com/a/50444524/192092

import { Link as RouterLink } from 'react-router-dom'
import Link from '@material-ui/core/Link'

<Link underline='none' component={RouterLink} to='/your-target-path'>
  <Card>
    <CardActionArea>
      ...
    </CardActionArea>
  </Card>
</Link>
Share:
68,456
SeaWarrior404
Author by

SeaWarrior404

Updated on July 09, 2022

Comments

  • SeaWarrior404
    SeaWarrior404 almost 2 years

    Im using Material UI Next in a React project. I have the Card component which has an image(Card Media) and text(Card Text) inside it. I also have a button underneath the text. My question is..how to make the whole card clickable? ie. Whether a user presses on the card text, or the card image or the button, it should trigger the onClick event which I call on the button.

  • JW.
    JW. over 5 years
    This worked, although I found that I usually needed to add width: 100%; height: 100% to both the ButtonBase and the CardContent.
  • Christiaan Westerbeek
    Christiaan Westerbeek almost 4 years
    Next to href, you can also add target="_blank" to CardActionArea
  • AliAvci
    AliAvci over 3 years
    This seems to be overriding the CSS for the text elements inside CardContent
  • Lucas
    Lucas over 3 years
    after doing some research, I found that <CardActionArea> can be used like the <ButtonBase> and has better visual feedback 👍🏻
  • Ran Marciano
    Ran Marciano over 3 years
    Please don't post only code as an answer, but also provide an explanation of what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes
  • Dan
    Dan over 3 years
    fantastic answer!
  • 425nesp
    425nesp almost 3 years
    Quick and easy, but probably not as pretty as some of the other solutions. Worked for what I needed.