Reputation: 1774
I have a fixed header component as the two pics below illustrate. The current styling that I have is fine for when the page loads and nothing has changed. However, I want the header to have a visible border-bottom of say 1px solid black as soon as the user starts to scroll down the page. So in this case, this styling change would apply to the second pic. How can I accomplish this?
Header.js
:
const Header = props => {
return (
<header className="header-container">
<div className="logo-container">
<img className="white-logo" src={logo} alt="Food Truck TrackR logo white" />
</div>
<section className="header-section-one">
<div className="location-sub-div">
<i class="fas fa-map-marker-alt"></i>
<h3>User Location</h3>
</div>
<div className="order-sub-div">
<i class="fas fa-store"></i>
<h3>Order now</h3>
</div>
</section>
<section className="header-section-two">
<NavLink to="/dine/search" className="search-sub-div">
<i class="fas fa-search search-icon"></i>
<h3>Search</h3>
</NavLink>
<div className="acct-sub-div">
<i class="fas fa-user acct-icon"></i>
<h3>Account</h3>
</div>
</section>
</header>
)
}
Header.scss
:
.header-container {
width: 100%;
height: 9vh;
display: flex;
align-items: center;
color: black;
background: white;
font-size: 0.6rem;
padding-left: 4%;
padding-right: 4%;
position: fixed;
top: 0;
// border-bottom: 1px solid black;
z-index: 99;
}
.logo-container {
width: 20%;
margin-right: 6%;
.white-logo {
width: 100%;
}
}
.header-section-one {
width: 32%;
display: flex;
margin-right: 25%;
justify-content: space-evenly;
.location-sub-div {
display: flex;
h3 {
width: 100%;
white-space: nowrap;
}
}
.order-sub-div {
display: flex;
h3 {
white-space: nowrap;
}
}
}
.header-section-two {
width: 32%;
display: flex;
justify-content: space-evenly;
.search-sub-div {
display: flex;
.search-icon {
margin-right: 1%;
}
}
.acct-sub-div {
display: flex;
.acct-icon {
margin-right: 1%;
}
}
}
i {
margin-right: 1% !important;
}
Upvotes: 0
Views: 5797
Reputation: 2964
You can add an event listener to the document, and when a scroll event is fired, you can check to see what the vertical scroll position (scrollTop
) of the document is, and conditionally show a border based on that value.
Here's an example:
import React, { useEffect, useState } from "react";
const Header = () => {
// Store a bool that determines if the border is visible
const [isBorderVisible, setIsBorderVisible] = useState(false);
useEffect(() => {
// Define a function that is called when the scroll event fires
const handleScroll = e => {
const scrollTop = e.target.documentElement.scrollTop;
if (scrollTop > 200) {
setIsBorderVisible(true);
} else {
setIsBorderVisible(false);
}
};
// Add the event listener inside a useEffect
if (document) {
document.addEventListener("scroll", handleScroll);
}
// Remove the event listener on unmount
return () => {
if (document) {
document.removeEventListener("scroll", handleScroll);
}
};
}, [setIsBorderVisible]);
return (
<div
style={{
position: "fixed",
top: 0,
left: 0,
right: 0,
height: "100px",
background: "hotpink",
// Conditionally style the border
borderBottom: isBorderVisible ? "2px solid #000" : "0"
}}
/>
);
};
So we have a useEffect
, that adds an event listener to the document, listening for the scroll
event. Whenever a scroll occurs, the handleScroll
function (also defined inside the useEffect
) fires.
In this function, we get the scrollTop
value, which is the number of pixels that have been scrolled from the top of the document.
In the example, we are setting the state value isBorderVisible
to true
once we have a scrollTop
greater than 200 pixels, but this can be anything you want.
In the header's style, we conditionally set a border, based on the state value of isBorderVisible
.
Upvotes: 1
Reputation: 21
This neat CSS trick might help you with the problem:
html:not([data-scroll='0']) {
.header-container {
width: 100%;
height: 9vh;
display: flex;
align-items: center;
color: black;
background: white;
font-size: 0.6rem;
padding-left: 4%;
padding-right: 4%;
position: fixed;
top: 0;
border-bottom: 1px solid black;
z-index: 99;
}
}
Here is a, link further explaining the solution: https://css-tricks.com/styling-based-on-scroll-position/
Good luck.
Upvotes: 2