본문 바로가기
React

React 모바일(safari, chrome)에서 100vh 네비바 로 인한 화면 가려지는 현상 해결하기

by 나하니인데 2022. 12. 9.
반응형

web 개발하다 보면 여러가지 디바이스에서 자신이 개발한 화면이 잘 호환되면서 나오는지 확인하면서 개발하는게 굉장히 중요합니다.

모바일 화면에서 어떠한 모달을 띄우는데 모달의 크기가 큰 경우 모바일 웹 브라우저 네비바로 인하여 모달이 가려지는 현상이 종종 생기는데요 오늘은 이런문제 해결하는 방법을 작성해 보겠습니다. 

문제 :

pc 버전(chrome) 모바일 뷰에서는 잘 보여지는것을 볼 수 있습니다.

pc(chrome)버전 모바일 뷰 에서 보는 모달

하지만 이제 모바일 chrome에서는 네비바 때문에 가려져서 나옵니다.

모바일 (chrome) 에서 보는 모달

이유는 모달 컨테이너 css 보면서 설명 드리겠습니다.

const Background = styled.div`
  position: absolute;
  background-color: rgba(0, 0, 0, 0.5);
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const ModalContainer = styled.div`
  width: calc(100vw - 32px);
  height: calc(100vh - 32px);
  background: rgb(25, 31, 44);
  color: white;
`;

function Modal({ setIsOpenModal }) {
  return (
    <Background>
      <ModalContainer>
        <h1>MODAL</h1>
        <button onClick={() => setIsOpenModal(false)}>
          <h2>close</h2>
        </button>
      </ModalContainer>
    </Background>
  );
}
ModalContainter 컴포넌트가 모달 인데 여기서 height: calc(100vh -32px) 지정했는데요 높이를 전체화면에서 32px 뺀 값으로 지정했습니다. 근데 모바일에서는 네비바로 인하여 가려지는 현상이 일어나는 이유는 모바일 브라우저에서는 100vh를 (상단 + 하단) 네비바 까지 다 계산해서 줘서 그렇습니다. 그래서 저희는 window 객체에 있는 innerHeight(innerWidth, innerHeight 는 창 틀 네비바 을 뺀 내용과 스크롤을 포함한 크기입니다) 프로퍼티 값으로 100vh 다시 재 정의 하면 문제를 해결할 수 있습니다.

1 ) vh 단위 재정의를 위한 함수 작성:

1. 실제 내용을 보여줄 innerHeight 크기를 100등분 해서 vh 변수에 할당한다.

2. 기존에 있던 vh 단위를 재정의 한 vh값으로 변경해준다.

  const setScreenSize = () => {
    //1
    const vh = window.innerHeight * 0.01;
    //2
    document.documentElement.style.setProperty("--vh", `${vh}px`);
  };

2 )  addEventListner 'resize' 통해서 화면이 변경될 때 동적으로 vh 단위 재정의 하기:

 화면크기가 resize 될 때마다 innerHeight 값이 변경되기 때문에 변경될 때마다 setScreenSize 호출해주자.

  useEffect(() => {
    setScreenSize();
    window.addEventListener("resize", () => setScreenSize());
    return () => window.removeEventListener("resize", setScreenSize);
  }, []);
 

3 )  ModalContainter 컴포넌트 height 값 변경된 vh값으로 변경 해 주기.

height: calc(100vh - 32px);       =>    height: calc(var(--vh, 1vh) * 100 - 32px);
const ModalContainer = styled.div`
  width: calc(100vw - 32px);
  height: calc(var(--vh, 1vh) * 100 - 32px);
  background: rgb(25, 31, 44);
  color: white;
`;

4 )  전체코드:

import { useEffect, useState } from "react";
import styled from "styled-components";

const Background = styled.div`
  position: absolute;
  background-color: rgba(0, 0, 0, 0.5);
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const ModalContainer = styled.div`
  width: calc(100vw - 32px);
  height: calc(var(--vh, 1vh) * 100 - 32px);
  background: rgb(25, 31, 44);
  color: white;
`;

function Modal({ setIsOpenModal }) {
  return (
    <Background>
      <ModalContainer>
        <h1>MODAL</h1>
        <button onClick={() => setIsOpenModal(false)}>
          <h2>close</h2>
        </button>
      </ModalContainer>
    </Background>
  );
}

export default function Section1() {
  const [isOpenModal, setIsOpenModal] = useState(false);

  const handleOpenModal = () => {
    setIsOpenModal(true);
  };
  const setScreenSize = () => {
    //1. 실제 내용을 보여줄 innerHeight 크기를 100등분 해서 vh 변수에 할당한다.
    const vh = window.innerHeight * 0.01;
    //2. 기존에 있던 vh 단위를 재정의 한 vh값으로 변경해준다.
    document.documentElement.style.setProperty("--vh", `${vh}px`);
  };

  useEffect(() => {
    setScreenSize();
    window.addEventListener("resize", () => setScreenSize());
    return () => window.removeEventListener("resize", setScreenSize);
  }, []);

  return (
    <section>
      {isOpenModal && <Modal setIsOpenModal={setIsOpenModal} />}
      <header>
        <h2>
          모바일(safari, chrome)에서 100vh 네비바 로 인한 화면 가려지는 현상
          해결하기
        </h2>
      </header>
      <button onClick={handleOpenModal}>모달 열람</button>
    </section>
  );
}

 

해결 : 

네비바 가림 현상 해결

전체코드: https://github.com/sungmin-choi/react18/tree/main/src  section1 컴포넌트에 있습니다.

반응형

댓글