What I'm trying to achieve is the navbar on ufc.com
I've got everything I want so far except the CSS transition only works when returning to the original width. So when I scroll down the width snaps to 100% without transition.
Basically I am using a flex display encapsulating my navbar with two spacer divs on the left and right so that the transition expands and shrinks evenly on both sides.
In my React Navbar class I have a scroll event listener which adds a classname to to my nav items.
import React, { useEffect, useState } from 'react';
import { Navbar, NavItem } from 'reactstrap';
import './Nav.css';
function Nav() {
let nav = 'nav';
let spacer = 'spacer';
const [scrolled, setScrolled] = useState();
const handleScroll = () => {
setScrolled(document.documentElement.scrollTop);
};
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
});
if (scrolled > 0) {
nav = 'nav scrolled';
spacer = 'spacer scrolled';
}
return (
<div className='nav-container'>
<div className={spacer} />
<Navbar className={nav}>
<div className='items-box'>
<NavItem className='nav-item'>Projects</NavItem>
<NavItem className='nav-item'>
<strong>NAME</strong>
</NavItem>
<NavItem className='nav-item'>Resume</NavItem>
</div>
</Navbar>
<div className={spacer} />
</div>
);
}
export default Nav;
CSS
.nav-container {
display: flex;
flex-direction: row;
}
.spacer {
max-width: 20%;
width: 20%;
transition: 0.7s linear;
}
.spacer.scrolled {
width: 2%;
}
.nav {
flex: auto;
width: 100%;
color: black;
margin: auto;
background-color: white;
height: 4rem;
top: 3rem;
transition: all 0.2s;
}
.nav.scrolled {
width: 100%;
top: 0;
position: fixed;
}
.items-box {
list-style: none;
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.nav-item {
margin-left: 1rem;
margin-right: 1rem;
transition: 0.3s;
}
.nav-item:hover {
cursor: pointer;
color: forestgreen;
}
I believe my problem resides within the spacer and spacer.scrolled classes, any help would be much appreciated.
Alright I figured it out, I was just going about it the hard way as per usual. here's my new solution:
import React, { useEffect, useState } from 'react';
import { Navbar, NavItem } from 'reactstrap';
import './Nav.css';
function Nav() {
let nav = 'nav';
const [scrolled, setScrolled] = useState();
const handleScroll = () => {
setScrolled(document.documentElement.scrollTop);
};
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
});
if (scrolled > 0) {
nav = 'nav scrolled';
}
return (
<Navbar className={nav}>
<div className='items-box'>
<NavItem className='nav-item'>Projects</NavItem>
<NavItem className='nav-item'>
<strong>NAME</strong>
</NavItem>
<NavItem className='nav-item'>Resume</NavItem>
</div>
</Navbar>
);
}
export default Nav;
CSS
.nav {
align-content: center;
text-align: center;
flex: auto;
width: 60%;
color: black;
margin: auto;
background-color: white;
height: 4rem;
top: 3rem;
transition: width 0.7s linear, top 0.1s;
}
.nav.scrolled {
width: 100%;
margin: auto;
top: 0;
position: sticky;
}
.items-box {
list-style: none;
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.nav-item {
margin-left: 1rem;
margin-right: 1rem;
transition: 0.3s;
}
.nav-item:hover {
cursor: pointer;
color: forestgreen;
}
Turns out using position: fixed snaps the navbar to the left pane of the window which makes it expand un-evenly. Jut using position sticky and transitioning like so works just perfectly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.