웹사이트에서 가장 자주 만들지만 가장 자주 어긋나는 인터페이스가 있다. 버튼 위에 떠야 하는 툴팁, 메뉴 옆에 정렬돼야 하는 드롭다운, 폼 위에 살짝 떠 있는 안내 팝오버 같은 것들이다. 이들의 공통점은 단순하다. 어떤 요소의 위치에 맞춰 다른 요소를 띄워야 한다는 것이다. 그리고 이 단순한 요구를 위해 우리는 오랫동안 getBoundingClientRect()로 좌표를 재고, 스크롤마다 위치를 다시 계산하고, 화면을 벗어나면 반대편으로 뒤집는 코드를 직접 짜야 했다.
2026년 현재 이 모든 일을 CSS 한 영역이 대신해 줄 수 있게 됐다. CSS Anchor Positioning은 어떤 요소를 다른 요소에 '닻을 내리듯' 붙이는 기능을 표준 CSS로 정의한 새 모듈이다. 위치 계산을 브라우저에 맡기면, 우리는 자바스크립트 코드 수십 줄과 함께 따라오던 미묘한 버그들에서 풀려난다.
왜 위치 잡기가 늘 골치였나
전통적인 방법은 두 가지였다. 하나는 부모 요소를 position: relative로 만들고 자식을 position: absolute로 띄우는 방식이다. 간단하지만 부모 박스를 벗어나는 즉시 잘리고, 부모의 overflow: hidden 한 줄에 영향을 받는다. 다른 하나는 position: fixed로 화면 좌표에 직접 띄우는 방식이다. 자유롭지만 스크롤이 일어나면 어긋나고, 기준이 되는 요소의 위치를 자바스크립트로 계속 추적해야 한다.
그래서 Floating UI 같은 라이브러리가 사실상 표준이 됐다. 좋은 도구지만, 작은 인터페이스 하나를 위해 수 KB의 자바스크립트를 더 싣는 것은 늘 무거운 결정이었다.
anchor-name과 position-anchor — 닻을 내리는 두 줄
Anchor Positioning의 골격은 두 속성으로 끝난다. 기준이 되는 요소에 anchor-name으로 이름을 붙이고, 따라붙을 요소에 position-anchor로 그 이름을 가리킨다.
예를 들어 버튼이 닻이고, 툴팁이 그 위에 떠야 한다면 이렇게 쓴다. 버튼에는 anchor-name: --tooltip-anchor를, 툴팁에는 position-anchor: --tooltip-anchor를 지정하는 식이다. 두 요소가 DOM 트리에서 멀리 떨어져 있어도 상관없다. 부모-자식 관계가 아니라 이름으로 연결되기 때문이다.
anchor() 함수와 position-area로 위치를 정한다
이름만 붙여서는 어디에 떠야 할지 모른다. 위치는 두 가지 방법으로 지정할 수 있다. 하나는 anchor() 함수로 직접 좌표를 잡는 방법이고, 다른 하나는 position-area 키워드로 닻을 기준으로 한 12개 영역 중 하나를 고르는 방법이다.
위쪽 가운데에 띄우고 싶다면 position-area: top 한 줄이면 된다. 닻의 오른쪽 위 모서리에 붙이고 싶다면 position-area: top right이다. 직관적인 영어 키워드만으로 좌표 계산이 끝난다는 점이 이 모듈의 가장 큰 매력이다.
화면 끝에서 자동으로 뒤집히는 fallback positioning
실전에서 더 어려운 문제는 따로 있다. 툴팁이 위쪽에 뜨다가 화면 상단에 가까워지면 자동으로 아래쪽으로 뒤집혀야 한다. 드롭다운도 마찬가지다. 이 흐름을 자바스크립트로 짜면 늘 엣지 케이스가 남는다.
Anchor Positioning은 이를 위해 position-try와 position-try-fallbacks를 제공한다. "원래는 위에 띄우되, 공간이 부족하면 아래로 시도해 보고, 그것도 안 되면 오른쪽으로"라는 우선순위를 CSS로 직접 적을 수 있다. 브라우저는 뷰포트 안에서 가장 잘 들어맞는 위치를 골라 띄운다.
Popover API와의 조합 — 자바스크립트 없는 메뉴
Anchor Positioning이 진짜 빛을 발하는 순간은 작년에 표준이 된 Popover API와 만날 때다. popovertarget 속성으로 버튼과 팝오버를 연결하고, anchor-name과 position-anchor로 위치를 잡으면, 자바스크립트 한 줄 없이도 누르면 뜨고 ESC로 닫히고 화면 끝에서 뒤집히는 메뉴가 완성된다.
이전에는 'simple dropdown' 컴포넌트 하나를 만들기 위해 라이브러리 한두 개와 수백 줄의 보일러플레이트가 필요했다. 그 코드의 대부분이 표준 플랫폼 안으로 들어왔다는 뜻이다.
지금 도입하기 전에 알아야 할 것들
좋은 도구지만 무작정 던져 넣을 일은 아니다. 실제 프로젝트에 들이기 전에 세 가지를 점검해야 한다.
- 지원 범위 확인: Chromium 계열은 일찍 지원했고, Firefox와 Safari도 점진적으로 따라오는 중이다. 캐시 비율이 높은 자사 사이트와 트래픽 절반이 구형 사파리인 사이트는 도입 시점이 달라야 한다.
- 점진적 향상의 자세: 미지원 브라우저에서는 위치가 어긋나도 콘텐츠 자체는 읽혀야 한다. @supports (anchor-name: --x)로 감싸 지원 브라우저에만 정밀 위치를 주는 식의 설계가 안전하다.
- 접근성 검증: 위치만 잡힌다고 끝이 아니다. 키보드 포커스가 닻에서 팝오버로 자연스럽게 이동하는지, 스크린 리더가 두 요소의 관계를 이해하는지는 별도로 테스트해야 한다.
위치 계산이 더 이상 자바스크립트의 일이 아니다
지난 십 년간 우리는 라이브러리에 위치를 맡기고 그 라이브러리의 버전과 번들 크기를 걱정해 왔다. CSS Anchor Positioning은 그 책임을 다시 브라우저로 돌려놓는다. 더 적은 코드, 더 빠른 첫 화면, 더 적은 엣지 케이스. 같은 요구사항을 더 가볍게 풀 수 있는 길이 열렸다는 뜻이다.
CYAN 에이전시에서는 새로 시작하는 프로젝트의 인터페이스 설계 단계에서 어떤 부분을 표준 CSS로 풀고, 어떤 부분에 라이브러리를 남길지를 함께 정리해 드린다. 작은 인터페이스 하나가 사이트 전체의 속도와 유지보수 비용을 바꾸기 때문이다.