'How to change navbar background color in react when I scroll
I would like to make my navbar start out as transparent but when a user scrolls the navbar will change color / background-color. I am using a bootstrap navbar and react.
jsx code:
import React, { Component } from 'react';
import '../css/nav.scss';
import { Link, NavLink } from 'react-router-dom';
import 'react-bootstrap';
class Navbar extends Component {
state = {};
render() {
return (
<nav className="navbar sticky-top navbar-expand-lg ">
<NavLink
to="/"
class="navbar-brand"
activeClassName="navbar-brand--active"
>
Web_Env
</NavLink>
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarNavDropdown"
aria-controls="navbarNavDropdown"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="#">
Create post
</a>
</li>
</ul>
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<NavLink
to="/login"
className="nav-link"
activeClassName="nav-link--active"
>
Login
</NavLink>
</li>
<li className="nav-item">
<NavLink
to="/register"
className="nav-link"
activeClassName="nav-link--active"
>
Register
</NavLink>
</li>
</ul>
</div>
</nav>
);
}
}
export default Navbar;
css code:
$color1: #aceca1;
$bgcolor1: #629460;
.navbar {
background-color: $bgcolor1 !important;
.navbar-brand {
color: lighten($color1, 10%);
font-weight: bold;
font-size: 2em;
.navbar-brand--active {
color: white;
font-weight: bold;
font-size: 2em;
}
}
.nav-link {
color: $color1;
font-size: 1.1em;
transition: 200ms;
}
.nav-link--active {
color: white !important;
transform: scale(1.1);
font-weight: 10px;
}
.nav-link:hover {
color: white !important;
transform: scale(1.1);
text-decoration: none !important;
font-weight: 10px;
}
}
I have looked at a previous post about this from 2 years ago but being a beginner I didn't really understand any of it. If possible an explanations alongside the code would help me very much.
Solution 1:[1]
Here is An Example: https://codesandbox.io/s/nifty-newton-f4j0j
you can use document.scrollingElement.scrollTop
for detecting how much user scroll from top of the page.
in this case 120 from top.
you put this into the componentDidMount
and save this in a variable so u can remove this listener later in ComponentWillUnmount
.
and because this listener fired up each time scroll occurs it is good for having a better performance we check the value of the state and updated it just when it's necessary.
this.listener = document.addEventListener("scroll", e => {
var scrolled = document.scrollingElement.scrollTop;
if (scrolled >= 120) {
if (this.state.status !== "amir") this.setState({ status: "amir" })
} else {
if (this.state.status !== "top") this.setState({ status: "top" })
}
});
For anyone needs a solution using functional-based components
let listener = null
const [scrollState, setScrollState] = useState("top")
useEffect(() => {
listener = document.addEventListener("scroll", e => {
var scrolled = document.scrollingElement.scrollTop
if (scrolled >= 120) {
if (scrollState !== "amir") setScrollState("amir")
} else {
if (scrollState !== "top") setScrollState("top")
}
})
return () => {
document.removeEventListener("scroll", listener)
}
}, [scrollState])
Solution 2:[2]
You should add something like this
componentDidMount() {
document.addEventListener("scroll", () => {
const backgroundcolor = window.scrollY < 100 ? "red" : "blue";
this.setState({ navBackground: backgroundcolor });
});
}
to your code.
The scroll event fires when the document view or an element has been scrolled.
check this sample
Solution 3:[3]
In js
useEffect(() => {
document.addEventListener("scroll", () => {
let header = document.querySelector('.Header');
if (window.scrollY > 150) {
header?.classList.add('scrolled');
} else {
header?.classList.remove('scrolled');
}
},[]);
In Css
.Header {
/* How it will look before scrolled */
position: fixed;
background-color: #002241 !important;
/* To give smoote change */
-webkit-transition: all ease-out .5s;
-moz-transition: all ease-out .5s;
-o-transition: all ease-out .5s;
transition: all ease-out .5s;
}
.Header.scrolled {
/* How it will look when scrolled */
background-color: #FFFFFF !important;
}
The header itself:
<div className='Header'>
The Header content
</div>
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 | Alex |
Solution 3 | De Platinum Emirate |