앵커 포지셔닝

Anchor Positioning

JS로 좌표를 재지 않고, CSS만으로 한 요소를 다른 요소에 붙여 배치하는 기능. 툴팁·팝오버 위치 계산 라이브러리를 대체합니다.

다른 이름: CSS Anchor APIanchor()
···
html
<div class="wrap">
  <div class="badge" id="badge"><svg viewBox="0 0 10 10"><path id="bpath" d="M1.5 5.2l2.6 2.6L8.5 2.4" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg><span id="btext">확인 중</span></div>
  <button class="anchor" id="btn">기준 버튼</button>
  <div class="tip" id="tip">anchor(bottom)로 붙었어요</div>
</div>
css
.wrap{position:relative;width:100%;height:100%;display:grid;place-items:center}
.anchor{anchor-name:--trg;padding:9px 18px;border-radius:9px;border:1px solid var(--line);background:var(--surface);color:var(--fg);font-size:13px;font-weight:600}
.tip{position:absolute;position-anchor:--trg;top:anchor(bottom);left:anchor(center);translate:-50% 10px;
  padding:7px 12px;border-radius:8px;background:var(--accent);color:#fff;font-size:11px;font-weight:600;white-space:nowrap;
  opacity:0;animation:show 2.4s ease infinite}
.tip.fallback{position:fixed;translate:-50% 0}
@keyframes show{0%,15%{opacity:0}25%,75%{opacity:1}90%,100%{opacity:0}}
.badge{position:absolute;top:10px;right:10px;display:flex;align-items:center;gap:5px;padding:4px 9px;border-radius:999px;font-size:10px;font-weight:700;background:var(--bg);border:1px solid var(--line);color:var(--accent-3);z-index:2}
.badge.no{color:var(--accent-2)}
.badge svg{width:9px;height:9px}
js
const ok = CSS.supports('anchor-name', '--x');
const b=document.getElementById('badge'),p=document.getElementById('bpath'),t=document.getElementById('btext');
b.classList.toggle('no', !ok);
p.setAttribute('d', ok ? 'M1.5 5.2l2.6 2.6L8.5 2.4' : 'M2 2l6 6M8 2l-6 6');
t.textContent = ok ? 'anchor() 지원됨' : '미지원 · JS 폴백';
// 폴백: getBoundingClientRect() 로 직접 좌표를 재서 붙인다.
if (!ok) {
  const tip = document.getElementById('tip'), btn = document.getElementById('btn');
  tip.classList.add('fallback');
  function place(){ const r = btn.getBoundingClientRect(); tip.style.left = (r.left + r.width/2) + 'px'; tip.style.top = (r.bottom + 10) + 'px'; }
  place();
  window.addEventListener('resize', place);
}

툴팁이나 드롭다운을 트리거 옆에 붙이려면 지금까지는 getBoundingClientRect()로 위치를 재고, 스크롤·리사이즈마다 다시 계산하는 JS 라이브러리(Popper, Floating UI)가 사실상 필수였습니다. CSS 앵커 포지셔닝은 트리거에 `anchor-name`을 주고, 위치를 잡을 요소에 `position-anchor`와 `top: anchor(bottom)` 같은 anchor() 함수를 쓰면 브라우저가 레이아웃 단계에서 직접 계산해 줍니다.

`position-try` / `position-try-fallbacks`를 함께 쓰면 화면 밖으로 나갈 때 반대쪽으로 뒤집는 충돌 회피도 JS 없이 처리됩니다. 이건 팝오버 API·top layer와 특히 궁합이 좋아서, 네이티브 팝오버를 앵커 위치로 붙이는 조합이 늘고 있습니다.

기본 지원은 caniuse/MDN baseline을 확인하세요. 미지원 브라우저에서는 여전히 JS로 getBoundingClientRect() 기반 위치 계산이 필요하며, 아래 데모의 폴백이 그 최소 형태입니다.

언제 쓰나

툴팁·팝오버·드롭다운처럼 트리거에 붙는 UI를 JS 위치 계산 라이브러리 없이 만들 때.