Transform the scrollbar appearance on hover. Implement this feature using React and CSS with Material-UI

Within my React app, I am facing an issue with a scrollbar appearing in multiple lists. The global CSS being used within Material-UI is as follows:


  MuiCssBaseline: {
    ...theme.overrides?.MuiCssBaseline,
    '@global': {
      '@font-face': fontFace,
      '*::-webkit-scrollbar': {
        width: '1.3%',
        maxWidth: '5px'
      },
      '*::-webkit-scrollbar-thumb': {
        backgroundColor: 'white'
      },
      '*:focus': {
        outline: 'none'
      }
    }
  }
};

I want to implement global state for hover functionality where if I hover over a box (not the scroll itself), the scrollbar should change to gray. An example of the box structure is:

    <Box className={listStyle.root}>
      <AutoSizer>
        {({ height, width }) => (
          <List dense ...... 
              return (
                <ListItem
 
                />
              );
            })}
          </List>
        )}
      </AutoSizer>

I have tried adding the following code snippet, but it did not work as expected:

.listStyle:{
   '&:hover':{
       '*::-webkit-scrollbar-thumb': {
        backgroundColor: 'gray'
      },
   }
}

Any suggestions on how I can achieve this behavior?

Answer №1

One key issue that stands out is the necessity to utilize & rather than * when nesting a rule like ::-webkit-scrollbar-thumb pseudo-element within the :hover pseudo-class. Therefore, your listStyle should be structured as follows:

.listStyle:{
   '&:hover':{
      '&::-webkit-scrollbar-thumb': {
        backgroundColor: 'gray'
      },
   }
}

An alternative approach would be:

.listStyle:{
   '&:hover::-webkit-scrollbar-thumb': {
      backgroundColor: 'gray'
   }
}

If you wish to apply this globally, consider implementing the following adjustments (colors have been modified for clarity):

const theme = createMuiTheme({
  overrides: {
    MuiCssBaseline: {
      "@global": {
        "*::-webkit-scrollbar": {
          width: "1.3%",
          maxWidth: "5px"
        },
        "*::-webkit-scrollbar-thumb": {
          backgroundColor: "purple"
        },
        "*:hover": {
          "&::-webkit-scrollbar-thumb": {
            backgroundColor: "green"
          }
        }
        /* Equivalent alternative:
        "*:hover::-webkit-scrollbar-thumb": {
          backgroundColor: "green"
        }
         */
      }
    }
  }
});

https://codesandbox.io/s/change-scrollbar-on-hover-globally-q1i0f?fontsize=14&hidenavigation=1&theme=dark

Here's a complete example showcasing both the global and class-specific approaches:

import React from "react";
import CssBaseline from "@material-ui/core/CssBaseline";
import {
  ThemeProvider,
  createMuiTheme,
  makeStyles
} from "@material-ui/core/styles";

const theme = createMuiTheme({
  overrides: {
    MuiCssBaseline: {
      "@global": {
        "*::-webkit-scrollbar": {
          width: "1.3%",
          maxWidth: "5px"
        },
        "*::-webkit-scrollbar-thumb": {
          backgroundColor: "purple"
        },
        "*:hover": {
          "&::-webkit-scrollbar-thumb": {
            backgroundColor: "green"
          }
        }
        /* Equivalent alternative:
        "*:hover::-webkit-scrollbar-thumb": {
          backgroundColor: "green"
        }
         */
      }
    }
  }
});

const useStyles = makeStyles({
  divStyle: {
    "&:hover::-webkit-scrollbar-thumb": {
      backgroundColor: "red"
    }
  }
});
export default function App() {
  const classes = useStyles();
  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <div style={{ height: "200px", overflowY: "scroll" }}>
        <h1>
          Div with enough content to scroll. Globally controlled scrollbar hover
          color
        </h1>
        <h2>1</h2>
        <h2>2</h2>
        <h2>3</h2>
        <h2>4</h2>
        <h2>5</h2>
        <h2>6</h2>
      </div>
      <div
        style={{ height: "200px", overflowY: "scroll" }}
        className={classes.divStyle}
      >
        <h1>
          Div with enough content to scroll. Scrollbar hover color controlled by
          classes.divStyle.
        </h1>
        <h2>1</h2>
        <h2>2</h2>
        <h2>3</h2>
        <h2>4</h2>
        <h2>5</h2>
        <h2>6</h2>
      </div>
    </ThemeProvider>
  );
}

https://codesandbox.io/s/change-scrollbar-on-hover-globally-uj79x?fontsize=14&hidenavigation=1&theme=dark

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

Photos failing to load in the image slider

Although it may seem intimidating, a large portion of the code is repetitive. Experiment by clicking on the red buttons. <body> <ul id="carousel" class="carousel"> <button id="moveSlideLeft" class="moveSlide moveSlideLeft"></button& ...

Retrieved data from Axios and used it as the starting value for another state in React Hooks

Can you share any tips on how to set the value fetched from Axios as the initial value of a different state? I'm thinking of using useEffect so that the state updates after rendering. Check out the code snippet below: const [newCode, setNewCode] = ...

How to center align a fixed div position

I am looking for a way to center align a fixed position div on my page. In the past, I have been able to achieve this with absolutely positioned divs using a specific technique. left: 50%; width: 400px; margin-left: -200px; However, this method does no ...

The min-height property in Bootstrap 3 causes a div element to not expand as expected

Having a bootstrap 3 page with a centered box that contains content, I noticed that the box does not expand when the content grows. The bootstrap container grows, but the box remains static. I have tried using "position:relative" and "overflow:hidden", as ...

Create a notification menu in Bootstrap using Bootply, which conveniently displays a numerical badge at the top

I am interested in implementing a bootstrap notification menu similar to the one found at this link: http://www.bootply.com/oasBuRC8Kz# However, I would like to add the number of notifications to the upper right corner of the glyphicon. I have gone throug ...

Tips for incorporating a reference into a styled component div in a React application using TypeScript

Looking to include a reference to a styled component div. Here is the code snippet: const DragAndDrop: React.FC<any> = props => { const divRef= React.createRef(); return ( <Zone ref={divRef}/> ); } Encountering thi ...

Ways to transform date into a different structure using JavaScript

Fetching a date from an API gives me this format: 2017-04-20T07:00:00Z How can I convert it to the following format? 20.04.2017 I am using React to render the date: <div>{props.data.day}</div> I attempted to use toISOString().slice(0, 1 ...

We were unable to identify any Next.js version in your project. Please ensure that the `"next"` package is installed in either the "dependencies" or "devDependencies" section

My attempt to deploy a Next app using the Vercel CLI has hit a roadblock. After running vercel build with no errors, I proceeded to deploy with vercel deploy --prebuilt, which also went smoothly. However, when trying to move the project from the preview en ...

Steps for designing an HTML table that expands and collapses partially

I am currently revamping an old "Top Screens" page by expanding the display from the top 30 to the top 100 in a basic html table format. However, I only want to show the top 20 on page load with an expand/collapse feature. While I have come across examples ...

The progress bar in Next JS 13 seems to be malfunctioning and is not displaying any

After transitioning to the new Next JS 13 app directory, I encountered an issue where the progress bar at the top does not function when the page loads. In the previous version, Next JS 12, there was a package named nprogress and nextNprogress that simpli ...

When running `npm install`, it attempts to install version 1.20.0 of grpc even though version 1.24.2 is specified in

After running npm install on my React-Native project, an error occurred stating that it was attempting to install gRPC version 1.20.0, but my package.json and package-lock.json specified gRPC version 1.24.1. I attempted to fix the issue by adjusting the v ...

Adding a class to an img tag with TinyMCE

Currently, I am utilizing the TinyMCE editor as a standalone editor in my content management system (CMS). Within the CMS, there is an automatic setting that adds a curved border to any image tags within the cms div ID. In certain cases, I require the op ...

Exploring the wonders of Bootstrap 3 panels and stylish floating images

Is it possible to create a responsive design using Bootstrap 3 panel along with a floating image positioned next to it? I want the panel to seamlessly fit into the available space, without overlapping the image. Can anyone provide guidance on achieving thi ...

Infinite API calls leading to performance issues in a NextJs application due to the utilization of JavaScript's toISOString

To explore a potential issue I encountered while using the toISOString() JavaScript function within a variable called in a useSWR API call, I set up a sample Next.js app as an example: The code for pages/user/[id].tsx, where the toISOString() function is ...

Error: The createContext function is designed for use only in Client Components. To enable it, include the "use client" directive at the beginning of the file

After creating a fresh Next.js application with the app folder, I proceeded to integrate Materiel UI following the example provided in the documentation. However, I encountered an error: TypeError: createContext only works in Client Components. Add the & ...

Toggle display of list items using jQuery on click event

I want to be able to toggle the visibility of my submenus when a link is clicked. Here's an example code snippet: <ul> <li><a href="www.example.com">Test</a></li> <li><a href="www.example.com ...

Prevent scrolling with absolute positioning

Here's a snippet of my HTML pseudocode: <div> <VideoAnimation /> <div className="under-animation"> // a lot of content goes here </div> </div> The issue arises from using absolute positioning on th ...

Using Javascript to add hovering effects that demonstrate sophistication and style

I have a question : Here is the HTML code snippet: <div class="a b"> <span class="one">Success ONE</span> <span class="two">ONE</span> </div> <div class="a b"> <span class="one">Success TWO< ...

The background image's fadeInOut transitions create a strange phenomenon where all the text appears in white

So, here's a strange issue I'm facing. On my website, the background image changes with a smooth fadeIn/Out transition. Video: Website in action: Here is the HTML markup: <div class="fondo" onclick="descargar(2,500);descargar(1,500);"> ...

Bootstrap along with ROR 3.2.21 has a malfunctioning navbar

I am facing an issue with the Home section in the navbar. It used to work perfectly, but suddenly it stopped displaying as intended. I have checked and confirmed that both boostrap.min.js and boostrap.min.css are loaded properly. I have included boo ...