반응형
web 개발하다 보면 여러가지 디바이스에서 자신이 개발한 화면이 잘 호환되면서 나오는지 확인하면서 개발하는게 굉장히 중요합니다.
모바일 화면에서 어떠한 모달을 띄우는데 모달의 크기가 큰 경우 모바일 웹 브라우저 네비바로 인하여 모달이 가려지는 현상이 종종 생기는데요 오늘은 이런문제 해결하는 방법을 작성해 보겠습니다.
문제 :
pc 버전(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 컴포넌트에 있습니다.
반응형
'React' 카테고리의 다른 글
React 효과적인 비동기 처리 (0) | 2023.02.11 |
---|---|
기존 프로젝트 React 17에서 React 18로 업그레이드하기 (0) | 2023.02.02 |
[React 공식문서 공부] React로 생각하기 (1) | 2023.01.29 |
[React 공식문서 공부] JSX란? (0) | 2023.01.29 |
댓글