Skip to main content

Command Palette

Search for a command to run...

[트러블슈팅] Scroll to Top 버튼 및 페이지 이동 시 스크롤 맨 위 미작동 이슈 해결

Updated
•4 min read•View as Markdown
[트러블슈팅] Scroll to Top 버튼 및 페이지 이동 시 스크롤 맨 위 미작동 이슈 해결

이런 식으로 버튼들을 오른쪽 하단에 빼주었다 ✨

아무래도 글이 많아지면 스크롤을 아래로 계속 내렸다가 다시 위로 올리는 게 꽤 귀찮고 요즘 대부분의 웹사이트에서도 이 기능을 제공하고 있다..! (다들 아시다시피 😘)

근데 작동을 안 해요🙂‍↔️ ㅋㅋㅋㅋㅋㅋ

👻 기존코드

(App.jsx)

import { BrowserRouter } from 'react-router-dom'
import AppRoutes from './routes/AppRoutes'
import PageScrollToTop from './components/common/PageScrollToTop'
import { useEffect } from 'react'
import { ToastContainer } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'

function App() {

  return (
    <BrowserRouter>
      <ToastContainer position='top-center' autoClose={2000} />
      <PageScrollToTop />
      <AppRoutes />
    </BrowserRouter>
  )
}

export default App

(PageScrollToTop.jsx)

import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'

const PageScrollToTop = () => {
  const { pathname } = useLocation()

  useEffect(() => {
    window.scrollTo({
      top: 0,
      behavior: 'smooth',
    })
  }, [pathname])

  return null
}

export default PageScrollToTop

(ScrollAndWriteButton.jsx)

const ScrollBtn = () => {
  const navigate = useNavigate()
  const [showModal, setShowModal] = useState(false)

  const handleCreatePostClick = () => {
    setShowModal(true)
  }
  const handleTop = () => {
    const scrollContainer = document.querySelector('#root')
    if (scrollContainer) {
      scrollContainer.scrollTo({
        top: 0,
        behavior: 'smooth',
      })
    }
  }

(AppRoutes.jsx)

import { useEffect } from 'react'
import { Route, Routes } from 'react-router-dom'
import routes from './routes'
import Layout from './Layout'
import useAuthStore from '../store/login/useAuthStore'

const AppRoutes = () => {
  const mainPaths = ['/', '/community', '/user-post', '/job']
  const initialize = useAuthStore((state) => state.initialize)

  useEffect(() => {
    initialize()
  }, [])

  return (
    <Routes>
      {routes.map((route, index) => {
        const isMain = mainPaths.includes(route.path)

        return (
          <Route
            key={index}
            path={route.path}
            element={
              <Layout
                headerType={isMain ? 'main' : 'sub'}
                label={route.label}
                noMargin={route.noMargin}
              >
                {route.element}
              </Layout>
            }
          />
        )
      })}
    </Routes>
  )
}

export default AppRoutes

어떤게 문제지? 라고 했을 때

  • PageScrollToTop.jsx에서 window.scrollTo는 브라우저 윈도우 자체 스크롤을 조작하는데

  • 실제 스크롤은 #root나 그 안쪽 div에서 발생하고 있으면 window.scrollTo는 동작하지 않는 문제…👿

해결해보자 ‼️

  1. 스크롤이 브라우저 window에서 발생하도록 구조와 CSS를 조정했다
  html,
  body {
    @apply w-full h-full min-h-screen p-0 m-0 overflow-auto;
  }

이 부분에서

  1. h-full : 부모 요소의 높이를 따라가야만 제대로 작동함
  • html → body → #root → 그 하위 컴포넌트

  • 여기서 h-full은 부모가 정확한 높이를 가지고 있어야 의미 있음

    • 그런데 html이나 body에 h-full을 주면, 그 안의 콘텐츠가 넘쳐도 확장되지 않고 스크롤이 생기지 않음
      → 브라우저는 window 전체를 높이로 딱 맞춰버림!!!!
  1. overflow-auto는 높이가 초과될 때만 스크롤 생성

    • 그런데 위에서 h-full로 높이를 딱 맞췄기 때문에, overflow가 안 생김

    • 페이지 내용이 1000000000px이어도 body가 100vh로 고정돼 있어서 window에 스크롤이 안 생기고
      실질적으로는 자식 요소에서 스크롤이 생기거나, 아무 데서도 안 생김!!!!!!!

🤦🏻‍♀️ 어떤 관련성이 있냐고 ?

window.scrollTo는 브라우저 window 객체에 스크롤이 존재할 때만 작동하는데

→ 내가 작성한 코드에서는 실제 스크롤이 window가 아니라 내부 요소에 생겨서 window.scrollTo({ top: 0 })가 아무 반응을 하지 않게 되는 것…

🌱 수정 코드

  1. h-full, overflow-auto 제거
html,
  body {
    @apply w-full p-0 m-0;
    overflow: visible;
  }
  1. ScrollAndWriteButton.jsx 수정

    • #root를 삭제해주었다(#root는 스크롤 요소가 아니기 때문) + 실제 스크롤이 window에서 일어나고 있음
const handleTop = () => {
  window.scrollTo({
    top: 0,
    behavior: 'smooth',
  })
}

  • 위로 올라가는 버튼 완성!

  • 그리고 화면 이동시에 맨 위로 스크롤 되는 부분도 확인 👍🏻

🌱 느낀점 & 배운점

  1. 스크롤 컨테이너가 어디인지 정확히 파악하는 게 중요하다.

    • 특정 레이아웃이나 CSS 구조에 따라 내부 특정 요소가 스크롤 컨테이너가 되는 경우가 많다.!!
  • 당연히 window.scrollTo가 잘 작동할 거라 생각하고 작성했는데.. 실제 스크롤 이벤트와 스크롤 위치는 언제나 최상위 window가 아닐 수 있다는 점
  1. CSS 높이(height) 설정에 따른 스크롤 발생 원리를 이해하게 되었다

    • html, body, #root 등 부모 요소의 height: 100% 설정이 콘텐츠 확장과 스크롤 생성에 어떻게 영향을 주는지 그리고 overflow-auto와 함께 어떻게 동작하는지 실제로 경험하며 배웠다.

    • 잘못된 height 설정은 의도와 다르게 스크롤이 사라지고 이로 인해 window.scrollTo가 작동하지 않는 상황이 발생할 수 있다는 것을 깨달았다

  2. React Router에서 페이지 이동 후 스크롤 위치 초기화도 같은 맥락에서 문제를 재점검
    페이지가 전환될 때 window.scrollTo가 동작하지 않았는데! 이 문제는 스크롤 컨테이너 문제 때문임을 알게 되었고 이를 해결하기 위해 구조와 스타일을 점검하는 습관을 들여야겠다고 느꼈다.

  3. UI/UX 개선에 있어 디테일한 부분까지 놓치지 않고 점검하는 과정이 중요하다
    단순히 버튼을 띄우고 이벤트를 연결하는 것뿐 아니라 사용자가 실제 경험하는 인터랙션에 문제가 없는지 꼼꼼히 확인해야 한다는 점을 다시 한번 느꼈다.

More from this blog

[React] 클라이언트에서 이미지를 압축해보자

우리는 서버 비용을 직접 부담하고 있기 때문에 항상 최적화와 비용 절감 방법을 고민하게 된다. 현재 자유게시판이 활성화가 많이 되지는 않았지만 사용자들이 업로드하는 이미지가 평균 5MB 이상일 경우를 대비해서 클라이언트에서 이미지 압축을 진행했다. 웹에서는 크게 두 가지 방법이 있었는데 Canvas API를 직접 사용하는 방법 browser-image-compression 라이브러리를 활용하는 방법 이 있다. 여러 장점을 고려해 brow...

Oct 8, 20252 min read
[React] 클라이언트에서 이미지를 압축해보자

[책 추천] 프론트엔드 개발자라면 반드시 알아야 할 '웹 접근성' 이야기

내가 생각하는 프론트엔드 개발자는 단순히 보이는 화면만 구현하는 것을 넘어서 누구나 접근할 수 있는 웹을 만드는 데 중요한 역할을 해야 한다고 생각한다. 실무에 바로 적용하는 웹 접근성 가이드북 이번에 이 책을 받고 프엔들이 읽기에 너무 좋다고 생각해서 블로그에 추천 글까지 적게 되었다 ! 목차 Chatper1. 쉽게 이해하는 접근성 Chapter2. 웹 접근성의 기초 Chapter3. HTML 태그, 의미 있게 사용하기 Chpater4...

Jul 27, 20255 min read
[책 추천] 프론트엔드 개발자라면 반드시 알아야 할 '웹 접근성' 이야기

[Next.js] 나만의 학습 블로그 만들기#3-다국어 지원 (Feat.next-i18next)

오늘은 다국어 지원 가능한 기능 구현 과정을 적어보려고 한다. 원래는 댓글기능보다 먼저 구현하려고 했는데 ,, 갑자기 댓글기능 알아보다가 재밌어서 먼저 끝내버렸다,,,🙄 시작하기 전에 정말 어려웠다 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 어려움이 많아서 기능 적용하는 데 시간이 꽤 걸렸다 ,,, 다국어 지원 기능 나는 영어랑 일본어를 추가해줬다 ! (해외취업도 관심 있기 때문에 나중에 이력서 낼 때 도움이 되지 않을까? ..🤭) 다국어 구현 방법 구현 방...

Jul 15, 20254 min read
[Next.js] 나만의 학습 블로그 만들기#3-다국어 지원 (Feat.next-i18next)

[Next.js] 나만의 학습 블로그 만들기#4 - 댓글 기능(Feat. Giscus)

댓글기능이 있으면 무조건 재밌을 거 같아서 넣어보려고 한다🤭 아무래도 개발에 관련된 학습 블로그라서 개발자들이 많을 것으로 예상했다 ! 그래서 깃허브 이슈 기반 댓글 시스템을 기반으로 기능을 구현해보려고 한다. 👉🏻 도움이 많이 된 블로그 ! 방법 Giscus | (https://giscus.app) utterances | (https://utteranc.es) 알아봤을 때는 이렇게 두 개가 유명하다고 한다. 그럼 각각의 특징과 장...

Jul 14, 20253 min read
[Next.js] 나만의 학습 블로그 만들기#4 - 댓글 기능(Feat. Giscus)

[React] React + localStorage로 하루에 한 번만 보이는 팝업 만들기

이번 프로젝트에 설문조사 배너를 제작했는데… 흠… 뭔가 별로라는 의견이 많았다! (팀원들 의견) 🙄 디자인이 문제일까? 해서 래퍼런스를 많이 찾아봤는데 … ! 일반 웹사이트는 설문조사 배너 자체를 안 만들어요,,,🤭 충격 그 자체 ( 난 아직 멀었음 ) 그리고 알아보니깐.. 설문조사 배너는 사용자 경험을 해치기 쉬워 잘 쓰이지 않는다고 한다! 그래서 나는 모달 팝업 방식으로 전환하기로 결정했고 실무에서 자주 사용하는 패턴으로 구현했다. 방...

Jul 9, 20253 min read
[React] React + localStorage로 하루에 한 번만 보이는 팝업 만들기
S

subin-dev-blog

27 posts

끊임없이 배우기 위해 노력합니다. 🌱