CSS 앵커 위치 지정을 사용하여 도움말이나 팝오버를 빌드할 때 브라우저는 표시 영역을 오버플로하는 경우 요소를 대체 위치로 자동으로 '뒤집을' 수 있습니다. 이 경우 위치 지정 콘텐츠의 스타일을 조정할 수 있습니다. 예를 들어 위치 지정 콘텐츠에서 앵커를 가리키는 화살표의 위치를 변경할 수 있습니다.
고정 컨테이너 쿼리는 요소의 활성 위치 지정 상태를 쿼리하고 그에 따라 스타일을 적용할 수 있도록 하여 이 문제를 해결합니다. 표시 영역 충돌 플리핑이 있는 일반적인 앵커 드롭다운 및 플라이아웃 위치 지정 (방향 화살표 스타일 변경 없음)은 표시 영역 인식 드롭다운을 참고하세요.
문제
기본적으로 앵커 위에 표시되는 도움말을 상상해 보세요. 하단에 '아래쪽' 화살표가 있습니다. 사용자가 스크롤하여 도움말이 앵커 아래에 표시되도록 뒤집히면 화살표가 잘못된 방향을 가리키고 도움말의 잘못된 쪽에 표시됩니다.
해결책: 고정 컨테이너 쿼리
위치 지정 요소에 container-type: anchored를 설정하면 자체 앵커 위치 상태를 인식하는 쿼리 컨테이너로 전환됩니다. 그런 다음 @container anchored() 쿼리를 사용하여 하위 요소 또는 가상 요소를 업데이트할 수 있습니다.
1. 도움말 및 트리거 만들기
Popover API를 사용하여 도움말을 만듭니다. popovertarget를 통해 팝오버를 호출하면 트리거 버튼과 암시적 앵커 연결이 자동으로 설정되므로 명시적인 anchor-name 또는 position-anchor가 필요하지 않습니다.
<button popovertarget="tooltip" id="anchor" aria-describedby="tooltip">anchor</button>
<div id="tooltip" popover role="tooltip"></div>
앵커 위치 지정이 지원되는 경우에만 앵커 위치 지정과 함께 사용할 수 있도록 팝오버 인셋 및 여백 스타일을 재설정합니다.
@supports (anchor-name: --my-anchor) {
[popover] {
inset: auto;
margin: unset;
}
}
2. 컨테이너 설정
위치가 지정되는 요소에 container-type: anchored를 적용합니다. 이 요소에는 뒤집기 동작을 사용 설정하기 위해 정의된 position-try-fallbacks도 있어야 합니다.
#tooltip {
position: fixed;
position-area: block-start;
position-try-fallbacks: flip-block;
/* Enable anchored container queries */
container-type: anchored;
}
3. 대체 기반 스타일
특정 대체가 활성 상태일 때 스타일을 적용하려면 @container anchored(fallback: <value>)를 사용합니다.
모든 컨테이너 쿼리와 마찬가지로 @container는 컨테이너의 하위 요소에만 스타일을 지정할 수 있습니다. 화살표를 만드는 일반적인 전략은 ::before 및 ::after 가상 요소를 사용하는 것입니다. 이 요소는 하위 요소로 취급되며 직접 스타일을 지정할 수 있습니다. 하지만 도움말 자체의 스타일을 지정하려면 (4단계 참고) 도움말에 하위 요소를 추가하고 ::before 가상 요소에 화살표를 만듭니다.
<div id="tooltip" popover role="tooltip">
<div class="tooltip-content">Tooltip</div>
</div>
.tooltip-content::before {
/* Default "down" arrow for the 'top' position */
content: "▼";
position: absolute;
inset-block-end: 0;
inset-inline-start: 1rem;
}
/* Update to an "up" arrow when the 'flip-block' fallback (bottom) is active */
@container anchored(fallback: flip-block) {
.tooltip-content::before {
content: "▲";
inset-block-start: 0;
inset-block-end: auto;
}
}
4. 컨테이너 자체 스타일 지정
컨테이너가 뒤집힐 때 컨테이너 자체의 속성 (예: margin 또는 background-color)을 변경해야 하는 경우 내부 래퍼 요소를 사용해야 합니다.
- 바깥쪽에 위치한 요소에
container-type: anchored를 적용합니다. @container블록 내의 내부 요소를 타겟팅합니다.
@container anchored(fallback: flip-block) {
.tooltip-content {
border-radius: 0 0 .5rem .5rem;
margin-block-start: 0.25rem;
}
}
권장사항
- 논리적 대체 선호:
position-try-fallbacks에서flip-block및flip-inline와 같은 키워드를 사용하여 RTL 및 다양한 쓰기 모드를 자동으로 처리하는 더 간단한 쿼리를 작성합니다. - 화살표에 가상 요소 사용: 도움말 화살표는 순전히 장식용이며
::before또는::after에 적합합니다. 이는 추가 DOM 없이 앵커 컨테이너 쿼리를 통해 스타일을 지정할 수 있습니다.
대체 전략
적용된 대체에 따라 화살표를 배치하는 것은 점진적 개선이며 대체 위치에 반응하는 다른 방법은 없습니다. 앵커 위치 컨테이너 쿼리를 지원하지 않는 브라우저에서 화살표를 숨기려면 @supports (container-type: anchored)를 사용하여 CSS 지원을 테스트하세요.
@supports (container-type: anchored) {
.tooltip-content::before {
content: "▼";
}
}
Popover의 대체 및 브라우저 지원
Popover API는 대부분 점진적 개선이지만, 최상위 레이어 승격, 가벼운 닫기, popovertarget 호출과 같은 정의 동작에는 CSS 전용에 상응하는 기능이 없습니다. 이전 브라우저에는 폴리필이 필요하며, 폴리필을 제공하지 않으려면 수동 대체가 필요합니다.
폴리필: 이전 브라우저에서 popover 속성을 지원하려면 조건부로 @oddbird/popover-polyfill를 로드합니다. 필수: HTMLElement.prototype에서 popover 속성을 확인하여 기능을 감지하고 네이티브 지원이 누락된 경우에만 폴리필을 로드합니다. 무조건 로드하지 마세요.
번들러 또는 가져오기 맵 사용:
// MANDATORY: Feature detect 'popover' on HTMLElement.prototype.
if (!("popover" in HTMLElement.prototype)) {
import("@oddbird/popover-polyfill");
}
번들러가 없는 경우 <script type="module"> 내의 CDN에서 가져옵니다.
<script type="module">
if (!("popover" in HTMLElement.prototype)) {
import("https://unpkg.com/@oddbird/popover-polyfill@latest/dist/popover.min.js");
}
</script>
스타일 지정 주의사항: 폴리필은 실제 :popover-open 의사 클래스를 정의할 수 없으므로 대신 .\:popover-open 클래스를 적용합니다. 필수: :is() 또는 :where()를 사용하여 두 가지를 결합합니다. 그렇지 않으면 :popover-open가 없는 브라우저에서 전체 규칙을 삭제합니다.
[popover]:is(:popover-open, .\:popover-open) {
display: block;
}
또는 폴리필이 없는 기존 대체 기능의 경우 position: fixed를 사용하고 getBoundingClientRect()를 통해 좌표를 수동으로 계산하거나, 사용 사례에 적합한 경우 inset: auto를 사용하여 기본 위치 지정에 의존합니다.
Popover API를 지원하지 않는 브라우저는 앵커 위치 지정도 지원하지 않으므로 도움말이 화면 중앙에 표시됩니다.