clamp 함수 / 뷰포트 단위 / 최신 CSS 개발 패턴
내가 궁금했던 내용을 조사하고 GPT로 정리한 내용임
1. %와 vw의 차이
%는 부모 요소 기준
%는 부모 요소의 크기를 기준으로 계산된다.
.parent {
width: 500px;
}
.child {
width: 50%;
}
결과
부모 = 500px
50% = 250px
즉 %는 부모 요소가 기준이다.
vw는 화면(Viewport) 기준
.child {
width: 50vw;
}
브라우저 화면 너비가 1000px인 경우
50vw = 500px
부모 요소 크기와는 관계없이 현재 화면 크기를 기준으로 계산된다.
2. 실무에서 사용되는 경향
실무에서는 의외로 %를 훨씬 많이 사용한다.
레이아웃 내부 → %
화면 전체 높이 → dvh
화면 비례 크기 → vw
반응형 폰트 → vw 또는 clamp()
정사각형/원형 요소 → vmin
대표적인 사용 패턴은 다음과 같다.
첫 화면 높이
→ 100dvh
일반 컨텐츠 영역
→ 100%
화면 비례 크기
→ vw
반응형 폰트
→ vw 또는 clamp()
정사각형/원
→ vmin
3. 뷰포트 단위 정리
vw
현재 화면 너비의 1%
예를 들어 화면이
1200 × 800
이라면
1vw = 12px
10vw = 120px
화면 크기에 따라 동적으로 변경된다.
vh
현재 화면 높이의 1%
예를 들어 화면이
1200 × 800
이라면
1vh = 8px
10vh = 80px
마찬가지로 화면 크기에 따라 변경된다.
모바일에서 svh / lvh / dvh가 필요한 이유
모바일 브라우저는 주소창이 존재한다.
예를 들어 기기의 실제 높이가 800px이고 주소창이 100px이라고 가정하면
주소창 표시 중
→ 실제 보이는 화면 700px
주소창 숨김
→ 실제 보이는 화면 800px
이처럼 높이가 동적으로 변경된다.
svh (Small Viewport Height)
항상 가장 작은 높이를 사용한다.
100svh = 700px
주소창이 있든 없든 항상 700px이다.
lvh (Large Viewport Height)
항상 가장 큰 높이를 사용한다.
100lvh = 800px
주소창이 있든 없든 항상 800px이다.
dvh (Dynamic Viewport Height)
현재 실제 보이는 높이를 사용한다.
주소창 있음
100dvh = 700px
주소창 없음
100dvh = 800px
실시간으로 변경된다.
실무에서는 대부분 dvh를 사용한다.
동작 예시
초기 상태
기기 높이 = 800px
주소창 = 100px
실제 화면 = 700px
svh = 700
dvh = 700
lvh = 800
스크롤 후
기기 높이 = 800px
주소창 = 없음
실제 화면 = 800px
svh = 700
dvh = 800
lvh = 800
vmin
vw와 vh 중 더 작은 값을 사용한다.
예를 들어
1000 × 800
이면
vmin = 800 기준
.circle {
width: 20vmin;
height: 20vmin;
}
결과
20vmin = 160px
모바일
400 × 800
이면
vmin = 400 기준
20vmin = 80px
정사각형이나 원형 UI에서 자주 사용된다.
vmax
vw와 vh 중 더 큰 값을 사용한다.
1000 × 800
vmax = 1000 기준
특수한 디자인 요소나 대형 배경 텍스트에서 사용된다.
실무 사용 빈도는 매우 낮다.
4. clamp() 정리
구문
clamp(최소값, 선호값, 최대값)
예시
font-size: clamp(16px, 3vw, 32px);
의미
최소 16px
최대 32px
그 사이에서는 3vw를 기준으로 동적으로 변화
예를 들어 화면이
800 × 400
이면
1vw = 8px
3vw = 24px
결과
font-size = 24px
화면이 커지면
24px → 25px → 26px → ...
처럼 자연스럽게 증가한다.
단
최소 16px
최대 32px
범위를 벗어나지는 않는다.
clamp 등장 이전
과거에는 미디어 쿼리를 사용했다.
.title {
font-size: 24px;
}
@media (min-width: 768px) {
.title {
font-size: 36px;
}
}
@media (min-width: 1200px) {
.title {
font-size: 48px;
}
}
문제점
1.코드가 길어짐
2.브레이크포인트 증가
3.크기가 계단식으로 변화
현재 방식
.title {
font-size: clamp(24px, 3vw, 48px);
}
더 간결하고 부드럽게 변화한다.
5. 최신 CSS 개발 패턴
크기 조절
예전
font-size + @media
현재
font-size: clamp(...)
패턴
크기 조절
→ clamp()
사용 예
font-size
padding
margin
gap
width
height
화면 전체 높이
예전
height: 100vh;
현재
min-height: 100dvh;
패턴
전체 높이
→ dvh
가로 정렬
예전
float: left;
현재
display: flex;
패턴
가로 정렬
→ Flex
2차원 배치
예전
float
position
inline-block
현재
display: grid;
패턴
격자 배치
→ Grid
요소 간격
예전
margin-right: 20px;
현재
gap: 20px;
또는
gap: clamp(12px, 2vw, 32px);
패턴
요소 간격
→ gap
가운데 정렬
예전
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
현재
display: flex;
justify-content: center;
align-items: center;
패턴
가운데 정렬
→ Flex
컨텐츠 폭 제한
예전
width: 1200px;
현재
width: 100%;
max-width: 1200px;
margin: 0 auto;
패턴
컨텐츠 영역
→ width:100% + max-width
반응형 레이아웃
현재
display: flex;
display: grid;
@media
패턴
배치
→ Flex/Grid
구조 변경
→ @media
컬러 관리
현재
:root {
--primary-color: #1e88e5;
}
color: var(--primary-color);
패턴
색상 관리
→ CSS 변수
다크 모드
현재
@media (prefers-color-scheme: dark)
또는
[data-theme="dark"]
패턴
다크 모드
→ CSS 변수 + Theme
반응형 이미지
현재
img {
max-width: 100%;
height: auto;
}
패턴
이미지 반응형
→ max-width:100%
현업에서 가장 자주 보는 조합
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
.hero {
min-height: 100dvh;
}
.cards {
display: grid;
gap: clamp(16px, 2vw, 32px);
}
.title {
font-size: clamp(24px, 4vw, 64px);
}
<header>
<div class="container"></div> /* 안에 내용을 container에 정리함 이는 1200px까지 커지게 설정*/
</header>
<section class="hero"> /* 섹션은 해당 화면의 최대높이를 사용하도록 함 */
<div class="container"></div>
</section>
요약하면 다음과 같다.
크기 조절 → clamp()
전체 높이 → dvh
가로 정렬 → Flex
격자 배치 → Grid
간격 → gap
반응형 구조 → @media
컨텐츠 폭 제한 → max-width
색상 관리 → CSS 변수
이미지 → max-width:100%