2026년 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년 현재 모든 주요 브라우저가 지원하므로, 프로덕션 환경에서 적극 도입을 권장합니다.