Contents
see List2026년 CSS의 가장 혁신적인 기능 중 하나인 CSS Anchor Positioning이 모든 주요 브라우저에서 지원됩니다. 기존에는 툴팁, 드롭다운, 팝오버 등의 위치를 JavaScript로 계산해야 했지만, 이제 CSS만으로 한 요소를 다른 요소에 정확하게 고정(tether)할 수 있습니다. 브라우저가 자동으로 뷰포트 경계 감지, 위치 조정, 스크롤 추적을 처리합니다.
기본 개념: 앵커와 타겟
Anchor Positioning은 두 요소로 구성됩니다. 앵커(anchor)는 기준이 되는 요소이고, 타겟은 앵커에 상대적으로 위치하는 요소입니다.
<!-- HTML 구조 -->
<button id="menu-btn" class="anchor-btn">메뉴 열기</button>
<div class="dropdown" popover>
<ul>
<li>프로필</li>
<li>설정</li>
<li>로그아웃</li>
</ul>
</div>/* 앵커 요소 지정 */
.anchor-btn {
anchor-name: --menu-anchor;
}
/* 타겟 요소를 앵커에 연결 */
.dropdown {
position: fixed;
position-anchor: --menu-anchor;
/* 앵커의 아래쪽, 왼쪽 정렬 */
top: anchor(bottom);
left: anchor(left);
/* 앵커와의 간격 */
margin-top: 8px;
}anchor() 함수 상세
anchor() 함수는 앵커 요소의 각 변(edge)을 참조합니다.
/* anchor() 함수의 사용 가능한 값 */
.target {
position: fixed;
position-anchor: --my-anchor;
/* 수직 위치: top, bottom, center */
top: anchor(bottom); /* 앵커 하단에 배치 */
top: anchor(top); /* 앵커 상단에 배치 */
top: anchor(center); /* 앵커 수직 중앙 */
/* 수평 위치: left, right, center */
left: anchor(left); /* 앵커 좌측에 정렬 */
left: anchor(right); /* 앵커 우측 바깥에 배치 */
left: anchor(center); /* 앵커 수평 중앙 */
}
/* 앵커 크기 참조: anchor-size() */
.target {
/* 앵커와 같은 너비 */
width: anchor-size(width);
/* 앵커 너비의 1.5배 */
width: calc(anchor-size(width) * 1.5);
/* 최소 앵커 너비, 최대 300px */
width: clamp(anchor-size(width), 200px, 300px);
}position-area로 간편 배치
position-area 속성은 9개 영역 그리드를 기반으로 타겟 위치를 직관적으로 지정합니다.
/* position-area 그리드 */
/* top-left | top-center | top-right */
/* center-left | center | center-right */
/* bottom-left | bottom-center | bottom-right */
/* 툴팁: 앵커 위 중앙 */
.tooltip {
position: fixed;
position-anchor: --tooltip-anchor;
position-area: top center;
margin-bottom: 8px;
}
/* 사이드 패널: 앵커 오른쪽 */
.side-panel {
position: fixed;
position-anchor: --panel-anchor;
position-area: center right;
margin-left: 12px;
}position-try-fallbacks: 자동 위치 조정
뷰포트 경계에 부딪힐 때 대체 위치를 자동으로 시도합니다. JavaScript로 구현하면 수십 줄이 필요한 로직입니다.
/* 기본: 아래에 표시, 공간 부족하면 위로 */
.dropdown {
position: fixed;
position-anchor: --trigger;
top: anchor(bottom);
left: anchor(left);
margin-top: 8px;
/* 자동 플립: 아래 공간 부족 시 위로 이동 */
position-try-fallbacks: flip-block;
}
/* 좌우 플립 */
.side-tooltip {
position: fixed;
position-anchor: --icon;
left: anchor(right);
top: anchor(center);
/* 우측 공간 부족 시 좌측으로 */
position-try-fallbacks: flip-inline;
}
/* 양방향 플립 */
.context-menu {
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
}
/* 커스텀 폴백 위치 정의 */
@position-try --above-right {
top: auto;
bottom: anchor(top);
left: anchor(right);
margin-bottom: 8px;
}
@position-try --below-left {
top: anchor(bottom);
right: anchor(left);
margin-top: 8px;
}
.smart-popup {
position: fixed;
position-anchor: --trigger;
top: anchor(bottom);
left: anchor(left);
position-try-fallbacks: --above-right, --below-left, flip-block;
}실전 예제: 접근성 완비 툴팁
<!-- HTML -->
<button
aria-describedby="tooltip-1"
class="has-tooltip">
설정
</button>
<div id="tooltip-1" role="tooltip" class="tooltip" popover="hint">
애플리케이션 설정을 변경합니다
</div>/* CSS */
.has-tooltip {
anchor-name: --tooltip-trigger;
}
.tooltip {
position: fixed;
position-anchor: --tooltip-trigger;
/* 기본: 위에 중앙 배치 */
bottom: anchor(top);
left: anchor(center);
translate: -50% 0;
margin-bottom: 8px;
/* 위 공간 부족 시 아래로 */
position-try-fallbacks: flip-block;
/* 스타일 */
background: #1a1a2e;
color: #fff;
padding: 8px 16px;
border-radius: 6px;
font-size: 14px;
max-width: 250px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
/* 트랜지션 */
opacity: 0;
transition: opacity 0.2s ease;
}
/* hover/focus 시 표시 */
.has-tooltip:hover + .tooltip,
.has-tooltip:focus + .tooltip,
.tooltip:hover {
opacity: 1;
}
/* 화살표 */
.tooltip::before {
content: '';
position: absolute;
top: 100%;
left: 50%;
translate: -50% 0;
border: 6px solid transparent;
border-top-color: #1a1a2e;
}실전 예제: 네이티브 드롭다운 메뉴
<!-- Popover API + Anchor Positioning -->
<button popovertarget="user-menu" class="menu-trigger">
사용자 메뉴
</button>
<nav id="user-menu" popover class="menu-panel">
<a href="/profile">내 프로필</a>
<a href="/settings">설정</a>
<hr>
<a href="/logout">로그아웃</a>
</nav>.menu-trigger {
anchor-name: --user-menu-trigger;
}
.menu-panel {
position: fixed;
position-anchor: --user-menu-trigger;
top: anchor(bottom);
left: anchor(left);
width: anchor-size(width);
min-width: 180px;
margin-top: 4px;
position-try-fallbacks: flip-block;
/* 스타일 */
background: white;
border: 1px solid #e2e8f0;
border-radius: 8px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
padding: 4px;
/* 팝오버 진입/퇴장 애니메이션 */
opacity: 0;
transform: translateY(-8px);
transition: opacity 0.2s, transform 0.2s, display 0.2s allow-discrete;
}
.menu-panel:popover-open {
opacity: 1;
transform: translateY(0);
}
/* 진입 시 시작 상태 */
@starting-style {
.menu-panel:popover-open {
opacity: 0;
transform: translateY(-8px);
}
}브라우저 지원 현황
/* 점진적 개선을 위한 @supports */
@supports (anchor-name: --test) {
/* Anchor Positioning 사용 */
.tooltip {
position: fixed;
position-anchor: --trigger;
bottom: anchor(top);
}
}
@supports not (anchor-name: --test) {
/* 폴백: 기존 position: absolute 방식 */
.tooltip-wrapper {
position: relative;
}
.tooltip {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
}
}CSS Anchor Positioning은 웹 UI 개발에서 가장 자주 사용되면서도 가장 귀찮았던 위치 계산 문제를 브라우저 레벨에서 해결합니다. Popover API와 결합하면 JavaScript 한 줄 없이도 접근성이 완비된 드롭다운, 툴팁, 팝오버를 구현할 수 있습니다. 2026년 현재 모든 주요 브라우저가 지원하므로, 프로덕션 환경에서 적극 도입을 권장합니다.