Post

Radix UI Popover Portal 사용 시 모달 내 스크롤이 동작하지 않는 문제 해결기

아래는 "Radix UI Popover의 Portal로 인한 모달 내 스크롤 문제 트러블슈팅"을 범용적인 용어로 정리한 마크다운 예시입니다. 문제 상황 React 프로젝트에서 Radix UI의 Popover 컴포넌트를 사용해 검색어 추천/최근 검색어 팝업을 구현했습니다. 이 컴포넌트를…

2025-06-05·PopOverPortalReactradix-ui모달스크롤오버플로우트러블슈팅

아래는 "Radix UI Popover의 Portal로 인한 모달 내 스크롤 문제 트러블슈팅"을 범용적인 용어로 정리한 마크다운 예시입니다.


문제 상황

React 프로젝트에서 Radix UI의 Popover 컴포넌트를 사용해 검색어 추천/최근 검색어 팝업을 구현했습니다. 이 컴포넌트를 모달(LayerPage 등) 내부에서 사용할 때, 팝업 내 스크롤 영역(예: 최근 검색어 리스트)이 스크롤되지 않는 현상이 발생했습니다.

  • Popover 내 스크롤 영역에 max-heightoverflow-y: auto를 적용했음에도 스크롤이 동작하지 않음

  • 동일 컴포넌트를 일반 페이지에서 사용할 때는 정상적으로 스크롤됨

원인 분석

Radix UI의 Popover는 기본적으로 Portal을 사용하여, Popover의 Content를 DOM의 최상단(body 등)으로 렌더링합니다.

이로 인해 다음과 같은 문제가 발생할 수 있습니다.

  • 모달의 부모 엘리먼트(오버레이, 컨테이너 등)에 overflow: hidden 또는 clip이 적용되어 있을 경우,

    • Popover Content가 모달의 시각적 컨텍스트를 벗어나면서 스크롤이 막히거나, 오버레이에 가려져 클릭/스크롤이 동작하지 않음
  • **body에 overflow: hidden**이 적용되는 경우,

    • Portal로 body에 렌더링된 Popover Content의 스크롤이 막힘

해결 방법

1. Portal 사용 제거

Radix UI의 Popover에서 <Popover.Portal>을 제거하여, Popover Content가 모달 내부의 DOM 트리에 렌더링되도록 변경합니다.

Before

<Popover.Root open={open} onOpenChange={onOpenChange}>
  <Popover.Anchor asChild>{anchor}</Popover.Anchor>
  <Popover.Portal>
    <Popover.Content>
      {/* ... */}
    </Popover.Content>
  </Popover.Portal>
</Popover.Root>

After

<Popover.Root open={open} onOpenChange={onOpenChange}>
  <Popover.Anchor asChild>{anchor}</Popover.Anchor>
  <Popover.Content>
    {/* ... */}
  </Popover.Content>
</Popover.Root>

2. (참고) Portal을 꼭 써야 한다면

  • Radix Popover의 container prop을 활용해, 모달 내부의 특정 DOM 노드에 Content를 렌더링하도록 지정할 수도 있습니다.

결과

  • Popover Content가 모달 내부에 렌더링되면서,

  • 스크롤 영역(overflow-y: auto)이 정상적으로 동작함

  • 모달의 오버레이/컨테이너의 overflow 스타일에 영향을 받지 않음

결론

Radix UI Popover 등 Portal 기반 컴포넌트를 모달 내부에서 사용할 때는 Portal이 의도치 않게 스크롤/레이어링 문제를 유발할 수 있으니, Portal 사용 여부를 상황에 맞게 조정하는 것이 중요합니다.