스티키 푸터

Sticky footer

내용이 짧아도 화면 맨 아래에 붙고, 내용이 길어지면 자연스럽게 그 아래로 밀리는 푸터 배치법.

다른 이름: Footer pinned to bottomFull-height layout
···
html
<div class="page" id="page">
  <header>Header</header>
  <main id="main"></main>
  <footer>Footer — always at the bottom</footer>
</div>
css
.page{width:min(64%,240px);height:min(92%,300px);border:1px solid var(--line);border-radius:12px;overflow:hidden;
  display:flex;flex-direction:column;box-shadow:0 8px 24px rgba(0,0,0,.12);background:var(--bg)}
header{background:var(--surface);border-bottom:1px solid var(--line);padding:10px;font-size:11px;font-weight:700;text-align:center}
main{flex:1 0 auto;padding:12px;display:flex;flex-direction:column;gap:8px;overflow-y:auto}
main .ln{display:block;height:8px;border-radius:3px;background:var(--surface);border:1px solid var(--line);flex-shrink:0}
footer{background:var(--accent);color:#fff;padding:10px;font-size:9px;font-weight:700;text-align:center;flex-shrink:0}
js
const main = document.getElementById('main');
function render(n) {
  main.innerHTML = '';
  for (let i = 0; i < n; i++) {
    const ln = document.createElement('i');
    ln.className = 'ln';
    main.appendChild(ln);
  }
}
let long = false;
render(2);
setInterval(() => {
  long = !long;
  render(long ? 9 : 2);
}, 2200);

콘텐츠가 짧은 페이지에서 흔히 생기는 문제입니다 — 푸터가 문서 흐름을 그대로 따라가면, 본문이 짧을 땐 화면 중간에 붕 떠버립니다. 해결책은 페이지 전체를 `display: flex; flex-direction: column; min-height: 100%`로 감싸고, 본문 요소에 `flex: 1`을 주는 것입니다. 본문이 짧으면 `flex: 1`이 남는 세로 공간을 전부 흡수해서 푸터를 화면 끝까지 밀어내고, 본문이 길면 그냥 콘텐츠만큼 커져서 푸터는 자연스럽게 그 아래에 옵니다.

과거엔 `position: absolute; bottom: 0`으로 억지로 고정하는 방법을 많이 썼지만, 이 경우 본문이 푸터 높이만큼 가려지지 않도록 `padding-bottom`을 수동으로 맞춰야 하고 푸터 높이가 바뀌면 다시 깨집니다. Flexbox 방식은 높이를 하드코딩할 필요가 없어서 더 안전합니다.

CSS Grid로도 똑같이 됩니다 — 부모에 `grid-template-rows: auto 1fr auto`를 주고 헤더·본문·푸터를 순서대로 놓으면 됩니다. 어느 쪽이든 핵심은 "본문에게 남는 공간을 몰아준다"는 한 문장으로 요약됩니다.

언제 쓰나

콘텐츠 길이가 페이지마다 다른 사이트(빈 검색 결과, 로그인 폼 등)에서는 사실상 기본값으로 깔아둬야 합니다. 콘텐츠가 항상 뷰포트보다 길다는 게 확실하면 신경 쓸 필요 없습니다.