Changing the hover background color and text color of Material UI Button

I recently developed a custom Appbar component using React.js that includes 3 buttons. I'm looking to enhance the user experience by changing the color scheme when users hover over these buttons. Currently, the background color is set to #3c52b2 and the text color is set to #fff. My goal is to switch the background color with the text color upon hovering.

Despite trying the code snippet below, I haven't been successful in achieving this effect:

Button: {
  '&:hover': {
    backgroundColor: '#ffffff',
    boxShadow: 'none',
  },
  '&:active': {
    boxShadow: 'none',
    backgroundColor: '#3c52b2',
  },
},

Answer №1

To modify the appearance of a button, focus on changing its default and hover states rather than the active state. The code snippet below demonstrates setting the button text color to white (#fff) and the background color to a shade of blue (#3c52b2), which then switches when hovered over.

If you are unsure about how to implement these style updates or override default styles, refer to the following example utilizing makeStyles(). The concept remains similar with the use of 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>

An alternative approach is to create a new styled button component:

const StyledButton = withStyles({
  root: {
    backgroundColor: '#3c52b2',
    color: '#fff',
    '&:hover': {
      backgroundColor: '#fff',
      color: '#3c52b2',
  },
}})(Button);

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

const StyledButton = withStyles({
  root: {
    backgroundColor: '#3c52b2',
    color: '#fff',
    '&:hover': {
      backgroundColor: '#fff',
      color: '#3c52b2',
  },
}})(Button);

function AppBarWithButtons() {
  return (
    <AppBar>
      <Toolbar>
        <Typography>
          YourApp
        </Typography>
        <div style={{flex: '1'}} />
        <StyledButton>
          Button 1
        </StyledButton>
        <StyledButton>
          Button 2
        </StyledButton>
      </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>

Answer №2

If you wish to achieve this in MUI version 5, you can utilize the sx prop:

<Button
  variant="text"
  sx={{
    ':hover': {
      bgcolor: 'primary.main', // theme.palette.primary.main
      color: 'white',
    },
  }}
>
  Text
</Button>

Alternatively, you can use styled() to create a reusable component:

const StyledButton = styled(Button)(({ theme, color = 'primary' }) => ({
  ':hover': {
    color: theme.palette[color].main,
    backgroundColor: 'white',
  },
}));
<StyledButton variant="contained" color="primary">
  Contained
</StyledButton>
<StyledButton variant="contained" color="secondary">
  Contained
</StyledButton>

Live Demo

https://codesandbox.io/s/64983425-material-ui-button-hover-active-background-color-and-text-color-zc5cf?file=/demo.tsx

Answer №3

To achieve the effect of a Material-UI default button getting darker on hover, you can utilize the following code snippet within your theme:

import { darken } from '@material-ui/core/styles';

containedPrimary: {
    backgroundColor: mainColor,
    '&:hover': {
        backgroundColor: darken(mainColor, 0.3),
    },
},

Answer №4

Here is a simple approach I implemented in my project.

const customStyles = {
  Button: {
    "&:hover": {
      backgroundColor: "#ffffff !important",
      boxShadow: "none !important",
    },
    "&:active": {
      boxShadow: "none !important",
      backgroundColor: "#3c52b2 !important",
    },
  },
};

return <Button styles={customStyles.button}>Click here</Button>;

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

Streamlined [JavaScript?] solution for displaying and modifying several location-specific purchasing and selling rates

No, this is not related to interviews or cryptocurrencies! :) It is for a non-profit personal web application designed to enhance a game. This question involves both finance and coding. I am developing this web app using Vue.js, so I prefer a JavaScri ...

JavaScript Integration for Microsoft Dynamics NAV

I have developed a JavaScript Addin for Microsoft Dynamics Nav 2013. The Addin functions properly when used on the same machine as Navision. However, when I replace "localhost" with the machine's name, the Addin stops working. Below is the script I am ...

Changing text inside ion-header-bar directive

When utilizing the ion-header-bar directive, I have the left side designated as class="button", the middle section containing <h1> with the word "Recent", and the right side as <ng-icon>. The text on the left side is dynamically generated usin ...

Issue with Karma: encountering error "ocLazyLoad initialization failed"

While attempting to run the tests from the quickstart sb-admin-angular, I encountered an error stating unable to init ocLazyLoad. (This issue is occurring on a Windows 7 machine.) The command I am using to run the tests is: $ grunt test --force After re ...

What is the best way to include and control persistent URL parameters when making Ajax requests?

Imagine having two different resource lists on your website: one for users and the other for groups. As you navigate through each list in increments of 10, it's important to preserve the state of the list so that when you share the URL with someone el ...

Having trouble getting transitionProperty to work in the style object of your ReactJS CSS?

In my current setup, I have been utilizing css transitions triggered by property updates to manage animations within my react components and everything has been functioning smoothly up until now. However, I am encountering an issue where I only want to tr ...

What could be causing the tooltip to not function properly with data-html="true"?

I am having trouble with customizing a tooltip. The data-html="true" attribute is not working as expected, and I can't seem to figure out what the issue is. .tooltip-custom { display: inline; position: relative; } ...

What are the best practices for incorporating an ASP variable into Javascript code?

Trying to incorporate an ASP variable into JavaScript code, but encountering difficulties. How can this be achieved? Any suggestions? <% dim strMyString strMyString = "hello there" %> <HTML> <body> <%=strMyString%> ...

Difficulty Zoom-Scrolling Issue in Pigeon-Maps using ReactJS

I am experiencing a problem with my pigeon-maps in a reactjs-app. While using the mouse to navigate through the map works perfectly fine, zooming with the scroll wheel seems to be dysfunctional. On the other hand, a double-click does zoom in the map, but t ...

Creating a disabled HTML button that reacts to the :active CSS pseudo class

CSS: button:active { /* active css */ } button:disabled { opacity: 0.5; } HTML: <button disabled="disabled">Ok</button> After clicking the button, the browser applies the button:active state to give the appearance of a click, despite the ...

Transmit JSON information from one webpage and dynamically retrieve it from another page via AJAX while both pages are active

I am attempting to transfer JSON data from page1 when the submit button is clicked and then retrieve this data dynamically from page2 using AJAX in order to display it in the console. I am unsure of the correct syntax to accomplish this task. There was a s ...

Revamping an npm package on GitHub

Currently, I am managing a project that has gained popularity among users and has received contributions from multiple individuals. The next step I want to take is to convert the entire library into TypeScript, but I am unsure of the best approach to ach ...

Create a dynamic progress bar that integrates seamlessly with the ajaxupload functionality for a smoother video uploading

Is there a way to display an accurate time estimate alongside a visually appealing progress bar during video uploads? Currently, I am utilizing the ajaxupload javascript library in conjunction with PHP CodeIgniter for server-side functionality. ...

Add a background color to a drop-down selection box on Mozilla

I am trying to add a background color to a select box. My code successfully adds the background color to the options in Chrome, but not in Mozilla. How can I apply the background color to the select box in Mozilla as well? https://i.sstatic.net/TYU6R.png ...

Issue with React Lazy not functioning properly in Production Build

In my current project, I have implemented lazy loading for routes. While it works well locally, I am facing several issues when it comes to the production build. Whenever I try to redirect to one of the lazy routes, instead of accessing the chunk from the ...

Creating a looping animation on multiple elements using jQuery that makes them fade in and out at different intervals

I am currently working on creating a fade in and out animation for multiple elements using jquery. It's a bit complex to explain, so I will start by sharing the relevant code. $(document).ready(function() { $("#1").delay(0).animate({ ...

Finding the automatically generated ID of a new document in a subcollection in Firebase Firestore Web V9, using Javascript/React

When a user clicks, I generate a new document in a subcollection associated with that user's profile. Below is the function responsible for this: // Function to create a new checkout session document in the subcollection under the user's profile ...

Refresh WebPage automatically after a Servlet successfully uploads and processes an image

I have a webpage that includes an image and a button. When the button is clicked, it uploads the image by submitting a form to a file upload servlet. However, after successfully uploading the image, the servlet does not display it in the img tag. Here is ...

What is the best way to integrate JSS styles into a React application that is using Material UI

I have multiple .js files that utilize { makeStyles } from "@material-ui/core/styles"; to create jss. I am using className={classes.myClass} and then calling it with const classes = useStyles();. This is a common setup, but the issue arises when I need to ...

What is the correct way to forcefully override an existing type in TypeScript?

As I work with Formik, a React form library, I find myself creating custom fields and utilizing the generic Schema type provided by Formik. This type represents the values object, which holds all the values for each field in the form. One of the custom co ...