UI-паттерны из Uiverse (Galaxy)
Каталог Galaxy — архив более 3000 UI-сниппетов с Uiverse.io: HTML и inline CSS, без JavaScript. Лицензия MIT — можно учиться, копировать и менять; желательно указывать автора сниппета и Uiverse.
Здесь — не полная копия репозитория, а подборка техник с упрощённым кодом и разбором. Теория по кнопкам, формам и сетке — Типовые элементы интерфейса; анимации — CSS-анимации. Когда CSS недостаточно — Работа с HTML в JavaScript.
Как пользоваться каталогом
| Шаг | Действие |
|---|---|
| 1 | Скопируйте блок HTML+CSS в playground выше или в test.html |
| 2 | Сравните с разделом в 113.md — там базовые варианты |
| 3 | Проверьте Tab, Enter, контраст, prefers-reduced-motion |
| 4 | Для React/Vue вынесите разметку в компонент, стили — в модуль; типы — TypeScript и React |
В Galaxy часто много <div> вместо <button>, нет focus trap у модалок и нет очереди toast. Берите технику (shimmer, :has(), кастомный radio), а разметку приводите к семантике из энциклопедии.
Skeleton (карточка)
Техника: linear-gradient + background-size + @keyframes для shimmer.
Источник (идея): Uiverse, vk-uiux — категория loaders.
<div class="card">
<div class="card__skeleton card__title"></div>
<div class="card__skeleton card__description"></div>
</div>
<style>
.card {
width: 18rem;
padding: 1rem;
border-radius: 0.8rem;
background: #fff;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.card__skeleton {
border-radius: 6px;
background: linear-gradient(90deg, #e9ecef 0, #f8f9fa 45%, #e9ecef 90%);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
}
.card__title { height: 14px; margin-bottom: 12px; width: 75%; }
.card__description { height: 80px; }
@keyframes shimmer { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) {
.card__skeleton { animation: none; background: #e9ecef; }
}
</style>
Энциклопедическая версия с aria-busy — Скелетон загрузки.
Спиннер с доступностью
Техника: role="progressbar", aria-busy, aria-label.
Источник (идея): Uiverse, fox-tech0.
<div class="loader" role="progressbar" aria-busy="true" aria-label="Загрузка">
<span></span><span></span><span></span>
</div>
<style>
.loader {
display: flex;
gap: 0.35rem;
padding: 1rem;
}
.loader span {
width: 0.65rem;
height: 0.65rem;
border-radius: 50%;
background: var(--color-primary, #7b68ee);
animation: bounce 0.6s ease-in-out infinite;
}
.loader span:nth-child(2) { animation-delay: 0.1s; }
.loader span:nth-child(3) { animation-delay: 0.2s; }
@keyframes bounce {
0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
40% { transform: scale(1); opacity: 1; }
}
</style>
Больше loaders — CSS-анимации — спиннер.
Переключатель темы (:has())
Техника: родитель .panel:has(input:checked) меняет фон; role="switch".
Источник (идея): Uiverse, csemszepp.
<div class="panel">
<label class="sw">
<input type="checkbox" role="switch" class="sw__in">
<span class="sw__track"></span>
<span class="sw__sr">Тёмная тема</span>
</label>
</div>
<style>
.panel {
padding: 2rem;
border-radius: 12px;
background: #f0f0f0;
transition: background 0.3s, color 0.3s;
}
.panel:has(.sw__in:checked) {
background: #1a1a2e;
color: #eee;
}
.sw { display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; }
.sw__in { position: absolute; opacity: 0; }
.sw__track {
width: 48px; height: 24px; border-radius: 12px;
background: #adb5bd; position: relative;
}
.sw__track::before {
content: ""; position: absolute; width: 20px; height: 20px;
left: 2px; top: 2px; border-radius: 50%; background: #fff;
transition: transform 0.25s ease;
}
.sw__in:checked + .sw__track { background: #7b68ee; }
.sw__in:checked + .sw__track::before { transform: translateX(24px); }
.sw__sr {
position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0);
}
</style>
Разбор в энциклопедии — Переключатель темы и :has().
Поиск без JavaScript
Техника: type="search", :focus, :valid, transform на ширине.
Источник (идея): Uiverse, fanishah.
<form class="sb">
<input class="sb__in" type="search" name="q" required autocomplete="off" aria-label="Поиск">
<button type="submit" class="sb__btn">⌕</button>
</form>
<style>
.sb { display: flex; max-width: 24rem; margin: 1rem auto; }
.sb__in, .sb__btn { height: 3rem; transition: all 0.25s ease; }
.sb__in {
width: 3rem; border: none; border-radius: 1.5rem;
box-shadow: inset 0 0 0 2px #333; padding: 0 0.75rem;
}
.sb__in:focus, .sb__in:valid {
width: 100%; background: #fff; border-radius: 0.375rem 0 0 0.375rem;
box-shadow: inset 0 0 0 1px #ccc;
}
.sb__btn {
width: 3rem; border: none; border-radius: 0 0.75rem 0.75rem 0;
background: #333; color: #fff; cursor: pointer;
}
.sb__in:focus + .sb__btn, .sb__in:valid + .sb__btn {
width: auto; padding: 0 1rem; border-radius: 0 0.375rem 0.375rem 0;
}
</style>
Радиокнопки
Техника: скрытый input + label[for]; стили :checked + label; общий name.
Источник (идея): Uiverse, shadowmurphy (анимация «червяка» упрощена).
<form class="rg">
<input type="radio" name="plan" id="p1" value="a" checked>
<label for="p1">Базовый</label>
<input type="radio" name="plan" id="p2" value="b">
<label for="p2">Про</label>
<input type="radio" name="plan" id="p3" value="c">
<label for="p3">Команда</label>
</form>
<style>
.rg { max-width: 12rem; margin: 1rem auto; }
.rg input { position: fixed; top: -10px; left: -10px; }
.rg label {
display: block; padding: 0.5rem 0.75rem; margin-bottom: 0.5rem;
border: 2px solid #dee2e6; border-radius: 8px; cursor: pointer;
transition: border-color 0.2s, color 0.2s;
}
.rg input:checked + label {
border-color: #7b68ee; color: #7b68ee; font-weight: 600;
}
</style>
Энциклопедия — Радиокнопки (radio).
Подсказки (tooltip)
Техника: attr(data-tooltip) в ::after; на hover/focus — показ. Для панели с иконками нужен JS.
Источник (идея): Uiverse, Mohammad-Rahme-576.
<button type="button" class="tip" data-tooltip="Поделиться ссылкой">Share</button>
<style>
.tip {
position: relative;
padding: 0.6rem 1.2rem;
border: none;
border-radius: 999px;
background: linear-gradient(135deg, #6e8efb, #a777e3);
color: #fff;
cursor: pointer;
}
.tip::after {
content: attr(data-tooltip);
position: absolute;
left: 50%;
bottom: calc(100% + 6px);
transform: translateX(-50%);
padding: 0.35rem 0.6rem;
font-size: 0.75rem;
background: #212529;
color: #fff;
border-radius: 6px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s;
}
.tip:hover::after, .tip:focus-visible::after { opacity: 1; }
</style>
Кнопка с «глубиной» (brutalist)
Техника: многослойный box-shadow, :active сдвигает «плиту».
Источник (идея): Uiverse, 0xnihilism.
<button type="button" class="brutal">Нажми</button>
<style>
.brutal {
font: 600 1rem/1.2 system-ui, sans-serif;
padding: 0.75rem 1.5rem;
border: 3px solid #111;
border-radius: 4px;
background: #ffe066;
box-shadow: 4px 4px 0 #111;
cursor: pointer;
transition: transform 0.1s, box-shadow 0.1s;
}
.brutal:active {
transform: translate(3px, 3px);
box-shadow: 1px 1px 0 #111;
}
</style>
Уведомление (toast)
Техника: CSS variables на блоке, @keyframes slide-in. Очередь и автозакрытие — в JS.
Источник (идея): Uiverse, WittyHydra.
<div class="toast" role="status">
<strong>Готово</strong>
<p>Настройки сохранены</p>
</div>
<style>
.toast {
--bg: #fff;
--fg: #212529;
--accent: #7b68ee;
max-width: 16rem;
padding: 1rem 1.25rem;
border-left: 4px solid var(--accent);
background: var(--bg);
color: var(--fg);
border-radius: 8px;
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
animation: toast-in 0.4s ease-out;
}
.toast p { margin: 0.25rem 0 0; font-size: 0.875rem; opacity: 0.85; }
@keyframes toast-in {
from { opacity: 0; transform: translateY(-12px); }
to { opacity: 1; transform: translateY(0); }
}
@media (prefers-color-scheme: dark) {
.toast { --bg: #2d2d3a; --fg: #f8f9fa; }
}
</style>
CSS-паттерн фона
Техника: conic-gradient + background-size для бесшовного узора без картинок.
Источник (идея): Uiverse, mobinkakei — категория Patterns.
<div class="pattern-demo">Контент поверх узора</div>
<style>
.pattern-demo {
min-height: 8rem;
display: grid;
place-items: center;
font-weight: 600;
color: #333;
background-color: #fafafa;
background-image: repeating-conic-gradient(
from 0deg at 50% 50%,
#e9ecef 0deg 90deg,
transparent 90deg 180deg
);
background-size: 24px 24px;
}
</style>
Таблица техник Galaxy → энциклопедии
| Категория в Galaxy | ~Файлов | Где учиться у нас |
|---|---|---|
| Buttons | 1231 | Кнопки, § brutal выше |
| loaders | 717 | 1116, Skeleton в 113 |
| Cards | 724 | Карточки |
| Toggle-switches | 260 | Switch |
| Inputs / Forms | 400+ | Поля, Поиск CSS |
| Checkboxes / Radio | 270 | Checkbox, Radio |
| Tooltips | 62 | Tooltip |
| Notifications | 23 | Уведомления |
| Patterns | 103 | § паттерн фона выше, градиенты |
Нет в Galaxy: модалки, таблицы, navbar — у нас уже в 113.md.
Дальше
| Цель | Материал |
|---|---|
| Целая страница | HTML-страницы целиком |
| Макет + сетка | HTML + CSS — макеты |
| Компонент в React | 1146 — JSX, 1146 — TypeScript, TS + React |
| Оригинальные сниппеты | github.com/uiverse-io/galaxy |