클램프 레이아웃

Clamp-based sizing

`clamp(최소, 선호값, 최대)` 하나로 미디어 쿼리 없이 최소~최대 사이를 뷰포트에 비례해 매끄럽게 늘고 줄게 만드는 기법.

다른 이름: CSS clamp()Fluid sizing
···
html
<div class="area">
  <div class="viewport" id="viewport">
    <div class="box" id="box"><span id="val">–</span></div>
  </div>
  <div class="code">width: clamp(70px, 55%, 220px)</div>
</div>
css
.area{width:min(94%,480px);display:flex;flex-direction:column;align-items:center;gap:10px}
.viewport{width:26%;min-width:110px;max-width:92%;border:2px dashed var(--muted);border-radius:10px;padding:12px;
  transition:width 3s cubic-bezier(.4,0,.2,1);display:flex;justify-content:center;box-sizing:border-box}
.viewport.wide{width:92%}
.box{width:clamp(70px,55%,220px);flex-shrink:0;height:44px;border-radius:8px;background:var(--accent);display:grid;place-items:center;
  color:#fff;font:800 clamp(10px,2vmin,13px)/1 ui-monospace,monospace;transition:background .3s}
.box.clamped{background:var(--accent-2)}
.code{font:700 clamp(9px,1.6vmin,11px)/1 ui-monospace,monospace;color:var(--muted)}
js
const viewport = document.getElementById('viewport');
const box = document.getElementById('box');
const val = document.getElementById('val');
setInterval(() => viewport.classList.toggle('wide'), 3200);
function tick() {
  const w = box.getBoundingClientRect().width;
  val.textContent = Math.round(w) + 'px';
  box.classList.toggle('clamped', w <= 72 || w >= 218);
  requestAnimationFrame(tick);
}
requestAnimationFrame(tick);

`clamp(A, B, C)`는 세 값 중 가운데(`B`, "선호값")를 기본으로 쓰되, 그 값이 `A`보다 작아지면 `A`로, `C`보다 커지면 `C`로 잘라냅니다. 선호값 자리에 `vw`(뷰포트 폭 비례) 단위를 넣으면 — 예: `clamp(70px, 40%, 220px)` — 화면(또는 컨테이너)이 커질수록 값도 함께 커지다가, 지정한 상한·하한에 닿는 순간 거기서 멈춥니다.

미디어 쿼리로 같은 효과를 내려면 `@media (min-width: …) { font-size: 18px }`처럼 브레이크포인트마다 값을 계단식으로 정의해야 하고, 그 사이 폭에서는 값이 갑자기 뚝 바뀝니다. `clamp()`는 두 브레이크포인트 사이를 수학적으로 보간하므로 계단이 아니라 경사로가 됩니다 — 그래서 "플루이드(fluid)" 타이포그래피·레이아웃이라고 부릅니다.

가장 흔한 함정은 중간 항(선호값)에 상대 단위를 전혀 안 쓰는 것입니다. `clamp(16px, 16px, 32px)`처럼 선호값이 고정 px면 뷰포트가 바뀌어도 절대 움직이지 않고 그냥 16px로 고정됩니다 — 유동적으로 만들려면 반드시 `vw`나 `%`, 혹은 `vw`가 섞인 계산식(`1rem + 2vw`)이 선호값 자리에 있어야 합니다.

언제 쓰나

제목 폰트 크기, 카드 폭, 섹션 패딩처럼 "화면마다 다른 값을 여러 개 정의하기는 귀찮지만 아예 고정값도 아닌" 대부분의 숫자에 기본값으로 씁니다.