I want a drop shadow on the navigation when it scrolls over the content on the page to easier show the difference between the content and the navigation. The drop shadow should also be applied with a transition to make it smoother.
When applying a box-shadow to the navigation after scrolling above a breakpoint, the transition of the drop shadow does not work. However, the transition works when applying the same style to the hover selector.
I am using gatsby for the project, but this is a react/js issue, just saying if there are any caveats I should know when applying this to the project with gatsby.
Notice I am using styled-components for styling the components. I am using a conditional render using 'CSS: ${condition && css-style}' syntax which works with styled-components.
I have already tried using an animation, which works, but it is run every time you scroll on the page.
class App extends Component {
constructor() {
super();
this.state = {
scrollPos: 0
};
}
componentDidMount() {
window.addEventListener("scroll", this.updateScroll);
this.updateScroll();
}
componentWillUnmountt() {
window.removeEventListener("scroll", this.updateScroll);
}
updateScroll = () =>
this.setState({ scrollPos: document.documentElement.scrollTop });
render() {
let breakpointScroll = 20;
const Header = styled.div`
position: fixed;
width: 100vw;
height: 90px;
background-color: white;
font-size: 26px;
color: coral;
text-align: center;
transition: all 200ms ease;
/* Problem here */
box-shadow: ${this.state.scrollPos >= breakpointScroll &&
"0px 1px 5px rgba(0, 0, 0, 0.25)"};
/* This seems to work perfect */
:hover {
box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.25);
}
`;
return (
<>
<Header>Header</Header>
<Text>Scroll position: {this.state.scrollPos}</Text>
{/* IGNORE, content for scroll */}
<Box />
<Box backgroundColor="lightblue" />
<Box />
{/* IGNORE, content for scroll */}
</>
);
}
}
Codesandbox link: https://codesandbox.io/s/wizardly-cray-44mri
What you need to do is to change opacity of box-shadow gradually with scroll position. Transition is operating on time, so it won't give user an expected experience - i.e. we can have a situation when a user will stop scrolling on breakpoint, and then box-shadow will appear slowly. It would be a much cooler experience if box-shadow would appear with scrolling.
That's great you're using styled components - this way we can pass a prop to component Header, which will be taken from app's state where we keep scroll position as a number.
box-shadow: ${props =>
`0px 1px 5px rgba(0, 0, 0, ${
props.scrollPos >= breakpointScroll
? `0.25`
: 0.0125 * props.scrollPos
})`};
This way we will include a breakpoint and change box-shadow's opacity along with scrolling.
Here's your working example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With