TL;DR

  • 툴팁·각주·팝오버처럼 특정 요소를 기준으로 배치하는 요소는 CSS 앵커 위치 지정으로 스크롤·창 크기 변경에 대응하고 넘침에 따라 위치를 전환할 수 있음.
  • 기준 요소에 anchor-name, 대상 요소에 position-anchor를 지정하며, 대상은 이미 절대 또는 고정 위치 지정 상태여야 함.
  • position-area로 기준 요소 주변의 배치 위치를 표현하고, position-try-fallbacks로 뷰포트 넘침 시 대체 위치를 지정함.
  • 네이티브 popover와 앵커 위치 지정을 조합하면 자바스크립트 없이 바깥 클릭으로 닫히는 드롭다운을 만들 수 있고, anchor-size()로 기준 요소의 너비를 가져올 수 있음.
  • 앵커 위치 지정은 시각적 배치만 처리하며 접근성 관계를 바꾸지 않고, 브라우저별 대체 위치 차이와 팝오버 여백 문제도 고려해야 함.

앵커 이름과 위치 앵커의 기본

  • 툴팁이나 각주, 팝오버를 배치할 때 요소의 화면 좌표를 자바스크립트로 읽어 top과 left에 지정하는 방식은 창 크기 변경과 페이지 스크롤에 대응하려면 이벤트 리스너가 필요함. 요소가 뷰포트 아래쪽에 놓이면 화면 밖으로 잘릴 수도 있음.
  • CSS 앵커 위치 지정은 이러한 위치 계산을 브라우저에서 처리하며, 자바스크립트·라이브러리·이벤트 리스너 없이 위치를 다시 계산함.
  • 기준 요소에 anchor-name을 지정하고, 이를 따라 배치할 요소에 position-anchor와 position-area를 지정함. 대상 요소는 이미 position: absolute 또는 position: fixed로 배치된 상태여야 함.
  • anchor-name은 페이지 전체에서 고유할 필요는 없지만, 각 앵커와 그에 대응하는 대상 사이에서는 고유해야 함. 카드마다 툴팁이 있는 그리드에서 모든 카드가 같은 이름을 재사용하면 각 툴팁이 마우스를 올린 카드가 아니라 해당 이름을 가장 최근에 등록한 카드에 연결됨. 컴포넌트 인스턴스마다 이름을 생성해야 각 툴팁이 자기 카드에 연결됨.
  • position-area에는 bottom, top, bottom span-right 등 배치 위치를 지정할 수 있어 수동 오프셋 계산이나 top: calc()가 필요하지 않음.

위치 변경 리스너를 대신하는 대체 위치

  • position-try-fallbacks를 사용하면 대체 배치 위치를 지정할 수 있음. 예를 들어 flip-block과 flip-inline을 설정하면 페이지 아래쪽의 각주가 뷰포트를 벗어날 때 브라우저가 반대쪽 배치를 시도함.
  • 넘침 감지와 위치 재배치는 페이지가 스크롤되거나 창 크기가 바뀔 때 브라우저가 자동으로 처리함.

팝오버와 결합한 드롭다운

  • 정적인 툴팁보다 닫을 수 있는 드롭다운이나 메뉴를 만드는 경우가 많으며, 이때 앵커 위치 지정을 네이티브 popover 속성과 함께 사용할 수 있음.
  • popover는 요소를 최상위 레이어에 표시해 z-index 경쟁 없이 다른 요소 위에 배치하고, 바깥을 클릭하면 닫히는 라이트 디스미스를 제공함. 여기에 앵커 위치 지정을 결합하면 자바스크립트 없이 작동하는 드롭다운 메뉴를 만들 수 있음.

`anchor-size()`로 버튼과 드롭다운 너비 맞추기

  • 드롭다운의 너비를 드롭다운을 연 버튼과 정확히 같게 하려면 width: anchor-size(width)를 사용함.
  • anchor-size()는 앵커 요소의 크기를 직접 읽으므로 자바스크립트로 버튼 너비를 측정하고 인라인 너비를 지정할 필요가 없음.
  • Matt Smith(@AllThingsSmitty)의 CodePen 예제로 CSS 앵커 위치 지정과 팝오버를 이용한 드롭다운 메뉴가 제시됨.

요소 표시 상태와 앵커 위치 지정은 별개

  • 앵커 위치 지정은 두 요소가 같은 이름을 공유하는지만 확인하며, 두 요소가 DOM에서 어디에 있는지는 고려하지 않음.
  • 용어가 활성화됐을 때 각주를 표시하되 두 요소가 형제 요소가 아닌 경우, 일반 형제 선택자 ~는 두 요소가 같은 부모를 공유해야 하므로 사용할 수 없음. 문단 안에 있는 클릭 가능한 용어와 문서 끝의 별도 컨테이너에 있는 각주를 연결하는 예에서는 가장 가까운 공통 조상에 :has()를 적용함.
  • 앵커 위치 지정은 요소가 어디에 놓이는지를 해결할 뿐, 언제 표시되는지는 해결하지 않음. 표시 여부를 제어하려면 :has(), popover 또는 자바스크립트가 여전히 필요할 수 있음.
  • Matt Smith(@AllThingsSmitty)의 CodePen 예제에서는 밑줄 친 용어를 클릭하면 마크업상 서로 떨어진 각주가 해당 용어에 연결됨.

적용 기준

  • 특정 요소를 기준으로 다른 요소를 배치한다면 먼저 anchor-name과 position-anchor를 고려함.
  • 요소를 자체 컨테이너를 기준으로 배치하는 경우에는 앵커 위치 지정이 필요하지 않으며, position: relative인 부모와 position: absolute인 자식으로 처리할 수 있음.

아직 주의가 필요한 환경

  • 현재 버전의 Chrome, Firefox, Safari, Edge에서는 브라우저 지원이 안정적임. 다만 대체 위치의 일부 경계 사례에서 Safari와 Chrome의 동작이 다르며, 팝오버 속성의 기본 여백이 앵커 위치 지정과 간섭하는 알려진 문제가 있어 여백을 명시적으로 초기화해야 함.
  • 구형 브라우저를 위해 @supports not (anchor-name: --a) 대체 처리를 유지해야 함.
  • 화면 낭독기 사용자는 시각 사용자와 같은 방식으로 앵커 관계를 경험하지 않음. 앵커 관계는 시각적 관계일 뿐이며, 각주가 DOM의 다른 위치에 있으면 화면 낭독기는 앵커와의 시각적 근접성이 아니라 문서 순서에 따라 읽음.
  • aria-describedby가 일부 차이를 보완할 수 있지만 완전한 해결책은 아니며, 앵커 위치 지정을 접근성 기능으로 간주해서는 안 됨. 시각적 관계가 기본 문서 구조를 바꾸지는 않음.