Anchor positioning/Anchored container queries

김동현·2026년 3월 30일

mdn 학습 번역 - CSS

목록 보기
36/190

앵커된 컨테이너 쿼리 사용하기

CSS 앵커 포지셔닝에는 폴백 옵션을 제공하는 메커니즘이 포함되어 있어요. 이것들은 위치 지정된 요소가 뷰포트를 넘치기 시작할 때 화면 안으로 다시 배치하기 위해, 브라우저가 앵커 위치 지정 요소를 앵커에 상대적으로 배치할 수 있는 대안 위치예요.

앵커된 컨테이너 쿼리는 앵커 위치 지정 요소가 어떤 폴백 위치에 배치되는지에 따라 다른 스타일링을 가능하게 함으로써 앵커 포지셔닝 폴백 옵션의 유용성을 더욱 높여요. 이 가이드에서는 앵커된 컨테이너 쿼리를 사용하는 방법을 보여주고 몇 가지 예시를 제공해요.

참고:
CSS 앵커 포지셔닝의 기본 원리에 대한 정보는 CSS 앵커 포지셔닝 사용하기를 참고하세요.

요소가 화면 밖으로 나가지 않게 위치를 옮기는 것(폴백)도 중요하지만, 위치가 바뀌었을 때 그에 맞춰 스타일(예: 말풍선 꼬리 방향)을 자동으로 바꿔주는 게 진짜 '디테일'이거든요. 자, 원문 내용을 하나도 빠짐없이 구어체로 친절하게 설명해 드릴게요!


기능 요약 (Feature summary)

앵커 포지셔닝을 사용해 UI 요소에 상대적으로 툴팁의 위치를 잡을 때, position-try-fallbacks 속성을 통해 position-try 폴백 옵션을 제공하는 것이 유용합니다. 이를 통해 툴팁이 화면에 가능한 한 오래 표시되도록 할 수 있죠.

예를 들어, 기본적으로 툴팁이 기준이 되는 UI 요소 위에 배치되어 있을 때, 사용자가 화면을 위로 스크롤하면 툴팁이 화면 밖으로 나가기 직전에 요소 아래로 위치를 옮기도록 폴백을 사용할 수 있습니다.

하지만 이것만으로는 해결되지 않는 문제가 하나 있는데, 바로 각기 다른 폴백 옵션에 맞춰 앵커 지정 요소의 스타일을 업데이트하는 것입니다. 예를 들어, 시각적인 연결을 명확히 하기 위해 툴팁에 기준 요소를 가리키는 작은 화살표를 포함하는 경우가 많죠. 툴팁이 다른 위치로 이동하면 화살표의 위치와 방향도 함께 바뀌어야 합니다. 그러지 않으면 모양이 어색해 보일 거예요.

이 문제를 해결하기 위해 앵커 기반 컨테이너 쿼리를 사용할 수 있습니다. 이는 CSS 컨테이너 쿼리의 기능을 확장하여, 앵커 지정 요소에 특정 폴백 옵션이 적용되는 시점을 감지하고 그 결과에 따라 자손 요소에 CSS를 적용할 수 있게 해줍니다. 구체적으로 앵커 기반 컨테이너 쿼리는 다음 두 가지 기능에 의존합니다.

  • container-type 속성의 anchored 값: 이를 앵커 지정 요소에 적용하면, 어떤 폴백 옵션이 적용되는지 감지하기 시작합니다.
  • @container 앳 규칙의 anchored() 함수: 이 함수는 fallback 디스크립터를 인자로 받습니다. 이 디스크립터의 값은 position-try-fallbacks에 쓴 값과 같습니다.

예를 들어, position-area 값이 top이라 기본적으로 앵커 위에 위치하지만, position-try-fallbacks 값이 flip-block으로 지정된 툴팁 요소가 있다고 해봅시다. 이렇게 하면 툴팁이 뷰포트 상단을 넘어가기 시작할 때 앵커의 아래쪽으로 뒤집히게(flip) 됩니다. 이때 폴백이 적용되었는지 감지하고 싶다면, 먼저 툴팁에 container-type: anchored를 설정해서 앵커 쿼리 컨테이너로 만들어야 합니다.

.tooltip {
  position: absolute;
  position-anchor: --my-anchor;
  position-area: top;
  position-try-fallbacks: flip-block;
  /* 앵커 기반 컨테이너로 지정! */
  container-type: anchored;
}

이렇게 설정했다면, 이제 다음과 같이 컨테이너 쿼리를 작성할 수 있습니다.

@container anchored(fallback: flip-block) {
  /* 여기에 자손 요소의 스타일을 작성하세요 */
}

anchored(fallback: flip-block) 쿼리 테스트는 툴팁에 flip-block 폴백 옵션이 적용될 때 참(true)을 반환하며, 그 경우 @container 블록 내부에 지정된 스타일이 적용됩니다. 예를 들어 화살표가 아래가 아닌 위를 가리키도록 위치와 방향을 바꾸거나, 그라데이션의 방향을 변경하고 싶을 때 유용하겠죠.

참고: 모든 컨테이너 쿼리와 마찬가지로, 적용된 스타일은 컨테이너의 자손 요소에만 영향을 줄 수 있으며 컨테이너 자체에는 영향을 줄 수 없다는 점을 명심하세요. 이 때문에 여러 폴백 예제에서 보여주는 것처럼, 위치 지정 요소 자체에 스타일을 주기보다는 그 안의 래퍼(wrapper) 요소에 스타일을 적용해야 할 수도 있습니다.


기본 사용 예시 (Basic usage example)

이 예제에는 정보 상자(infobox)가 상대적으로 배치된 앵커 요소가 포함되어 있습니다. 처음에는 정보 상자가 앵커 위에 배치되어 있고 앵커를 향해 아래를 가리키는 화살표가 있습니다. 콘텐츠를 위로 스크롤해서 정보 상자가 뷰포트 상단을 벗어나려고 하면 앵커 아래로 이동하도록 position-try-fallback을 설정했습니다. 추가로, 앵커 기반 컨테이너 쿼리를 사용해 폴백이 발동되면 화살표를 옮기고 위를 가리키도록 스타일을 변경했습니다.

앵커와 정보 상자는 아래와 같이 두 개의 <div> 요소로 구성됩니다. 실제 렌더링에서는 페이지 스크롤을 위해 텍스트로 감싸져 있지만, 여기서는 간결함을 위해 생략했습니다.

HTML

<div class="anchor">⚓︎</div>

<div class="infobox">Infobox</div>

CSS

먼저 anchor 역할을 하는 <div>anchor-name으로 --my-anchor라는 이름을 주어 앵커 요소로 지정합니다.

.anchor {
  anchor-name: --my-anchor;
}

그다음, infobox 역할을 하는 <div>position 값을 fixed로 주고, position-anchor 값을 --my-anchor로 설정해 앵커 요소와 연결합니다. 또한 position-area 값을 top으로 주어 앵커 위에 배치하고, position-try-fallbacks 값을 bottom으로 설정하여 위쪽이 넘칠 때 아래로 이동하게 만듭니다.

마지막으로, 정보 상자에 container-type 값을 anchored로 설정하여 앵커 기반 쿼리 컨테이너로 지정합니다. 이제 @container 앳 규칙을 통해 어떤 폴백이 활성화되었는지 감지하고 자손의 스타일을 업데이트할 수 있습니다.

.infobox {
  position: fixed;
  position-anchor: --my-anchor;
  position-area: top;
  position-try-fallbacks: bottom;
  /* 앵커 기반 쿼리 가능하게 설정 */
  container-type: anchored;
}

이제 정보 상자의 ::before 의사 요소를 사용해 화살표를 추가합니다. content 속성에 아래쪽 화살표 아이콘을 넣고, 절대 위치를 잡은 뒤 top: 105%를 주어 정보 상자 바닥에 배치합니다.

.infobox::before {
  content: "▼";
  position: absolute;
  top: 105%;
}

이제 앵커 기반 컨테이너 쿼리를 추가합니다. @container 앳 규칙의 조건을 anchored(fallback: bottom)로 정의합니다. 이는 정보 상자에 bottom 폴백이 적용될 때 이 안의 CSS가 적용됨을 의미합니다. 내부적으로는 ::before 의사 요소의 아이콘을 위쪽 화살표로 바꾸고 위치를 정보 상자 꼭대기로 옮기도록 스타일을 정의합니다.

@container anchored(fallback: bottom) {
  .infobox::before {
    content: "▲";
    bottom: 100%;
    top: auto;
  }
}

참고: 이 예제에는 모든 요소의 기본 스타일을 잡기 위한 CSS가 더 들어있지만, 여기서는 앵커 기반 컨테이너 쿼리와 관련된 부분만 보여드렸어요. 전체 코드가 궁금하다면 코드 블록의 "Play" 버튼을 눌러 MDN Playground에서 확인해 보세요.

결과 (Result)

데모를 스크롤해서 앵커가 뷰포트 상단에 가까워지게 해보세요. 정보 상자가 화면에 계속 보이기 위해 앵커 아래로 이동할 뿐만 아니라, 새로운 위치에 맞춰 화살표 아이콘 스타일도 업데이트되는 것을 확인할 수 있습니다.

다시 아래로 스크롤하면 정보 상자가 원래 위치인 앵커 위로 돌아옵니다. top으로 돌아오기 위해 별도의 폴백 값을 지정할 필요는 없는데, 이는 position-area: top이 기본 위치이기 때문입니다. 제공된 폴백으로도 넘침을 막을 수 없다면 브라우저는 기본 위치로 되돌아갑니다.


여러 폴백 예시 (Multiple fallbacks example)

이 예제는 여러 개의 position-try 폴백과 앵커 기반 컨테이너 쿼리가 실제로 어떻게 작동하는지 보여줍니다. 또한, 컨테이너 쿼리를 사용해 컨테이너 자체가 아닌 자손에게만 스타일을 줄 수 있는 한계를 극복하기 위해 별도의 래퍼(wrapper) 요소를 사용하는 방법도 다룹니다. 마우스나 키보드로 앵커 요소를 움직여보며 다양한 폴백을 확인할 수 있는 자바스크립트 코드도 포함되어 있습니다.

HTML에는 앵커와 정보 상자를 나타내는 두 개의 <div>가 있습니다. 앵커 <div>에는 키보드 포커스가 가능하도록 tabindex를 주었고, 정보 상자 <div> 안에는 @container 규칙으로 스타일을 제어할 수 있도록 추가적인 래퍼 <div>를 넣었습니다.

HTML

<div class="anchor" tabindex="0">⚓︎</div>

<div class="infobox">
  <div>Infobox</div>
</div>

CSS

스타일의 시작으로 anchor <div>를 앵커 요소로 지정하고(anchor-name: --my-anchor), 자바스크립트로 위치를 옮길 수 있도록 절대 위치를 잡습니다.

.anchor {
  anchor-name: --my-anchor;
  position: absolute;
}

다음으로 정보 상자의 위치를 잡습니다. 이번에는 position-area: top left를 주어 앵커의 왼쪽 상단에 배치합니다. 그리고 세 개의 폴백(flip-block, flip-inline, flip-block flip-inline)을 설정합니다. 이렇게 하면 앵커가 화면 가장자리에 닿을 때 블록 축, 인라인 축, 혹은 양쪽 축 모두로 위치를 뒤집어 화면 안에 머물게 됩니다. 마지막으로 container-type: anchored를 설정해 줍니다.

.infobox {
  position: absolute;
  position-anchor: --my-anchor;
  position-area: top left;
  position-try-fallbacks:
    flip-block,
    flip-inline,
    flip-block flip-inline;
  container-type: anchored;
}

이제 정보 상자 안의 래퍼 <div>에 시각적 스타일을 적용합니다. 여기서 핵심은 정보 상자 자체가 아니라 그 안의 자손 요소에 스타일을 준다는 거예요. 그래야 나중에 앵커 기반 컨테이너 쿼리로 스타일을 조작할 수 있거든요.

특히 border-radius를 설정해서 오른쪽 하단 모서리만 뾰족하게(라운드 없이) 만들었습니다. 정보 상자가 앵커의 왼쪽 상단에 있으니까, 이 뾰족한 모서리가 앵커를 가리키는 화살표 역할을 하게 되는 거죠.

.infobox div {
  color: white;
  background-color: black;
  font-size: 1.4em;
  padding: 10px;
  margin: 1px;
  /* 오른쪽 하단만 뾰족하게! */
  border-radius: 10px 10px 0 10px;
}

마지막으로, 정보 상자에 적용될 수 있는 각 폴백 상황에 대해 앵커 기반 컨테이너 쿼리를 정의합니다. 각 경우마다 정보 상자 래퍼 <div>의 모서리 둥글기를 조절해서, 항상 앵커와 가장 가까운 쪽 모서리가 뾰족하게 유지되도록 만듭니다.

/* 상하가 뒤집혔을 때 (flip-block) */
@container anchored(fallback: flip-block) {
  .infobox div {
    border-radius: 10px 0 10px 10px;
  }
}

/* 좌우가 뒤집혔을 때 (flip-inline) */
@container anchored(fallback: flip-inline) {
  .infobox div {
    border-radius: 10px 10px 10px 0;
  }
}

/* 둘 다 뒤집혔을 때 (flip-block flip-inline) */
@container anchored(fallback: flip-block flip-inline) {
  .infobox div {
    border-radius: 0 10px 10px 10px;
  }
}

참고: 이번에도 간결함을 위해 기본 스타일과 움직임을 제어하는 자바스크립트는 생략했어요. 전체 코드는 MDN Playground에서 확인해 보세요.

결과 (Result)

다음 방법으로 앵커 요소를 뷰포트 여기저기로 옮겨보세요.

  • 마우스로 클릭하거나 터치스크린에서 탭하기.
  • 키보드의 W, A, S, D 키를 사용해 상, 좌, 하, 우로 움직이기.

앵커를 화면 구석으로 가져가면 정보 상자가 화면 안에 남기 위해 위치를 바꾸는 것뿐만 아니라, border-radius가 변하면서 항상 뾰족한 모서리가 앵커를 가리키는 것을 볼 수 있습니다. 앵커를 네 귀퉁이로 다 옮겨보면 확실한 차이를 느낄 수 있을 거예요!

profile
프론트에_가까운_풀스택_개발자

0개의 댓글