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

При работе с Driver.js часто возникает ситуация, когда подсветка элементов и тултипы оказываются не видны или перекрываются другими элементами страницы. Это напрямую связано с особенностями работы CSS-свойства z-index и порядком построения слоев в DOM.

Как работает z-index в контексте Driver.js

Driver.js создаёт поверх DOM полупрозрачный оверлей и выделяет активный элемент. Основные элементы, которые используют z-index:

  1. Overlay – затемнённый фон, блокирующий взаимодействие с остальной страницей.
  2. Tooltip/Popovers – элементы с текстовыми подсказками.
  3. Highlighted Element Clone – иногда создаётся копия выделяемого элемента для эффекта подсветки.

По умолчанию Driver.js устанавливает z-index для оверлея и тултипов достаточно высоко (например, z-index: 9999), чтобы перекрывать обычные элементы страницы. Однако если на странице присутствуют элементы с явно установленным z-index выше этого значения, подсветка и подсказки будут находиться ниже этих элементов, что делает их невидимыми.

Типичные причины проблем

  • Фиксированные или абсолютно позиционированные элементы с высоким z-index Элементы, такие как sticky header, модальные окна или меню с position: fixed и z-index: 10000+, могут перекрывать подсветку.

  • Контекст наложения (stacking context) В CSS каждый контейнер с position: relative/absolute/fixed и z-index создаёт новый контекст наложения. Если родитель элемента имеет z-index выше оверлея Driver.js, подсветка не сможет выйти за пределы этого контекста, даже если у Driver.js высокий z-index.

  • Использование transform, opacity и filter Любой родительский элемент с transform, opacity < 1 или filter создаёт новый контекст наложения, что тоже может блокировать отображение подсветки и тултипов.

Способы решения

  1. Повышение z-index через настройки Driver.js

Driver.js позволяет настраивать z-index оверлея и тултипов через опции:

const driver = new Driver({
  stageBackground: '#ffffff', // цвет оверлея
  allowClose: true,
  padding: 10,
  zIndex: 20000 // увеличение z-index
});

Это часто решает проблему с элементами, которые перекрывают подсветку, но не всегда, если проблема в stacking context.

  1. Перемещение Driver.js в конец body

По умолчанию скрипт создаёт оверлей в том месте DOM, где загружен. Если родительский контейнер имеет ограниченный контекст наложения, можно вручную переместить оверлей в конец body:

document.body.appendChild(document.querySelector('.driver'));

Это позволяет обойти большинство ограничений контекста.

  1. Проверка stacking context у родительских элементов
  • Убедиться, что родительские контейнеры выделяемого элемента не имеют z-index выше оверлея.
  • Если нельзя изменить родительский контейнер, иногда помогает временное применение position: static или z-index: auto через CSS перед запуском Driver.js.
  1. Использование fixed-позиционирования для тултипов

Driver.js по умолчанию использует absolute позиционирование. Если подсветка перекрывается скроллируемыми элементами, можно задать тултипам position: fixed через кастомный CSS:

.driver-tooltip {
  position: fixed !important;
}
  1. Динамическая корректировка позиции

Если элементы на странице динамически изменяют положение (например, анимация или lazy-load), важно вызвать driver.refresh() после изменения DOM, чтобы пересчитать позиции подсветки и тултипов.

Практические рекомендации

  • Всегда проверять, какие элементы на странице имеют z-index выше 9999.
  • Избегать фиксированных контейнеров с высоким z-index в местах, где планируется подсветка.
  • Для сложных интерфейсов с многослойной структурой использовать кастомные z-index через опцию Driver.js и фиксированные тултипы.
  • Проверять наличие transform, filter, opacity у родительских контейнеров, так как они создают неожиданные stacking context.
  • Если проблема не решается, можно создать отдельный контейнер для Driver.js поверх всего DOM, гарантируя максимальный z-index.

Правильное управление z-index в сочетании с пониманием контекста наложения позволяет использовать Driver.js на сложных страницах без визуальных конфликтов и скрытых подсветок.