#root{ height: 200vh; background: #3c1671;}
@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500;600;700;800;900&display=swap');
// smart sticky header
header{
cursor: pointer;
width: 10%;
font-weight: 900;
-webkit-tap-highlight-color: transparent;
font-family: 'Rubik', sans-serif;
box-shadow: inset 0 -2px 0 0 hsla(0,0%,100%,1);
color: #fff;
position: sticky;
top: -20px;
font-size: 156px;
transition: 1.345s ease-out;
left: 4.9%;
&.isSticky{
flex-shrink: 0;
-webkit-font-smoothing: antialiased;
font-weight: 100;
-webkit-tap-highlight-color: transparent;
padding-top: 44px;
left: 34.9%;
font-size: 38px;
&::after{
line-height: calc((13vw - 320px)/860*7 + 20px);
box-shadow: inset 4px -0px 44px 98px hsla(0,0%,100%,1);
width: 60%;
content:" menu";
color: #e826ff;
}
}
}
View Compiled
const {createRef, useState, useEffect} = React
function Header({ children, sticky=false, className, ...rest }){
const [isSticky, setIsSticky] = useState(false)
const ref = React.createRef()
// mount
useEffect(()=>{
const cachedRef = ref.current,
observer = new IntersectionObserver(
([e]) => setIsSticky(e.intersectionRatio < 1),
{threshold: [1]}
)
observer.observe(cachedRef)
// unmount
return function(){
observer.unobserve(cachedRef)
}
}, [])
return (
<header className={className + (isSticky ? " isSticky" : "")} ref={ref} {...rest}>
{children}
</header>
)
}
function App(){
return <>
<Header>DESIGN</Header>
</>
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
View Compiled