'MUI - How can I style the scrollbar with CSS in JS?

I really hate having to have an external stylesheet for my scrollbar stylings and I want to put it in with the rest of my styles on my root component. I have tried this...

const styles = (theme: Theme) =>
  createStyles({
    scrollBar: {
      '&::-webkit-scrollbar': {
        width: '0.4em'
      },
      '&::-webkit-scrollbar-track': {
        '-webkit-box-shadow': 'inset 0 0 6px rgba(0,0,0,0.00)'
      },
      '&::-webkit-scrollbar-thumb': {
        backgroundColor: 'rgba(0,0,0,.1)',
        outline: '1px solid slategrey'
      }
    }
  });

and then adding the class to root component div. I am using the withStyles HOC and the other styles there are being applied, so I know it is working, but I cannot figure out how to get at the scroll bar styles. Is there any way to do this?

<div className={classes.scrollBar} />


Solution 1:[1]

Since you want to do this globally, you may want to follow what CssBaseline does in it source code: https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/CssBaseline/CssBaseline.js

const styles = theme => ({
  '@global': {
    '*::-webkit-scrollbar': {
      width: '0.4em'
    },
    '*::-webkit-scrollbar-track': {
      '-webkit-box-shadow': 'inset 0 0 6px rgba(0,0,0,0.00)'
    },
    '*::-webkit-scrollbar-thumb': {
      backgroundColor: 'rgba(0,0,0,.1)',
      outline: '1px solid slategrey'
    }
  }
});

it looks like the top-level/global selector to use is @global.

Solution 2:[2]

I would recommend to apply scrollbar styles only for the specific container, cause @Global may take rendering time to apply on the All elements. This works fine as for me

list: {
  overflowY: "auto",
  margin: 0,
  padding: 0,
  listStyle: "none",
  height: "100%",
  '&::-webkit-scrollbar': {
    width: '0.4em'
  },
  '&::-webkit-scrollbar-track': {
    boxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
    webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)'
  },
  '&::-webkit-scrollbar-thumb': {
    backgroundColor: 'rgba(0,0,0,.1)',
    outline: '1px solid slategrey'
  }
}

Solution 3:[3]

For me I just wanted to change the scrollbar settings globally, so based on the sample provided here: typography-html-font-size

You can use some approach like this for building your theme:

createMuiTheme({
  overrides: {
    MuiCssBaseline: {
      '@global': {
        '*': {
          'scrollbar-width': 'thin',
        },
        '*::-webkit-scrollbar': {
          width: '4px',
          height: '4px',
        }
      }
    }
  }
})

Then just pass the created object to ThemeProvider. ThemeProvider document

Solution 4:[4]

None of the previous 4 answers gives a simple copy/paste solution that works right away for mui v4 or v5 and CssBaseline. So heres mine

For v4:

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

const theme = createTheme({
  overrides: {
    MuiCssBaseline: {
      "@global": {
        body: {
          scrollbarColor: "#6b6b6b #2b2b2b",
          "&::-webkit-scrollbar, & *::-webkit-scrollbar": {
            backgroundColor: "#2b2b2b",
          },
          "&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
            borderRadius: 8,
            backgroundColor: "#6b6b6b",
            minHeight: 24,
            border: "3px solid #2b2b2b",
          },
          "&::-webkit-scrollbar-thumb:focus, & *::-webkit-scrollbar-thumb:focus": {
            backgroundColor: "#959595",
          },
          "&::-webkit-scrollbar-thumb:active, & *::-webkit-scrollbar-thumb:active": {
            backgroundColor: "#959595",
          },
          "&::-webkit-scrollbar-thumb:hover, & *::-webkit-scrollbar-thumb:hover": {
            backgroundColor: "#959595",
          },
          "&::-webkit-scrollbar-corner, & *::-webkit-scrollbar-corner": {
            backgroundColor: "#2b2b2b",
          },
        },
      },
    },
  },
});

export default theme;

So, If you are using CssBaseline at the top of your app, then just put the overrides object into your global theme and it will work fine.

If you got your hands on the beta v5 of mui, then use this in your global theme:

// optional for better type support
import type {} from "@mui/lab/themeAugmentation";

import { createTheme } from "@mui/material/styles";

const theme = createTheme({
  components: {
    MuiCssBaseline: {
      styleOverrides: {
        body: {
          scrollbarColor: "#6b6b6b #2b2b2b",
          "&::-webkit-scrollbar, & *::-webkit-scrollbar": {
            backgroundColor: "#2b2b2b",
          },
          "&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
            borderRadius: 8,
            backgroundColor: "#6b6b6b",
            minHeight: 24,
            border: "3px solid #2b2b2b",
          },
          "&::-webkit-scrollbar-thumb:focus, & *::-webkit-scrollbar-thumb:focus": {
            backgroundColor: "#959595",
          },
          "&::-webkit-scrollbar-thumb:active, & *::-webkit-scrollbar-thumb:active": {
            backgroundColor: "#959595",
          },
          "&::-webkit-scrollbar-thumb:hover, & *::-webkit-scrollbar-thumb:hover": {
            backgroundColor: "#959595",
          },
          "&::-webkit-scrollbar-corner, & *::-webkit-scrollbar-corner": {
            backgroundColor: "#2b2b2b",
          },
        },
      },
    },
  },
});

Solution 5:[5]

The simplest one is to use the following code in your app.css file and import it to your App.js :

::-webkit-scrollbar {
  width: 5px;
}

/* Track */
::-webkit-scrollbar-track {
  background: #f1f1f1;
}

/* Handle */
::-webkit-scrollbar-thumb {
  background: #888;
}

/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
  background: #555;
}

Solution 6:[6]

    const useStyles = makeStyles((theme) => ({
     
    
        DetailedCard: {
            height: theme.spacing(60),
            display: 'flex',
            flexDirection: 'column',
            overflow: 'scroll',
            '&::-webkit-scrollbar': {
             width:0.5px
            },
           '&::-webkit-scrollbar-thumb': {
               width:0.5px
            },
        },
    }))

Solution 7:[7]

You don't even need to use createTheme, just use GlobalStyles in MUI v5, this is more reusable:

<GlobalStyles
  styles={{
    '*::-webkit-scrollbar': {
      width: '0.4em',
    },
    '*::-webkit-scrollbar-track': {
      '-webkit-box-shadow': 'inset 0 0 6px rgba(0,0,0,0.00)',
    },
    '*::-webkit-scrollbar-thumb': {
      backgroundColor: 'rgba(0,0,0,.1)',
      outline: '1px solid slategrey',
    },
  }}
/>

Or if you want to use a scrollbar in dark theme, MUI has one for you out-of-the-box:

import darkScrollbar from '@mui/material/darkScrollbar';
<GlobalStyles styles={{ ...darkScrollbar() }} />

Live Demo

Codesandbox Demo

Solution 8:[8]

Update March 2022

In MUI@5 the easiest way the achieve scroll adjusted to dark/light theme is to use Color Scheme in CssBaseline which works in Chrome, Edge & FF

https://mui.com/components/css-baseline/#color-scheme

<CssBaseline enableColorScheme />

CSB for thin scroller for light/dark mode for Chrome, Edge, FF & Safari:

https://codesandbox.io/s/material-ui-toggle-dark-light-mode-scrollbar-t542f7?file=/demo.tsx

More details:

if you want nice thin scroll you can use scroll-width: "thin"

https://caniuse.com/mdn-css_properties_scrollbar-width

but for now in works only in FF

darkScrollbar from MUI makes nice thin dark scrollbar in Edge & Chrome, but not in FF

darkScrollbar has also 3 available options, so we can combine those two methods and pass grey colors for light mode:

import { grey } from "@mui/material/colors";
import { darkScrollbar } from "@mui/material";
...

MuiCssBaseline: {
    styleOverrides: {
      html: {
        ...darkScrollbar(
          mode === "light"
            ? {
                track: grey[200],
                thumb: grey[400],
                active: grey[400],
              }
            : undefined
        ),
        //scrollbarWidth for Firefox
        scrollbarWidth: "thin",
      },
    },
},

Solution 9:[9]

This configuration works well for Material UI v4 on modern Chrome and Firefox browsers.

const theme = createTheme({
  overrides: {
    MuiCssBaseline: {
      '@global': {
        '*': {
          scrollbarWidth: 'thin',
          scrollbarColor: '#B7B7B7 transparent',
          '&::-webkit-scrollbar': {
            width: 6,
            height: 6,
            backgroundColor: 'transparent',
          },
          '&::-webkit-scrollbar-track': {
            backgroundColor: 'transparent',
          },
          '&::-webkit-scrollbar-thumb': {
            borderRadius: 6,
            backgroundColor: '#B7B7B7',
            minHeight: 24,
            minWidth: 24,
          },
          '&::-webkit-scrollbar-thumb:focus': {
            backgroundColor: '#adadad',
          },
          '&::-webkit-scrollbar-thumb:active': {
            backgroundColor: '#adadad',
          },
          '&::-webkit-scrollbar-thumb:hover': {
            backgroundColor: '#adadad',
          },
          '&::-webkit-scrollbar-corner': {
            backgroundColor: 'transparent',
          },
        },
      },
    },
  },
});

Solution 10:[10]

In MUI v5 for the specific element you can simply use:

<Box sx={{
  overflow:"auto",
  scrollbarWidth: 'thin',
  '&::-webkit-scrollbar': {
    width: '0.4em',
  },
  '&::-webkit-scrollbar-track': {
    background: "#f1f1f1",
  },
  '&::-webkit-scrollbar-thumb': {
    backgroundColor: '#888',
  },
  '&::-webkit-scrollbar-thumb:hover': {
    background: '#555'
  }
  }}>
</Box>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Artem Luzhanovskyi
Solution 3 user487779
Solution 4
Solution 5 Tina
Solution 6
Solution 7 NearHuscarl
Solution 8
Solution 9 Burak Ă–zdemir
Solution 10 Abdul Rehman