[✨포트폴리오] 모바일 환경에서 100vh 이슈

JiEun·2023년 9월 26일
1

포트폴리오

목록 보기
2/5

✏️ 시작

포트폴리오 사이트가 거의 완성 되었을 때
반응형을 위해 모바일로 확인하니 위아래 툴 바가 가려지는 이슈가 있었다.

메인 height를 100vh으로 설정했다.
vh단위는 viewport height으로 스크린 높이에 맞춰 설정해 주는 것이다.

100vh로 설정하면 스크린 높이에 맞춰 전부 채워준다.

현재 보여지는 배경과 이미지 사이즈는 vh단위로 설정해
높이에 따라 배경과 이미지 사이즈 변하는걸 알 수 있다.

첫 메인 화면에서 유저가 스크롤 내릴 수 있도록 하단에 표시 했다.

하지만 모바일 환경에서 확인할 경우 브라우저 툴바로 인해 가려지는 이슈가 발생하게 됐다.

모바일 브라우저 위, 아래 툴바 가 100vh에 적용되지 않고 가려지는 문제였다.

100vh가 모바일 브라우저 환경에서 적용되지 않는다고 한다.

✨ 해결

구글링해보니 css만으로도 해결을 할 수 있다고 한다.

허나 시도해 봤지만 해결 되지 않았고,
스크립트와 css를 같이 수정하는 방법을 찾아 냈다.

참고한 사이트

Tip-모바일-브라우저에서-100vh-적용-오류-해결-iosandroid @edie_ko님

사이트를 참고해 해결할 수 있었다.

// 해당 파일에 적용
let vh = 0;

useEffect(() => {
  vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
}, []);
//원하는 영역에 스타일
height: calc(var(--vh, 1vh) * 100);
/* 전역 스타일 설정*/
:root {
   --vh: 100%;
}

html,
body {
    height: 100vh;
    height: var(--vh);
}

❗️ 잘 작동하나 여기서 문제가 생겼다.

Assignments to the 'vh' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect.eslintreact-hooks/exhaustive-deps
(property) innerHeight: number

EsLint가 경고를 하고 있었다.

vh를 useEffect 외부에서 변수로 선언하면 React 컴포넌트의 각 렌더링에서 0으로 다시 초기화됩니다.
이것은 useEffect 내부에서 할당한 값이 각 렌더링 후에 손실되고 예상대로 보존되지 않을 것을 의미합니다.

useRef훅을 사용하여 vh 값을 저장해야 한다고 한다.

  const vhRef = useRef(0);

  useEffect(() => {
    vhRef.current = window.innerHeight * 0.01;
    document.documentElement.style.setProperty('--vh', `${vhRef.current}px`);
    
  }, []);

허나 웹 환경에서도 적용이 되는 이슈로 스크린 넓이로 조건문을 주려고 했으나 해결되지 않았다.

알아보니 navigator를 이용해 모바일 환경을 알 수 있는 방법이 있었다.

참고한 사이트

react 에서 모바일 웹인지 확인하는 방법 @glevel님

 const vhRef = useRef(0);
  const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);

  useEffect(() => {
    if (isMobile) {
      vhRef.current = window.innerHeight * 0.01;
      document.documentElement.style.setProperty('--vh', `${vhRef.current}px`);
    }
  }, [isMobile]);

isMobile를 콘솔로 확인하니 boolean으로 값을 반환했다.

isMobile가 true인 경우에만 해당 코드가 실행하도록 수정하고
props로 내려줘 이미지 스타일도 수정했다.

type IsMobile = {
  isMobile: boolean
}

export const Img = tw.img<IsMobile>`
  absolute
  bottom-0
  w-auto
  h-[calc(100vh-40vh)]
  transition-all

  ${props => props.isMobile ? 'max-sm:h-[calc(var(--vh,1vh)*60)]' : 'max-sm:h-[calc(100vh-40vh)]'}
`;

✏️ 마치며


그렇게 이미지 사이즈도 잘 맞고 하단 화살표 아이콘도 잘리지 않고 잘 보이는 걸 확인했다.

카카오톡 링크로도 확인했을 때도 잘 보였다..! ㅎㅎ

아마 해당 코드는 유용하게 사용할 것 같아 블로그로 남겨둔다.

profile
💻 프론트엔드를 목표로 성장 중! (알아봤던 내용 등을 정리하기)

0개의 댓글