Подчеркивание вкладки позиционирования якоря

В меню вкладок должны быть визуальные подсказки, которые помогают пользователям понять, на какой странице они находятся. Один из вариантов – подчеркивание вкладки. С помощью позиционирования привязки вы можете создать плавную анимацию между позициями подчеркивания. Это не работает, если при переходе на активную вкладку загружается новая веб-страница.

Этот эффект также можно использовать, чтобы добавить анимированную точку, указывающую на активную вкладку на вертикальной панели вкладок.

Создайте подчеркивание, используя псевдоэлемент ::before для элемента <ul>, содержащего элементы <li>. Использование псевдоэлемента – предпочтительный подход, поскольку он сохраняет 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;
}

Привяжите подчеркивание к якорю активного элемента с помощью position-anchor, соответствующего anchor-name на якоре, и сделайте его 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 aria-current="page" или aria-selected.

<!-- 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;
  }
}