영구 앱 둘러보기 만들기

온보딩 둘러보기에는 사용자가 강조 표시된 기능과 상호작용하는 동안 유지되는 오버레이가 필요합니다. 자동 팝오버와 달리 수동 팝오버는 사용자가 페이지의 다른 곳을 클릭해도 닫히지 않습니다. popover="manual"를 CSS 앵커 위치 지정과 결합하면 모달이 아닌 테더링된 둘러보기 단계를 만들 수 있습니다.

HTML

<div id="feature-target">Highlight this feature</div>

<!-- MANDATORY: Enforce overlay dialog semantics and accessible name bindings -->
<div id="tour-step" popover="manual" role="dialog" aria-labelledby="tour-title">
  <!-- Assume an <h1> precedes this element in the full document outline -->
  <h2 id="tour-title">Step 1</h2>
  <p>Learn how to use this feature.</p>
  <button popovertarget="tour-step" popovertargetaction="hide">Got it</button>
</div>

CSS

#feature-target {
  anchor-name: --feature-target;
}

#tour-step {
  popover: manual;
  position-anchor: --feature-target;
  position-area: right center;
  inset: auto;
  margin: 1rem;
  padding: 1rem;
  border: 1px solid blue;
  border-radius: 0.5rem;
  background: aliceblue;
}

JavaScript

const tourStep = document.getElementById('tour-step');
tourStep.showPopover();
// MANDATORY: Programmatically route focus into the non-modal popover so keyboard/assistive technology users immediately perceive the new context
tourStep.querySelector('button').focus();

구현 가이드라인

  • 필수: popover="manual"를 사용하여 사용자 상호작용 중에 둘러보기 단계가 실수로 종료되지 않도록 합니다.
  • 필수: 컨테이너를 role="dialog"로 표시하고 aria-labelledby를 통해 제목을 연결합니다.
  • 필수: 포커스 이탈을 방지하기 위해 팝오버를 연 직후 팝오버 내부로 프로그래매틱 포커스를 이동합니다.
  • 권장사항: CSS 앵커 포지셔닝을 사용하여 둘러보기 단계를 설명 중인 특정 기능에 연결합니다.
  • popovertargetaction="hide"를 사용하는 팝오버 내에 명시적인 '닫기' 또는 '다음' 버튼을 제공해야 합니다.

대체 전략

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를 사용하여 기본 위치 지정에 의존합니다.

anchor-positioning

앵커 위치 지정을 지원하지 않는 브라우저를 지원하려면 폴리필 또는 순수 CSS 대체 중 하나를 선택하면 됩니다.

옵션 1: 폴리필 대체

@oddbird/css-anchor-positioning 폴리필을 사용하여 앵커 위치 지정을 에뮬레이션할 수 있습니다. 암시적 앵커를 지원하지 않으므로 트리거에 명시적 앵커 이름을 추가해야 합니다(MUST). 또한 폴리필은 팝오버에서 position-area를 지원하지 않으므로 position-area 대신 원하는 인셋에 anchor()를 사용해야 합니다(MUST).

<script type="module">
  if (!CSS.supports('anchor-name: --foo')) {
    await import("https://unpkg.com/@oddbird/css-anchor-positioning");
  }
</script>
#tour-step {
  /* If using the anchor positioning polyfill with a popover, DO use `anchor()` functions instead of `position-area`. */
  left: anchor(right);
  top: anchor(top);
}
옵션 2: 비폴리필 CSS 대체

폴리필을 사용하지 않으려면 @supports not를 사용하여 표시 영역 하단의 고정된 위치로 도움말을 기본 설정하면 됩니다.

@supports not (anchor-name: --foo) {
  #tour-step {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    margin: 0;
    border-radius: 0;
  }
}