How to add ripple effect when clicking Card in MUI

20,106

Solution 1

I can see this question was not answered, so I'll provide an up-to-date solution (writing this as material-ui is v. 0.18.7 (stable):

You need to import the ripple higher-order comp. (HOC) as:

import TouchRipple from '@material-ui/core/ButtonBase/TouchRipple';

Then you can wrap any component of you choice with TouchRipple, like:

<TouchRipple>
   <div>
     MY RIPPLING DIV
   </div>
</TouchRipple>

Or, if you need a CSS class-based apporach, you can use materialize lib -> https://react-materialize.github.io/#/

In that case, it's as simple as adding a value to waves prop on a material-ui Button, like:

<Button waves='light'>EDIT ME<Icon left>save</Icon></Button>

Solution 2

I noticed that TouchRipple has been moved out of the internal directory. It's now available in the ButtonBase folder.

Here is how I was able to add ripple effect by using the ButtonBase component -

Basically, you wrap your component, let's say <Card> inside the <ButtonBase> like so, and the ButtonBase takes care of the TouchRipple setting up for you -

<ButtonBase>
     <Card>
         ....
     </Card>
</ButtonBase>

Here is a Codesandbox link to working demo. I know this is not the best way. You could directly use the TouchRipple/Ripple component, but I found this way to be very easy to use.

Hope this helps.

Solution 3

2021 Update

The most idiomatic way to add the ripple effect when clicking the Card is using the CardActionArea. This component inherits the props of ButtonBase. It also changes the Card background color when hovered and focused (unlike ButtonBase):

<Card>
  <CardActionArea>
    <CardContent>
      {...}
    </CardContent>
  </CardActionArea>
</Card>

Codesandbox Demo

Solution 4

The approach taken in @xiaofan2406 never worked for me, not to mention passing height, width and position seems easily breakable and might not be possible when using flexbox.

However I managed to make it work like:

<YourComponent>
    <TouchRipple>
        {children}
    </TouchRipple>
</YourComponent>

Solution 5

Here is a Solution 2021 updated

  1. simple You need wrap your custom components with component from material ui .
  2. Then add style padding: 0 that solve.
  3. Here I want my Image should react with ripple effect.

You can customize by wrapping with Grid and props container


import { Button } from "@material-ui/core";

function ImageCard(props){

return (
            <Button style={{ padding: 0, borderRadius: "16px" }}>
              {/*my custom component you can use any component even material ui component also*/}
                <img
                  src={yourImageUrl}
                  alt="img"
                  style={{
                    height: 200,
                    width: 400,
                    borderRadius: "16px",//optional
                  }}
                />
              </Button>
      );
}
Share:
20,106

Related videos on Youtube

Vishal Vijay
Author by

Vishal Vijay

Updated on February 21, 2022

Comments

  • Vishal Vijay
    Vishal Vijay about 2 years

    Is there a way I can add ripple effect to MUI Card component on click.

    And I would also like to know, is it possible to make ripple effect to come on top of the content of Card component, rather that it showing as background.

    • lux
      lux about 8 years
      With materialize-css, you're able to add the "wave" effect to seemingly any element (materializecss.com/waves.html#!). I haven't tested this out, but looks up your alley.
  • Oscar Franco
    Oscar Franco over 7 years
    I have been trying to make this work for the last 2 hours or so, but doesn't work, apparently the onTouchTap propagation does not reach the underlaying TouchRipple component, I tried to manually pass the event, but that does not seem to work either... any suggestions?
  • Oscar Franco
    Oscar Franco over 7 years
    Just fyi, I have read the source code and that is how I knew I had to manually pass the onTouchTap even to handleOnMouseDown, but it still does not work
  • xiaofan2406
    xiaofan2406 over 7 years
    @das_franco TouchRipple doesn't have any onTouchTap or handleOnMouseDown. See here
  • Yurii N.
    Yurii N. over 7 years
    Seems like it doesn't work, I've added TouchRipple and use it around my component, but ripple creates at the top left corner of the page, which is obviuosly not the mentioned behaviour.
  • Oscar Franco
    Oscar Franco over 7 years
    Are the items inside absolutely positioned? bare into account material-ui calculates a lot of the properties on runtime, so you should take a look at the actual children representation, in any case, it worked for me and taking a look at the source code of material-ui components this is how it is being used
  • Yurii N.
    Yurii N. over 7 years
    I'm not sure about absolutely positioned items, however, I'm using ripple like this: <TouchRipple><Card>...</Card></TouchRipple> and it doesn't work.
  • Oscar Franco
    Oscar Franco over 7 years
    I have no idea of <Card> component internal workings, this is working when wrapping non-material ui components, my advice is: take a look at the source code of <Card> the children prop is probably being not being calculated the way you expect My second suggestion: <Card><TouchRipple>...</TouchRipple></Card>
  • Vojtěch Dohnal
    Vojtěch Dohnal almost 6 years
    Module not found: Can't resolve 'material-ui/internal/TouchRipple'
  • Miguel Lara
    Miguel Lara about 5 years
    Thanks! just one thing: Now the Ripple is located in '@material-ui/core/ButtonBase/TouchRipple';