В библиотеке Radix UI overlay — это элемент интерфейса, который используется для создания модальных окон, тултипов, дропдаунов и других компонентов, требующих затемнения или визуального отделения контента. Overlay по умолчанию предоставляет базовую функциональность, но библиотека позволяет гибко кастомизировать его поведение и визуальное оформление.
Overlay в Radix UI обычно состоит из двух ключевых компонентов:
Пример базового использования:
import * as Dialog from '@radix-ui/react-dialog';
<Dialog.Root>
<Dialog.Trigger>Открыть окно</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="overlay" />
<Dialog.Content className="content">
Содержимое окна
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
Здесь Dialog.Overlay создаёт затемнённый фон, а Dialog.Content — сам модальный блок.
Overlay в Radix UI полностью управляется через классы CSS или
стилизованные компоненты (например, styled-components или
@stitches/react). Основные параметры, доступные для
кастомизации:
Цвет фона и прозрачность Используется свойство
background-color с RGBA или HSLA для плавного эффекта
затемнения.
Анимации появления и скрытия Взаимодействие с overlay становится более «живым» через CSS-анимации или keyframes.
Позиционирование и размер Overlay может занимать
весь экран, часть окна или ограниченную область, управляется через
position: fixed/absolute и inset.
Пример с кастомными стилями и анимацией:
import { keyframes, styled } from '@stitches/react';
const fadeIn = keyframes({
'0%': { opacity: 0 },
'100%': { opacity: 1 },
});
const fadeOut = keyframes({
'0%': { opacity: 1 },
'100%': { opacity: 0 },
});
const CustomOverlay = styled(Dialog.Overlay, {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
position: 'fixed',
inset: 0,
animation: `${fadeIn} 200ms ease-out`,
'&[data-state="closed"]': {
animation: `${fadeOut} 200ms ease-in`,
},
});
Использование кастомного overlay:
<Dialog.Portal>
<CustomOverlay />
<Dialog.Content className="content">Содержимое окна</Dialog.Content>
</Dialog.Portal>
Radix UI предоставляет данные о состоянии overlay через атрибуты
data-state и data-open. Это позволяет
управлять логикой появления и скрытия через CSS или JS:
data-state="open" — overlay
видим.data-state="closed" — overlay
скрыт.Можно реагировать на события:
<Dialog.Overlay
onCl ick={() => console.log('Overlay кликнут')}
className="overlay"
/>
Такое управление позволяет реализовать закрытие окна по клику на overlay или запуск анимации при изменении состояния.
Для плавного появления overlay используют CSS-транзишены или анимации keyframes. Radix UI совместим с большинством популярных библиотек анимаций, включая Framer Motion:
import { motion } from 'framer-motion';
const MotionOverlay = motion(Dialog.Overlay);
<Dialog.Portal>
<MotionOverlay
initial={{ opacity: 0 }}
animate={{ opacity: 0.5 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.2 }}
/>
<Dialog.Content>Контент окна</Dialog.Content>
</Dialog.Portal>
Radix UI позволяет создавать несколько overlay с разными z-index и уровнями прозрачности. Для управления стеком используется:
Пример вложенного overlay:
<Dialog.Root>
<Dialog.Trigger>Главное окно</Dialog.Trigger>
<Dialog.Portal>
<CustomOverlay style={{ zIndex: 10 }} />
<Dialog.Content>Первый уровень</Dialog.Content>
<Dialog.Root>
<Dialog.Trigger>Вложенное окно</Dialog.Trigger>
<Dialog.Portal>
<CustomOverlay style={{ zIndex: 20 }} />
<Dialog.Content>Второй уровень</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
</Dialog.Portal>
</Dialog.Root>
transform, opacity) вместо
top/left или width/height..backdrop {
backdrop-filter: blur(4px);
background-color: rgba(0,0,0,0.3);
}
const GradientOverlay = styled(Dialog.Overlay, {
background: 'linear-gradient(180deg, rgba(0,0,0,0.3), rgba(0,0,0,0.6))',
animation: `${fadeIn} 300ms ease`,
});
<Dialog.Overlay onPointerD own={(e) => e.target === e.currentTarget && close()} />
Этот подход обеспечивает полную гибкость в реализации любого типа overlay, от модальных окон до тултипов с анимацией, с точным контролем визуальных эффектов и поведения.