Material Effect on Button with Background Color

Material effect on button with background color

When you use android:background, you are replacing much of the styling and look and feel of a button with a blank color.

Update: As of the version 23.0.0 release of AppCompat, there is a new Widget.AppCompat.Button.Colored style which uses your theme's colorButtonNormal for the disabled color and colorAccent for the enabled color.

This allows you apply it to your button directly via

<Button
...
style="@style/Widget.AppCompat.Button.Colored" />

If you need a custom colorButtonNormal or colorAccent, you can use a ThemeOverlay as explained in this pro-tip and android:theme on the button.

Previous Answer

You can use a drawable in your v21 directory for your background such as:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="?attr/colorPrimary"/>
</ripple>

This will ensure your background color is ?attr/colorPrimary and has the default ripple animation using the default ?attr/colorControlHighlight (which you can also set in your theme if you'd like).

Note: you'll have to create a custom selector for less than v21:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primaryPressed" android:state_pressed="true"/>
<item android:drawable="@color/primaryFocused" android:state_focused="true"/>
<item android:drawable="@color/primary"/>
</selector>

Assuming you have some colors you'd like for the default, pressed, and focused state. Personally, I took a screenshot of a ripple midway through being selected and pulled the primary/focused state out of that.

Change Ripple Color on click of Material UI Button /

Here's an example showing how to modify the button ripple for v4 (v5 example further down):

import React from "react";
import { withStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";

const styles = theme => ({
button: {
backgroundColor: "green",
"&:hover": {
backgroundColor: "red"
}
},
child: {
backgroundColor: "blue"
},
rippleVisible: {
opacity: 0.5,
animation: `$enter 550ms ${theme.transitions.easing.easeInOut}`
},
"@keyframes enter": {
"0%": {
transform: "scale(0)",
opacity: 0.1
},
"100%": {
transform: "scale(1)",
opacity: 0.5
}
}
});

function MyButton({ classes, ...other }) {
const { button: buttonClass, ...rippleClasses } = classes;
return (
<Button
TouchRippleProps={{ classes: rippleClasses }}
className={buttonClass}
{...other}
/>
);
}

export default withStyles(styles)(MyButton);

Edit button ripple

The default opacity of the ripple is 0.3. In the example I have increased this to 0.5 to make it easier to verify that the ripple is blue. Since the button background is red (due to the hover styling), the result is purple. You'll get a different overall effect if you move to the button via the keyboard since the blue will be layered on top of the button's green background.

You'll find some additional background in my answer here: How to set MuiButton text and active color

The main resource for the styling of the ripple is its source code: https://github.com/mui-org/material-ui/blob/v4.10.2/packages/material-ui/src/ButtonBase/TouchRipple.js

JSS keyframes documentation: https://cssinjs.org/jss-syntax/?v=v10.3.0#keyframes-animation


Here's a similar example for MUI v5:

import { styled } from "@mui/material/styles";
import Button from "@mui/material/Button";
import { keyframes } from "@emotion/react";

const enterKeyframe = keyframes`
0% {
transform: scale(0);
opacity: 0.1;
}
100% {
transform: scale(1);
opacity: 0.5;
}
`;
const StyledButton = styled(Button)`
background-color: green;
&:hover {
background-color: red;
}
&& .MuiTouchRipple-child {
background-color: blue;
}
&& .MuiTouchRipple-rippleVisible {
opacity: 0.5;
animation-name: ${enterKeyframe};
animation-duration: 550ms;
animation-timing-function: ${({ theme }) =>
theme.transitions.easing.easeInOut};
}
`;
export default StyledButton;

Edit button ripple

v5 TouchRipple source code: https://github.com/mui/material-ui/blob/v5.4.0/packages/mui-material/src/ButtonBase/TouchRipple.js#L92

Emotion keyframes documentation: https://emotion.sh/docs/keyframes

Answer demonstrating use of keyframes: How to apply custom animation effect @keyframes in MUI?

Android material button set icon and background color not working?

I ended up adding to my button the attribute

android:drawableLeft="@drawable/fb_icon"

and then also adding some start padding to the style so I could position the icon where I wanted to.

MUI Button hover background color and text color

You probably don't want to change the button's :active state but the default and the :hover state. The following sets the button color to #fff and the backgroundColor to #3c52b2 and switch them on :hover.

I'm not sure how you applied the updated styles (or how you tried to override the default styles), I created this snippet below with makeStyles() but the idea is the same with the withStyles() HOC.

const { 
AppBar,
Button,
makeStyles,
Toolbar,
Typography,
} = MaterialUI

const useStyles = makeStyles({
flexGrow: {
flex: '1',
},
button: {
backgroundColor: '#3c52b2',
color: '#fff',
'&:hover': {
backgroundColor: '#fff',
color: '#3c52b2',
},
}})

function AppBarWithButtons() {
const classes = useStyles()

return (
<AppBar>
<Toolbar>
<Typography>
YourApp
</Typography>
<div className={classes.flexGrow} />
<Button className={classes.button}>
Button 1
</Button>
<Button className={classes.button}>
Button 2
</Button>
</Toolbar>
</AppBar>
);
};

ReactDOM.render(
<React.StrictMode>
<AppBarWithButtons />
</React.StrictMode>,
document.getElementById("root")
)
<div id="root"></div>
<script src="https://unpkg.com/react/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.production.min.js"></script>

How can I change Angular Material button background color on hover state?

As of Angular 6, the use of /deep/ or ng-deep in the chosen solution is marked for deprecation. The recommended way is to use global styles as stated in the docs.

Some Angular Material components, specifically overlay-based ones like
MatDialog, MatSnackbar, etc., do not exist as children of your
component. Often they are injected elsewhere in the DOM. This is
important to keep in mind, since even using high specificity and
shadow-piercing selectors will not target elements that are not direct
children of your component. Global styles are recommended for
targeting such components.

In the specific case of button hover background, I had to use the following code in my styles.css (global stylesheet included via angular-cli or directly linked in index.html). Note that you might have to replace primary with accent or warn depending on the palette type (color="primary" or color="accent" or color="warn") used in the button.

.mat-button.mat-primary .mat-button-focus-overlay {
background-color: transparent;
}

If you don't want every button to be affected, it's better to have a specific class like no-hover-effect as shown below.

.no-hover-effect.mat-button.mat-primary .mat-button-focus-overlay,
.no-hover-effect.mat-button.mat-accent .mat-button-focus-overlay,
.no-hover-effect.mat-button.mat-warn .mat-button-focus-overlay
{
background-color: transparent;
}

For every material button that doesn't need hover-effect, you'd do

  <button mat-button color="primary" class="no-hover-effect">
No Hover Button
</button>

Add ripple effect to my button with button background color?

Here is another drawable xml for those who want to add all together gradient background, corner radius and ripple effect:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorPrimaryDark">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="@color/colorPrimaryDark" />
<corners android:radius="@dimen/button_radius_large" />
</shape>
</item>

<item android:id="@android:id/background">
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="@color/colorPrimaryLight"
android:startColor="@color/colorPrimary"
android:type="linear" />
<corners android:radius="@dimen/button_radius_large" />
</shape>
</item>
</ripple>

Add this to the background of your button.

<Button
...
android:background="@drawable/button_background" />

PS: this answer works for android api 21 and above.



Related Topics



Leave a reply



Submit