1vh를 구하는 이유와 100vh의 정확한 의미

calm·2025년 6월 29일
0

GSAP애니메이션

목록 보기
2/8

1단계: 왜 1vh를 구하려고 하는가?

픽셀 단위의 한계

/* 픽셀 단위의 문제점 */
.section {
  height: 600px;  /* 모든 화면에서 항상 600px */
}

/* 결과: */
/* 800px 화면: 600px = 화면의 75% 차지 (적당함) */
/* 400px 화면: 600px = 화면보다 큼 (넘침) */  
/* 1200px 화면: 600px = 화면의 50% (너무 작음) */

vh 단위의 해결책

/* vh 단위의 장점 */
.section {
  height: 75vh;  /* 모든 화면에서 항상 화면의 75% */
}

/* 결과: */
/* 800px 화면: 75vh = 600px (75%) */
/* 400px 화면: 75vh = 300px (75%) */
/* 1200px 화면: 75vh = 900px (75%) */

1vh가 필요한 이유

// 1vh = 화면 높이의 기본 단위 (1%)
// 다른 vh 값들은 1vh의 배수로 계산

1vh = 화면의 1%
10vh = 1vh × 10 = 화면의 10%  
50vh = 1vh × 50 = 화면의 50%
100vh = 1vh × 100 = 화면의 100%
300vh = 1vh × 300 = 화면의 300%

2단계: 100vh의 정확한 의미

100vh ≠ 브라우저 전체 높이

브라우저 창 전체
┌─────────────────────────┐ ← window.outerHeight (전체 브라우저)
│ 제목표시줄              │
├─────────────────────────┤  
│ 주소창, 탭바, 도구모음  │ ← 이 부분들 제외
├─────────────────────────┤ ↑
│                         │ │
│   실제 콘텐츠 영역      │ │ window.innerHeight 
│   (viewport)            │ │ = 100vh
│                         │ │ (실제 웹페이지 보이는 부분)
│                         │ │
└─────────────────────────┘ ↓

viewport의 정확한 정의

// viewport = 실제 웹 콘텐츠가 렌더링되는 영역
console.log('전체 브라우저 높이:', window.outerHeight);  // 900px
console.log('viewport 높이:', window.innerHeight);       // 800px  
console.log('차이:', window.outerHeight - window.innerHeight); // 100px (UI 요소들)

// 100vh = window.innerHeight = viewport 높이

3단계: 실제 측정으로 확인하기

브라우저 콘솔에서 테스트

// 현재 브라우저에서 실행해보세요
console.log('=== 브라우저 크기 측정 ===');
console.log('전체 브라우저 높이:', window.outerHeight);
console.log('viewport 높이 (100vh):', window.innerHeight);
console.log('주소창+탭바 높이:', window.outerHeight - window.innerHeight);

// 예시 결과:
// 전체 브라우저 높이: 900
// viewport 높이 (100vh): 820  
// 주소창+탭바 높이: 80

CSS 테스트

<!-- 100vh 테스트 -->
<div style="height: 100vh; background: red; border: 2px solid black;">
  이 빨간 박스가 viewport 전체 높이 (100vh)
</div>

<!-- 결과: 스크롤 없이 화면에 딱 맞게 표시됨 -->

4단계: ScrollTrigger에서 300vh를 사용하는 이유

사용자 경험 설계

ScrollTrigger.create({
  trigger: introCard,
  start: "top top",
  end: "+=300vh",    // 화면 3개 분량의 스크롤
  onUpdate: (self) => {

300vh = 충분한 애니메이션 시간

[1번째 화면] 100vh - 이미지가 작고 둥근 상태
     ↓ 스크롤
[2번째 화면] 100vh - 이미지가 점점 커지면서 변형
     ↓ 스크롤  
[3번째 화면] 100vh - 이미지가 최대 크기, 사각형으로 완성
     ↓
애니메이션 완료

왜 하필 300vh인가?

// 100vh: 너무 빠름 (1번 스크롤로 끝)
// 200vh: 적당하지만 약간 빠름
// 300vh: 충분히 천천히 변화 관찰 가능 ✓
// 500vh: 너무 김 (사용자가 지루해함)

5단계: 반응형 디자인에서 vh의 가치

다양한 기기에서 일관된 경험

/* 모든 섹션을 화면 높이에 맞춤 */
.hero-section { height: 100vh; }      /* 첫 화면 전체 */
.content-section { height: 80vh; }    /* 화면의 80% */  
.footer-section { height: 20vh; }     /* 화면의 20% */

기기별 결과

아이폰 (844px):
- hero: 844px
- content: 675px  
- footer: 169px

데스크탑 (1080px):  
- hero: 1080px
- content: 864px
- footer: 216px

→ 비율은 동일하지만 실제 크기는 화면에 맞게 조절

6단계: 1vh 계산이 중요한 이유

정밀한 애니메이션 제어

// ScrollTrigger에서 진행률별 계산
onUpdate: (self) => {
  const progress = self.progress; // 0.0 ~ 1.0
  
  // progress와 vh를 조합한 정밀한 계산
  let currentVH = window.innerHeight / 100;  // 1vh 크기
  let animationDistance = currentVH * 300;   // 300vh 거리
  let currentPosition = animationDistance * progress;
  
  // 예: progress 0.5일 때
  // currentPosition = (10.8px × 300) × 0.5 = 1620px
}

브라우저 호환성

// 구형 브라우저에서 vh 지원 안 할 때 폴백
function getVH(amount) {
  if (CSS.supports('height', '1vh')) {
    return `${amount}vh`;  // 모던 브라우저
  } else {
    return `${(window.innerHeight / 100) * amount}px`; // 폴백
  }
}

console.log(getVH(300)); // "300vh" 또는 "2400px"

7단계: 모바일에서의 특별한 문제

모바일 브라우저의 vh 문제

// iOS Safari의 문제: 주소창이 사라지면 vh가 변함
초기 상태 (주소창 있음): 100vh = 635px
스크롤  (주소창 없음): 100vh = 695px

// 해결책: 실제 높이 고정
function setVH() {
  let vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
}

window.addEventListener('resize', setVH);
setVH();

CSS 활용

/* 안정적인 vh 사용법 */
.full-height {
  height: 100vh; /* 폴백 */
  height: calc(var(--vh, 1vh) * 100); /* 정확한 값 */
}

핵심 정리

1vh를 구하는 이유

  1. 반응형 디자인: 화면 크기에 비례하는 크기 계산
  2. 정밀한 제어: 다양한 vh 값 (50vh, 300vh 등) 계산의 기초
  3. 일관성: 모든 기기에서 동일한 비율 유지
  4. 애니메이션: progress와 결합하여 부드러운 변화 구현

100vh의 정확한 의미

  • 100vh = viewport 전체 높이
  • viewport = 실제 콘텐츠가 보이는 영역
  • ≠ 브라우저 전체 창 크기
  • = window.innerHeight

일상생활 비유

TV 화면 (전체 기기) vs 실제 영상 영역 (viewport)
┌─────────────────────┐ ← TV 전체 (outerHeight)
│ [전원] [음량] [채널] │ ← 버튼들 (브라우저 UI)
├─────────────────────┤
│                     │ ← 실제 영상 (viewport = 100vh)
│   영화 화면 영역    │
│                     │
└─────────────────────┘

이제 vh 단위의 목적과 100vh의 정확한 의미를 이해하셨나요?

profile
공부한 내용을 기록합니다

0개의 댓글