min-height
요소의 최소 높이를 설정합니다. 콘텐츠가 적어도 지정된 높이 이상을 보장합니다. minh100vh로 페이지 전체 높이를 보장하는 것이 가장 대표적인 사용법입니다.
단위가 있는 클래스
minh{값}{단위} 패턴으로 다양한 단위를 사용할 수 있습니다.
| 클래스 | CSS | 설명 |
|---|---|---|
minh100px | min-height: 100px | 최소 100px |
minh200px | min-height: 200px | 최소 200px |
minh50rem | min-height: 50rem | 최소 500px (50rem) |
minh100vh | min-height: 100vh | 최소 뷰포트 전체 높이 |
minh50vh | min-height: 50vh | 최소 뷰포트 절반 높이 |
minh100p | min-height: 100% | 부모 높이의 100% 이상 |
키워드 클래스
| 클래스 | CSS | 설명 |
|---|---|---|
minha | min-height: auto | 브라우저 기본값 |
minhn | min-height: auto | 최소 높이 제한 없음 |
minhfc | min-height: fit-content | 콘텐츠에 맞춤 |
minhminc | min-height: min-content | 콘텐츠의 최소 크기 |
minhmaxc | min-height: max-content | 콘텐츠의 최대 크기 |
시각적 비교
세 상자는 모두 같은 마크업이고 내용만 다릅니다. min-height가 바닥값으로만 작동하고 천장 역할은 하지 않는다는 점을 확인해 보세요.
min-height 없음
짧은 콘텐츠
콘텐츠 크기에 맞게 줄어듦
minh10rem — minh10rem
짧은 콘텐츠
내용이 100px보다 작아도 상자 높이는 100px 아래로 내려가지 않습니다.
minh10rem — minh10rem
내용이 길어지면 상자는 지정한 최소 높이를 넘어 계속 늘어납니다. min-height는 바닥값일 뿐 상한이 아니기 때문입니다. 이 문단이 길어질수록 상자도 함께 커집니다.
내용이 100px보다 커지면 상자가 그만큼 늘어납니다. 잘리지 않습니다.
핵심
min-height는 바닥을 정할 뿐 천장을 정하지 않습니다. 높이의 상한을 두고 싶다면 max-height를, 높이를 고정하고 싶다면 height를 쓰세요.
클래스별 상세
minh100vhmin-height: 100vh
뷰포트 높이만큼을 최소 높이로 보장합니다. 내용이 길면 그 아래로 자연스럽게 이어집니다.
언제 쓰나
페이지 전체 래퍼에 적용하는 대표적인 용법입니다. 내용이 짧은 페이지에서도 푸터가 화면 중간에 떠 있지 않게 만듭니다.
<!-- Page shell that always fills the viewport -->
<div class="minh100vh dg gtrauto-1fr-auto bg0F0F17">
<header class="p2rem bb1pxsolid27272A">Header</header>
<main class="p2rem">Short content still pushes the footer down</main>
<footer class="p2rem bt1pxsolid27272A">Footer</footer>
</div>minh100pmin-height: 100%
부모 높이의 100%를 최소 높이로 삼습니다. 백분율이므로 부모의 높이가 실제로 정해져 있어야 합니다.
언제 쓰나
높이가 확정된 컨테이너 안에서 자식이 최소한 부모만큼은 차지해야 할 때 씁니다. 부모 높이가 auto라면 백분율을 해석할 기준이 없어 효과가 없습니다.
<!-- Percentage needs an ancestor chain with a resolved height -->
<div class="h40rem bg18181B br8px">
<div class="minh100p p2rem">
Fills the 40rem parent at minimum, grows past it if content is taller
</div>
</div>minhamin-height: auto
최소 높이를 브라우저 기본 계산에 맡깁니다. 일반 블록에서는 사실상 0과 같지만, flex와 grid 아이템에서는 콘텐츠 크기가 바닥값이 됩니다.
언제 쓰나
공용 컴포넌트나 상위 규칙에서 걸어 둔 최소 높이를 특정 상황에서만 해제할 때 씁니다.
<!-- Undo a minimum height inherited from a shared component -->
<div class="minha p16px bg18181B br8px">
Height is decided by the content again
</div>minh0min-height: 0
최소 높이를 0으로 명시합니다. flex와 grid 아이템의 자동 최소 크기를 무력화하는 용도로 가장 많이 쓰입니다.
언제 쓰나
flex 자식 안에 스크롤 영역을 넣었는데 스크롤이 생기지 않고 컨테이너만 늘어난다면, 그 자식에 이 클래스를 주세요. flex 아이템의 기본 최소 크기가 콘텐츠 크기라서 줄어들지 못하는 것이 원인입니다.
<!-- Let a flex child shrink so its inner area can scroll -->
<div class="df fdc h40rem">
<header class="p16px bb1pxsolid27272A">Title</header>
<!-- Without minh0 this child refuses to shrink below its content -->
<div class="fg1 minh0 oya p16px">
<p class="mb16px">Long list...</p>
</div>
</div>minhfcminhmincminhmaxc
고정된 숫자 대신 콘텐츠 크기를 기준으로 바닥값을 정합니다. min-content는 줄바꿈을 최대한 허용했을 때의 크기, max-content는 줄바꿈 없이 펼쳤을 때의 크기, fit-content는 그 사이에서 상황에 맞춘 크기입니다.
언제 쓰나
내용 길이를 미리 알 수 없는 컴포넌트에서 최소한 잘리지는 않도록 보장할 때 씁니다. 다만 세로 축에서는 브라우저 구현 차이가 있으니 실제 화면에서 확인하세요.
<!-- Floor tied to the content rather than a fixed number -->
<div class="minhminc p16px bg18181B br8px">
Never shorter than the tallest unbreakable content
</div>
<div class="minhfc p16px bg18181B br8px">
Shrink wraps the content as the floor
</div>minhnmin-height: auto
최소 높이 제한을 두지 않겠다는 선언입니다.
언제 쓰나
의미상 제한 없음을 나타낼 때 씁니다. 실무에서 최소 높이를 확실히 없애야 한다면 0을 지정하는 <code class="fs13px cC4B5FD bg1E1E2E py2px px4px br4px">minh0</code> 쪽이 더 안전합니다.
<!-- Declares no minimum height limit -->
<div class="minhn p16px bg18181B br8px">
No minimum height limit
</div>사용 예시
페이지 높이 보장, 히어로 섹션, 카드 높이 정렬의 기본 형태입니다.
<!-- Full viewport page (footer fixed at bottom) -->
<div class="minh100vh dg gtrauto-1fr-auto">
<header>Header</header>
<main>Footer stays at bottom even with little content</main>
<footer>Footer</footer>
</div>
<!-- Hero section minimum height -->
<section class="minh50vh df jcc aic bg18181B">
<h1 class="cFAFAFA fs4rem">Hero Title</h1>
</section>
<!-- Card minimum height guaranteed -->
<div class="dg gtcr3-1fr gap2rem">
<div class="minh20rem bg18181B p2rem br8px">Card 1</div>
<div class="minh20rem bg18181B p2rem br8px">Card 2</div>
<div class="minh20rem bg18181B p2rem br8px">Card 3</div>
</div>검색 결과 패널입니다. 로딩, 결과 없음, 오류 상태가 모두 같은 최소 높이를 쓰기 때문에 상태가 바뀌어도 아래 내용이 튀지 않습니다.
<!-- Results panel that does not collapse between states -->
<section class="minh30rem df fdc jcc aic bg0F0F17 b1pxsolid27272A br12px p3-2rem">
<!-- Loading, empty and error states all reuse this same floor, -->
<!-- so the page below never jumps as the state changes -->
<p class="fs2rem fw700 cFAFAFA mb8px">No results</p>
<p class="fs14px c71717A lh1-7 tac mb16px">
Try a different keyword or clear the filters.
</p>
<button class="py8px px16px bg6366F1 cFFFFFF br8px bn cp">Clear filters</button>
</section>팁
푸터를 하단에 고정하기
minh100vh를 body나 메인 래퍼에 적용하고 dg gtrauto-1fr-auto와 조합하면 콘텐츠가 적어도 푸터가 항상 화면 하단에 위치합니다.
백분율은 부모 높이가 정해져 있어야 합니다
minh100p는 부모의 높이가 확정되어 있을 때만 동작합니다. 부모 높이가 auto라면 백분율을 계산할 기준이 없어 무시됩니다. 이럴 때는 부모에 높이를 주거나 뷰포트 단위를 쓰세요.
min-height가 height와 max-height를 이깁니다
세 값이 충돌하면 min-height가 최종 승자입니다. height를 100px로 줘도 min-height가 200px이면 결과는 200px입니다. 높이가 의도대로 안 나올 때 확인해야 할 첫 번째 지점입니다.
flex 아이템의 자동 최소 크기
flex 아이템은 기본 최소 크기가 콘텐츠 크기라, 안쪽 스크롤 영역이 동작하지 않는 원인이 됩니다. 세로 방향 flex에서는 minh0을 함께 주면 해결됩니다.
모바일에서 100vh 주의
모바일 브라우저의 주소창이 접혔다 펴지면서 100vh 기준 높이가 흔들립니다. 화면에 꽉 차는 레이아웃이 필요하다면 동적 뷰포트 단위를 검토하거나, 여백이 튀어도 무방한 구조로 설계하세요.