앵커 위치 지정 탭 밑줄

탭 메뉴에서는 사용자에게 현재 어떤 페이지에 있는지 시각적인 힌트를 제공해야 합니다. 한 가지 옵션은 탭에 밑줄을 긋는 것입니다. 앵커 위치 지정을 사용하면 밑줄 위치 간에 부드러운 애니메이션을 만들 수 있습니다. 활성 탭을 변경하여 새 웹페이지를 로드하는 경우에는 작동하지 않습니다.

이 효과를 사용하여 애니메이션 점을 추가하여 세로 탭 표시줄에서 활성 탭을 나타낼 수도 있습니다.

<li> 요소가 포함된 <ul>에서 ::before 가상 요소를 사용하여 밑줄을 만듭니다. 의사 요소를 사용하면 DOM을 깔끔하게 유지하고 순전히 장식 효과를 위해 추가 요소를 추가하지 않아도 되므로 이 방법이 더 좋습니다.

ul::before {
  /* Use a pseudo-element on the container to represent the animated indicator */
  content: '';
}

--로 시작하는 값을 가진 anchor-name 속성을 추가하여 활성 목록 항목을 앵커로 만듭니다.

li.active {
  /* Make a unique anchor-name for the active element. */
  anchor-name: --active;
}

앵커의 anchor-name와 일치하는 position-anchor를 사용하여 밑줄을 활성 항목 앵커에 연결하고 position: absolute로 만듭니다.

ul::before {
  /* Tether the underline to the active element. */
  position: absolute;
  position-anchor: --active;
}

인셋 속성과 anchor() 함수를 사용하여 앵커를 기준으로 밑줄을 배치합니다.

ul::before {
  /* DO NOT use position-area, which can not be transitioned. */
  /* Use calc() to offset the top slightly */
  inset-block-start: calc(anchor(bottom) + .1lh);
  inset-inline-start: anchor(left);
  inset-inline-end: anchor(right);
}

높이 및 기타 시각적 스타일을 추가합니다.

ul::before {
  /* Apply your project's styles for the indicator */
  block-size: .25lh;
  background: red;
}

마지막으로 inset 속성에 전환을 추가합니다.

ul::before {
  @media (prefers-reduced-motion: no-preference) {
    /* MANDATORY: The transition must be wrapped in a prefers-reduced-motion media query to respect user preferences. */
    transition: inset .2s;
  }
}

이는 시각적 표시기일 뿐이며 적절한 aria-current="page" 또는 aria-selected aria 값을 설정하는 것을 대체해서는 안 됩니다.

<!-- MANDATORY: Provide explicit assistive technology state alongside the visual tab underline -->
<nav aria-label="Primary">
  <ul>
    <li class="active">
      <a href="/home" aria-current="page">Home</a>
    </li>
    <li>
      <a href="/about">About</a>
    </li>
  </ul>
</nav>

대체 전략

브라우저에서 앵커 위치 지정이 지원되지 않는 경우 border-bottom를 사용하여 밑줄을 추가합니다. 애니메이션이 적용되지 않습니다.

ul li.active {
  @supports not (position-anchor: auto) {
    /* Choose a color appropriate to the app theme. */
    border-bottom: .25lh var(--primary) solid;
  }
}