Стилизация компонентов

Radix UI предоставляет низкоуровневые, полностью доступные UI-компоненты, которые можно гибко стилизовать. Компоненты поставляются без предопределённых стилей, что позволяет полностью контролировать внешний вид с помощью CSS, Tailwind или CSS-in-JS решений. Основной принцип работы с ними заключается в разделении структуры компонента и его визуального представления.

Каждый компонент Radix UI состоит из нескольких частей: корневой элемент, триггер, контент и дополнительные вспомогательные элементы (например, Indicator или Portal). Для стилизации важно понимать, какие элементы являются корневыми и какие атрибуты они получают.


Селекторы и классы

Radix UI использует систему data-атрибутов, которые отражают состояние компонента. Это позволяет писать CSS, ориентированный на поведение компонента, а не только на структуру DOM.

Примеры атрибутов:

  • data-state="open" / data-state="closed" — для раскрывающихся элементов, таких как DropdownMenu или Accordion.
  • data-disabled — для неактивных элементов.
  • data-highlighted — для элементов, находящихся в состоянии наведения или фокусировки.
  • data-orientation="horizontal" / data-orientation="vertical" — для компонентов с осевой ориентацией, например, Tabs или Accordion.

Пример CSS:

[data-state="open"] {
  opacity: 1;
  transform: scaleY(1);
}

[data-state="closed"] {
  opacity: 0;
  transform: scaleY(0);
  transition: all 0.2s ease;
}

[data-disabled] {
  opacity: 0.5;
  pointer-events: none;
}

Использование этих атрибутов позволяет создавать динамическую и отзывчивую стилизацию, не вмешиваясь в логику работы компонента.


Комбинированная стилизация с Tailwind

Tailwind CSS хорошо сочетается с Radix UI благодаря возможности динамического применения классов через data-атрибуты. Например, для компонента Accordion:

<Accordion.Root type="single" collapsible>
  <Accordion.Item value="item-1" className="border-b border-gray-200">
    <Accordion.Header>
      <Accordion.Trigger className="flex justify-between w-full py-2 text-left">
        Пункт 1
      </Accordion.Trigger>
    </Accordion.Header>
    <Accordion.Content
      className="overflow-hidden transition-all duration-300 [data-state=open]:pb-4 [data-state=closed]:pb-0"
    >
      Контент 1
    </Accordion.Content>
  </Accordion.Item>
</Accordion.Root>

Здесь используются групповые селекторы Tailwind, применяемые через data-атрибуты, что делает анимацию раскрытия плавной и полностью управляемой.


Стилизация через CSS-in-JS

Для библиотек вроде styled-components или @emotion/styled Radix UI позволяет создавать стилизованные компоненты, сохраняя полную доступность и логику:

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

const StyledOverlay = styled(Dialog.Overlay)`
  background: rgba(0, 0, 0, 0.5);
  position: fixed;
  inset: 0;
`;

const StyledContent = styled(Dialog.Content)`
  background: white;
  border-radius: 8px;
  padding: 20px;
  max-width: 500px;
  margin: auto;
  [data-state='open'] {
    animation: slideDown 0.3s ease-out forwards;
  }
  [data-state='closed'] {
    animation: slideUp 0.2s ease-in forwards;
  }
`;

Преимущество такого подхода — инкапсуляция стилей внутри компонента, возможность использования динамических props для изменения внешнего вида и интеграция с анимациями.


Анимации и переходы

Radix UI не накладывает ограничений на анимацию. Использование data-state позволяет управлять состояниями плавно. Часто применяют CSS transitions, keyframes или библиотеки типа framer-motion.

Пример анимации для выпадающего меню:

[data-state="open"] {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

[data-state="closed"] {
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 0.15s ease, transform 0.15s ease;
}

Фокусировка и наведение также легко анимируются с помощью data-highlighted:

[data-highlighted] {
  background-color: #f3f4f6;
  transition: background-color 0.2s ease;
}

Работа с темами

Radix UI совместим с системами управления темами. Наиболее распространённый подход — использование CSS-переменных. Например:

:root {
  --color-bg: #ffffff;
  --color-text: #111827;
}

[data-theme='dark'] {
  --color-bg: #1f2937;
  --color-text: #f9fafb;
}

.Button {
  background-color: var(--color-bg);
  color: var(--color-text);
  padding: 0.5rem 1rem;
  border-radius: 6px;
}

Компоненты автоматически наследуют переменные, сохраняя структуру и доступность, а внешний вид полностью контролируется.


Полезные практики стилизации

  1. Не изменять внутренние структуры компонента напрямую — всегда использовать предоставленные селекторы и data-атрибуты.
  2. Разделять стили состояния и базовые стили — базовый вид и вид при открытии/выборе/фокусе.
  3. Использовать CSS-переменные для темизации — упрощает переход между светлой и тёмной темами.
  4. Инкапсулировать стили для модульности — Styled Components, Tailwind с className, или CSS Modules.
  5. Сохранять доступность — Radix UI уже обеспечивает ARIA-атрибуты, не удалять их в процессе стилизации.

Соблюдение этих принципов позволяет создавать профессиональные, отзывчивые и доступные интерфейсы, полностью используя потенциал Radix UI.