Reputation: 53
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.
Upvotes: 3
Views: 22145
Reputation: 98
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>
Upvotes: 0
Reputation: 1504
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])
Upvotes: 12
Reputation: 3991
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
Upvotes: 0