Проблемы с z-index

При работе с библиотекой Shepherd.js часто возникают ситуации, когда всплывающие подсказки или шаги тура перекрываются другими элементами страницы. Основная причина подобных проблем — неправильная настройка z-index у элементов DOM. Shepherd.js использует библиотеку Tippy.js для отображения тултипов и модальных подсказок, и каждый шаг тура рендерится в отдельном контейнере, который позиционируется абсолютно относительно документа. Если элементы страницы имеют высокий z-index, тултипы могут оказаться скрытыми за ними.

Контейнеры Shepherd.js и их z-index

По умолчанию Shepherd создаёт контейнеры с классами:

  • .shepherd-element — основной контейнер шага.
  • .shepherd-header, .shepherd-body, .shepherd-footer — внутренние блоки шага.
  • .shepherd-arrow — стрелка, указывающая на целевой элемент.

Эти элементы имеют стандартный z-index, который можно переопределить через CSS или настройки тура:

.shepherd-element {
  z-index: 1000; /* Можно увеличить для перекрытия других элементов */
}

Если на странице есть модальные окна или панели с z-index выше 1000, шаги тура могут оказаться позади них. Для контроля этого используется опция modal или ручное задание стилей через attachTo и кастомные классы.

Использование опции modal и её влияние на z-index

Shepherd.js поддерживает модальные оверлеи, которые затемняют фон страницы:

const tour = new Shepherd.Tour({
  defaultStepOptions: {
    classes: 'shepherd-theme-arrows',
    scrollTo: true,
    modalOverlayOpeningPadding: 5
  },
  useModalOverlay: true
});

Модальный оверлей создаёт отдельный DOM-элемент с собственным z-index. Проблемы могут возникнуть, если:

  • Оверлей имеет z-index меньше, чем некоторые элементы страницы.
  • Шаги тура рендерятся внутри контейнера с меньшим z-index.

В таких случаях рекомендуется явно задать z-index для модального оверлея:

.shepherd-modal-overlay-container {
  z-index: 2000; /* Повышаем поверх большинства элементов */
}

Шаги с attachTo и перекрытие целевых элементов

При использовании шага с привязкой к элементу страницы (attachTo) иногда шаг может скрыться за другим блоком. Это связано с контекстом stacking context в CSS. Если родительский элемент целевого блока имеет position: relative и высокий z-index, а шаг туры создаётся в body, тултип может оказаться ниже.

Решения:

  1. Использовать кастомные классы и повышать z-index шага:
tour.addStep({
  title: 'Пример шага',
  text: 'Текст подсказки',
  attachTo: { element: '#button', on: 'bottom' },
  classes: 'custom-zindex'
});
.custom-zindex {
  z-index: 3000 !important;
}
  1. Рендерить шаги внутри родительского контейнера — через опцию appendTo можно указать родителя, который имеет высокий z-index, чтобы шаг оказался поверх других элементов.
appendTo: document.querySelector('#high-zindex-container')

Динамическое управление z-index

В некоторых проектах страницы динамически изменяют порядок слоёв (например, всплывающие меню или сторонние библиотеки UI). Для таких случаев рекомендуется:

  • Отслеживать появление новых элементов с высоким z-index.
  • Динамически обновлять z-index шагов Shepherd через метод updateStepOptions:
tour.getCurrentStep().updateStepOptions({
  classes: 'updated-zindex'
});
  • В качестве альтернативы использовать MutationObserver для контроля появления элементов с высоким z-index и поднимать слой шагов туры выше.

Влияние CSS-переменных и тем

Shepherd.js поддерживает CSS-переменные для управления стилями шагов. Иногда темы задают z-index через переменные, что может конфликтовать с локальными стилями страницы. В таких случаях следует:

:root {
  --shepherd-z-index: 2500;
}

Или через кастомные классы шагов, чтобы повысить приоритет:

.shepherd-theme-arrows {
  z-index: 2500 !important;
}

Практические советы

  • Всегда проверять контекст стэка (stacking context) родительских элементов целевого блока.
  • Для модального оверлея задавать z-index выше, чем у всех элементов страницы.
  • Для шагов с attachTo использовать кастомные классы и повышенные z-index.
  • При динамическом UI применять MutationObserver или метод updateStepOptions.
  • При интеграции с сторонними библиотеками UI учитывать их z-index и при необходимости использовать локальный контейнер через appendTo.

Эффективное управление z-index в Shepherd.js позволяет сделать туры видимыми и интерактивными даже на страницах со сложным UI и множеством слоёв элементов.