스크롤을 내리다가 특정 element가 viewport를 벗어나는 순간 상단 고정되는 UI를 구현하고 싶어서 방법을 찾아봤다.
<!DOCTYPE html>
<html>
<head>
<style>
.sticky {
position: -webkit-sticky; /* Safari */
position: sticky;
top: 0;
background-color: green;
color: white;
padding: 10px;
}
</style>
</head>
<body>
<h2>Sticky Element Test</h2>
<p>Scroll down this page to see the effect</p>
<div class="sticky">I will stick to the screen when you reach my scroll position</div>
<p>Some example text..</p>
</body>
</html>
position: sticky;
를 이용하면 간단하게 구현할 수 있다.
position: sticky;
는 이 속성이 적용된 element의 parent element에 overflow 속성이 정의되어 있는 경우에 동작하지 않는다.
window.addEventListener('scroll', ...)
와 position: fixed;
를 이용하면 sticky element를 구현하는 것이 가능하다. 아래는 React에서의 사용 예시이다.
import React, { useState, useEffect, useRef } from 'react';
const MyComponent = () => {
const [isSticky, setSticky] = useState(false);
const [width, setWidth] = useState(null);
const stickyRef = useRef(null);
const checkStickiness = () => {
const rect = stickyRef.current.getBoundingClientRect();
setWidth(rect.width);
setSticky(window.pageYOffset > rect.top);
};
useEffect(() => {
window.addEventListener('scroll', checkStickiness);
return () => {
window.removeEventListener('scroll', checkStickiness);
};
}, []);
return (
<div ref={stickyRef} className={isSticky ? 'sticky' : ''} style={isSticky ? { width: `${width}px` } : {}}>
{/* 내용 */}
</div>
);
};
export default MyComponent;