앞서 테스트 구현한 다락에서 추가로 구현해보고 싶은 UI가 있어서 window.outerHeight / window.innerHeight / window.scrollY를 활용하여 구현하였다.
예제 사이트 화면
아래 화면에서 우측에 있는 "신규 지점 오픈특가 알림" 팝업창이 스크롤을 내려도 스무스하게 이동하면서 고정되는 UI가 마음에 들어서 구현해 보았다.
구현 코드 및 실행 화면
스크롤 내렸을 때 화면 우측에 팝업창을 고정하려면 transform: translate(x, y)에서 y를 조정해주어야 하기 때문에
아래 식을 사용하여 translate의 y를 조정해 주었다. + 잊지 말고 transition: transform 0.3s ease;도 넣기⭐
window.outerHeight - window.innerHeight + window.scrollY
window.outerHeight (브라우저 전체 높이 / 메뉴, 툴바, 스크롤바 포함)
window.innerHeight (브라우저 화면의 높이, viewport)
window.scrollY (현재 스크롤 위치)
더보기
- MiniBanner.jsx
import { useEffect, useRef, useState } from "react";
import styles from "./MiniBanner.module.css";
const MiniBanner = (props) => {
const [scroll, setScroll] = useState(0);
const miniBannerRef = useRef();
// - scroll 이벤트 생성 및 해제
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
useEffect(() => {
// window.outerHeight : 브라우저 전체의 높이(메뉴, 툴바, 스크롤바 포함)
// window.innerHeight : 브라우저 화면의 높이(viewport)
// window.scrollY : 현재 scroll 위치
if (scroll === 0) {
miniBannerRef.current.style = `transform: translate(0px, 500px);`;
} else {
const move = window.outerHeight - window.innerHeight + scroll;
// 브라우저 전체의 높이 - 브라우저 화면의 높이 + 현재 scroll 위치
miniBannerRef.current.style = `transform: translate(0px, ${move}px);`;
}
}, [scroll]);
const handleScroll = () => {
setScroll(window.scrollY);
};
return (
<div className={styles.wrap}>
<h2>미니 배너 테스트</h2>
<div className={styles.miniBannerWrap} ref={miniBannerRef}>
미니 배너
</div>
</div>
);
};
export default MiniBanner;
- MiniBanner.module.css
.wrap {
margin: 0 20px;
position: relative;
height: 300vh;
}
.miniBannerWrap {
width: 200px;
height: 200px;
color: white;
font-weight: 800;
line-height: 200px;
text-align: center;
border: 1px solid #e1e1e1;
border-radius: 12px;
background: tomato;
position: absolute;
top: 0px;
right: 20px;
transform: translate(0px, 500px);
transition: transform 0.3s ease;
}
window.# 참고 블로그
'프레임워크 > CSS' 카테고리의 다른 글
[CSS] animation : running로 컨텐츠 반복 애니메이션 구현하기 (0) | 2023.06.08 |
---|---|
[CSS] @container (0) | 2022.06.08 |
[CSS] Cascade Layers (0) | 2022.06.08 |
[CSS] Input 태그 > 자동완성 해제 및 입력 기록 제거 (0) | 2022.04.15 |
[CSS] text 마우스 드래그 시 CSS 설정 (::selection) (0) | 2022.04.15 |
댓글