Управление z-index

Radix UI — это библиотека компонентов для React, ориентированная на создание доступных и гибких интерфейсов. Одним из критически важных аспектов при работе с интерфейсами является управление слоями отображения элементов, что напрямую связано с CSS-свойством z-index. В Radix UI управление z-index встроено в компоненты через контексты слоёв, что упрощает работу с перекрывающимися элементами, такими как модальные окна, тултипы, всплывающие меню и поповеры.


Контекст слоёв (Layering Context)

В Radix UI каждый компонент, который может перекрываться с другими, работает с контекстом слоёв. Это позволяет автоматически управлять порядком рендеринга и предотвращает проблемы с конфликтами z-index.

  • Portal — большинство Radix-компонентов используют портал для рендеринга вне DOM-иерархии родителя. Это гарантирует, что элемент будет визуально поверх других.
  • Root и Provider — библиотека предоставляет контексты, которые могут управлять глобальными z-index для всех компонентов внутри приложения.

Пример использования провайдера контекста слоёв:

import { Layer } from '@radix-ui/react-layer';

<Layer.Provider>
  <Tooltip />
  <Dialog />
</Layer.Provider>

Здесь Layer.Provider автоматически назначает правильные уровни z-index для компонентов внутри.


Уровни z-index в Radix UI

Radix UI использует системный подход к слоям отображения, где каждый тип компонента имеет предопределённый приоритет:

Компонент z-index по умолчанию Комментарий
Tooltip 1000 Поверх контента, но под модальными окнами
DropdownMenu / Popover 1100 Выше тултипов, ниже диалогов
Dialog / Modal 1200 Всплывающие окна, перекрывающие основное содержимое
Toast 1300 Сообщения уведомлений поверх всего

Такая система предотвращает неожиданное перекрытие элементов, особенно при множественных слоях интерфейса.


Управление z-index вручную

Radix UI предоставляет возможность переопределять z-index через пропсы и стили. Для большинства компонентов это делается через style или className, либо через пользовательские контексты.

Пример для Dialog:

import * as Dialog from '@radix-ui/react-dialog';

<Dialog.Root>
  <Dialog.Trigger>Открыть окно</Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay style={{ zIndex: 1500 }} />
    <Dialog.Content style={{ zIndex: 1500 }}>
      Контент модального окна
    </Dialog.Content>
  </Dialog.Portal>
</Dialog.Root>

В данном примере переопределение z-index гарантирует, что диалоговое окно будет поверх всех других слоёв.


Работа с несколькими порталами

Если в приложении используются несколько порталов, важно учитывать, что z-index считается относительно ближайшего контекста. Radix UI решает это через автоматическое создание контекста слоёв в Layer.Provider. Без него порталы могут конфликтовать:

<Layer.Provider>
  <DropdownMenu />
  <Dialog />
</Layer.Provider>

Если Layer.Provider не используется, необходимо следить за z-index вручную, иначе возможны ситуации, когда тултип окажется выше диалогового окна.


Использование Layer API

Компоненты Radix UI имеют встроенный API для управления слоями через <Layer> и <Layer.Provider>.

  • Layer — назначает элементу уровень иерархии.
  • Layer.Provider — управляет глобальными уровнями z-index.

Пример:

import { Layer } from '@radix-ui/react-layer';

<Layer.Provider>
  <Layer level={2}>
    <Tooltip>Тултип поверх основного контента</Tooltip>
  </Layer>
  <Layer level={3}>
    <Dialog>Модальное окно выше тултипа</Dialog>
  </Layer>
</Layer.Provider>

level соответствует приоритету слоя, чем выше число, тем выше элемент отображается на экране.


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

  • Всегда использовать Portal для компонентов, которые должны быть поверх других элементов.
  • Для сложных интерфейсов с множеством перекрывающихся слоёв подключать Layer.Provider, чтобы избежать ручного управления z-index.
  • Использовать предопределённые уровни z-index Radix UI для согласованного отображения элементов.
  • При переопределении z-index учитывать, что числовое значение должно быть выше всех нижестоящих слоёв, но не конфликтовать с глобальной системой уровней.

Управление z-index в Radix UI строится на сочетании порталов, контекстов слоёв и приоритетов компонентов, что позволяет создавать сложные, перекрывающиеся интерфейсы без проблем с визуальной иерархией.