'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
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