How to Override Scroll Bar CSS Styling Globally in Next.js

Table of Contents
Introduction
This short post will go over how-to add a custom scrollbar using Material UI theme. Adding this flexibility to UIs will make your site more attractive to a variety of users and their visual preferences. However, sometimes we need to go beyond the default styling and customize our components to make them stand out a bit more. In this article, we’ll look at one of many techniques to override CSS in Next.js, letting you to take full control of your styles and create an impressive user interface.
For more detailed information on CSS in React.js please check out https://www.w3schools.com/react/react_css.asp.
Scrollbar Generators
http://webkit-scroll-gen.sourceforge.net
https://scriptgenerator.net/html-css-custom-scrollbar-code-generator
Prerequisites
MUI – Material UI v5.4.3 and Joy UI v5.0.0-alpha.42
npm install @mui/material @emotion/react @emotion/styled
Material UI Icons – Optional
npm install @mui/icons-material
Create a Example Page Containing a List
The component ScrollDemoComp.jsx renders a list inside a box with a fixed height and vertical overflow enabled.
import * as React from 'react';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import ListSubheader from '@mui/material/ListSubheader';
export default function ScrollDemoComp(props) {
return (
<List
sx={{
mt: 10,
width: '100%',
maxWidth: 360,
bgcolor: 'background.paper',
position: 'relative',
overflow: 'auto',
maxHeight: 300,
'& ul': { padding: 0 },
}}
subheader={<li />}
>
{[0, 1, 2, 3, 4].map((sectionId) => (
<li key={`section-${sectionId}`}>
<ul>
<ListSubheader>{`I'm sticky ${sectionId}`}</ListSubheader>
{[0, 1, 2].map((item) => (
<ListItem key={`item-${sectionId}-${item}`}>
<ListItemText primary={`Item ${item}`} />
</ListItem>
))}
</ul>
</li>
))}
</List>
);
}
Setting up a Global Theme in _app.js

In _app.js create a theme and store the it with useMemo(). This was the app can cache the so that it does not need to be recalculated every time it renders.
A state variable can also be defined in this section to switch between Light and Dark themes.
Source code for _app.js
import { useMemo } from 'react' ;
import CssBaseline from '@mui/material/CssBaseline';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { blue, red, teal, cyan, grey, deepOrange } from '@mui/material/colors';
import Layout from 'components/Layout';
import './custom.css';
export default function App() {
const theme = useMemo(
() =>
createTheme({
palette: {
primary: {
main: '#4674c3',
},
secondary: {
main: '#11cb5f',
},
warning: {
main: red[300],
},
dark: {
main: grey[700],
},
default: {
main: grey[50]
},
mode: 'light' ,
},
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
"&::-webkit-scrollbar, & *::-webkit-scrollbar": {
borderRadius: 10,
height: 50,
},
"&::-webkit-scrollbar-track, & *::-webkit-scrollbar-track": {
webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.3)',
borderRadius: '20px',
backgroundColor: '#F5F5F5',
marginTop: '5px',
marginBottom: '5px'
},
"&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
borderRadius: 8,
backgroundColor: "orangered",
minHeight: 24,
border: "3px solid orangered",
},
},
},
},
},
// CUSTOM BREAK POINTS - Disabled for now
// breakpoints: {
// values: {
// xs: 0,
// sm: 600,
// md: 900,
// lg: 1700,
// xl: 1720,
// },
// },
}), []);
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Component {...pageProps} />
</ThemeProvider>
);
}
CSS webkit-scrollbar
::-webkit-scrollbar

::-webkit-scrollbar-thumb

"&::-webkit-scrollbar, & *::-webkit-scrollbar": {
borderRadius: 10,
height: 50,
},
"&::-webkit-scrollbar-track, & *::-webkit-scrollbar-track": {
webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.3)',
borderRadius: '20px',
backgroundColor: '#F5F5F5',
marginTop: '5px',
marginBottom: '5px'
},
"&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
borderRadius: 8,
backgroundColor: "orangered",
minHeight: 24,
border: "3px solid orangered",
},
In App.js
Example below.
::-webkit-scrollbar can be written as scrollbarColor.
-webkit-box-shadow can be written as webkitBoxShadow.
::-webkit-scrollbar-thumb can be written as “&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb”.
::-webkit-scrollbar-thumb:focus can be written as “&::-webkit-scrollbar-thumb:focus, & *::-webkit-scrollbar-thumb:focus”.
const theme = useMemo(
() =>
createTheme({
...
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
"&::-webkit-scrollbar, & *::-webkit-scrollbar": {
borderRadius: 10,
height: 50,
},
"&::-webkit-scrollbar-track, & *::-webkit-scrollbar-track": {
webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.3)',
borderRadius: '20px',
backgroundColor: '#F5F5F5',
marginTop: '5px',
marginBottom: '5px'
},
"&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
borderRadius: 8,
backgroundColor: "orangered",
minHeight: 24,
border: "3px solid orangered",
},
},
},
},
},
...
}), [colorMode]);
Scrollbar With Gradient Colors

Adding a gradient to the scrollbar.
Example below.
const theme = useMemo(
() =>
createTheme({
palette: {
...
},
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
"&::-webkit-scrollbar, & *::-webkit-scrollbar": {
borderRadius: 10,
height: 50,
webkitBoxShadow: 'inset 2px 2px 2px hsla(0,0%,100%,.25), inset -2px -2px 2px rgba(0,0,0,.25)',
},
"&::-webkit-scrollbar-track, & *::-webkit-scrollbar-track": {
webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.3)',
borderRadius: '20px',
backgroundColor: '#F5F5F5',
marginTop: '5px',
marginBottom: '5px'
},
"&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": {
borderRadius: 10,
height: 50,
backgroundColor: "orangered",
webkitBoxShadow: 'inset 2px 2px 2px hsla(0,0%,100%,.25), inset -2px -2px 2px rgba(0,0,0,.25)',
background: 'linear-gradient(180deg,#ff8a00,#e52e71)',
},
},
},
},
},
}), []);
You must be logged in to post a comment.