26 KiB
name, title, description, tags, source
| name | title | description | tags | source | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| concepts/ux-guidelines-99 | 99 UX Guidelines | 99 practical UX rules with code examples, sorted by category and severity. |
|
ui-ux-pro-max-skill |
99 UX Guidelines
Практические правила UX, проверенные на реальных продуктах. Каждое правило содержит: что делать, чего НЕ делать, код-пример.
Severity Legend
| Бейдж | Значение |
|---|---|
| 🔴 High | Критично — влияет на доступность, конверсию, Core Web Vitals |
| 🟡 Medium | Важно — ухудшает UX, но не критично |
| 🟢 Low | Рекомендуется — мелкое улучшение |
Navigation (6 правил)
1. Smooth Scroll — High
Anchor links должны прокручивать плавно к целевому разделу.
html { scroll-behavior: smooth; }
❌ <a href='#section'> без CSS — прыжок
2. Sticky Navigation — Medium
Фиксированная навигация не должна перекрывать контент.
<div class="pt-20"> <!-- если nav height = h-20 -->
❌ Нет компенсации padding
3. Active State — Medium
Текущая страница/секция должна быть визуально обозначена.
<span class="text-primary border-b-2">Home</span>
❌ Все ссылки одного стиля
4. Back Button — High
На мобильных пользователи ожидают предсказуемого «назад».
history.pushState(null, '', '/page');
❌ location.replace() — ломает историю
5. Deep Linking — Medium
URL должны отражать текущее состояние для шаринга.
<!-- /page?sort=price&dir=asc -->
❌ Один URL для всех состояний
6. Breadcrumbs — Low
Показывать путь пользователя в иерархии сайта (3+ уровней).
<nav><ol>
<li><a href="/">Home</a></li>
<li><a href="/cat">Category</a></li>
<li>Product</li>
</ol></nav>
❌ Только на глубоких вложенных страницах
Animation (8 правил)
7. Excessive Motion — High
Слишком много анимаций отвлекают и вызывают укачивание.
✅ Анимировать 1-2 ключевых элемента на экран.
❌ animate-bounce на 5+ элементах
8. Duration Timing — Medium
Анимации должны ощущаться отзывчивыми, а не вялыми.
transition-all duration-200; /* 150-300ms */
❌ duration-1000 для UI
9. Reduced Motion — High
Уважать настройки пользователя о движении.
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
❌ Нет проверки media query
10. Loading States — High
Показывать обратную связь во время асинхронных операций.
<div class="animate-pulse"><div class="h-4 bg-gray-200 rounded w-3/4"></div></div>
❌ Пустой экран во время загрузки
11. Hover vs Tap — High
Hover-эффекты не работают на тач-устройствах.
<button onClick={handler}>Click</button>
❌ Только onMouseEnter для важных действий
12. Continuous Animation — Medium
Бесконечные анимации отвлекают.
✅ animate-spin только на лоадерах.
❌ animate-bounce на иконках
13. Transform Performance — Medium
Некоторые CSS-свойства вызывают дорогостоящие repaints.
transform: translateY(-10px); /* GPU-accelerated */
opacity: 0.8;
❌ Анимация top: 10px — trigger layout
14. Easing Functions — Low
Линейное движение выглядит роботизированным.
transition-timing-function: ease-out; /* вход */
transition-timing-function: ease-in; /* выход */
❌ linear для UI
Layout (7 правил)
15. Z-Index Management — High
Конфликты stacking context'а прячут элементы.
<div class="z-10"><div class="z-20"></div></div>
❌ z-[9999] — хаос
16. Overflow Hidden — Medium
Скрытый overflow может обрезать контент.
<div class="overflow-auto"><div class="w-max">...</div></div>
❌ overflow-hidden на контейнере с текстом
17. Fixed Positioning — Medium
Фиксированные элементы могут перекрывать друг друга.
<header class="fixed top-0 left-0 right-0 h-20 z-50">
<main class="pt-20">
❌ Несколько overlapping fixed без gap
18. Stacking Context — Medium
Новый stacking context сбрасывает z-index.
<!-- Parent creates new stacking context -->
<div class="relative z-10">
<div class="z-50"></div> <!-- только внутри parent -->
</div>
❌ z-index: 9999 не работает через контекст
19. Content Jumping — High
Сдвиг layout при загрузке контента — дёргает.
<img src="..." class="aspect-video" alt="..." />
❌ Нет размеров на изображениях — контент прыгает
20. Viewport Units — Medium
100vh проблематичен на мобильных (адресная строка).
<div class="min-h-dvh"> <!-- dynamic viewport height -->
❌ h-screen на мобильных — обрезка контента
21. Container Width — Medium
Слишком широкий текст трудно читать.
<p class="max-w-prose">...</p> <!-- ~65ch -->
❌ Текст на всю ширину viewport
Touch (6 правил)
22. Touch Target Size — High
Маленькие кнопки трудно нажимать точно.
<button class="min-h-[44px] min-w-[44px]">Tap</button>
❌ w-6 h-6 — 24px, ниже минимума
23. Touch Spacing — Medium
Расстояние между тач-целями — минимум 8px.
<button class="gap-2">Buttons</button>
❌ gap-0 или gap-1 между кнопками
24. Gesture Conflicts — Medium
Кастомные жесты могут конфликтовать с системой.
<!-- Vertical scroll primary, horizontal only in carousels -->
<div class="overflow-x-auto overflow-y-visible">
❌ Горизонтальный свайп на основном контенте
25. Tap Delay — Medium
300ms tap delay ощущается как лаг.
button { touch-action: manipulation; }
❌ Нет touch-оптимизации — 300ms задержка
26. Pull to Refresh — Low
Случайное обновление — раздражает.
<body style="overscroll-behavior: contain;">
❌ Стандартное поведение (pull-down на всём)
27. Haptic Feedback — Low
Тактильная обратная связь улучшает взаимодействие.
if ('vibrate' in navigator) navigator.vibrate(10);
❌ Вибрация при каждом тапе
Interaction (8 правил)
28. Focus States — High
Клавиатурные пользователи видят фокус только через visible focus.
<button class="focus:ring-2 focus:ring-blue-500">
❌ outline-none без замены
29. Hover States — Medium
Визуальная обратная связь на интерактивных элементах.
<button class="hover:bg-gray-100 cursor-pointer">
❌ Нет hover-стиля на кликабельных элементах
30. Active States — Medium
Немедленная обратная связь при нажатии.
<button class="active:scale-95 transition-transform">
❌ Нет active state
31. Disabled States — Medium
Чётко указывать неинтерактивные элементы.
<button disabled class="opacity-50 cursor-not-allowed">
❌ Disabled выглядит как enabled
32. Loading Buttons — High
Предотвращать двойную отправку формы.
<button disabled={loading} className={loading ? 'animate-pulse' : ''}>
{loading ? 'Processing...' : 'Submit'}
</button>
❌ Кнопка кликабельна во время загрузки
33. Error Feedback — High
Пользователь должен знать об ошибке.
<div class="text-red-600 text-sm mt-1">Invalid email</div>
❌ Тихий fail — нет индикации
34. Success Feedback — Medium
Подтверждать успешные действия.
<div className="text-green-600 flex items-center gap-2">
<CheckIcon /> Saved successfully
</div>
❌ Действие завершается без подтверждения
35. Confirmation Dialogs — High
Подтверждать деструктивные действия.
<button onClick={() => setShowModal(true)}>Delete</button>
<!-- Modal: Are you sure? -->
❌ Удаление без подтверждения
Accessibility (10 правил)
36. Color Contrast — High
Текст должен быть читаемым на фоне.
/* #333 on white = 7:1 ✅ | #999 on white = 2.8:1 ❌ */
.color { color: #333333; background: #ffffff; }
❌ #999 на #ffffff — fails WCAG AA
37. Color Only — High
Не передавать информацию только цветом.
<span class="text-red-600">
<AlertIcon /> Error: insufficient funds
</span>
❌ Только красная рамка без текста
38. Alt Text — High
У изображений должен быть текстовый эквивалент.
<img src="dog.jpg" alt="Dog playing in park" />
❌ alt="" для контентных изображений
39. Heading Hierarchy — Medium
Экранные читалки используют заголовки для навигации.
<h1>Home</h1><h2>About</h2><h3>Team</h3>
❌ h1 → h4 — пропуск уровней
40. ARIA Labels — High
Интерактивные элементы нужны доступные имена.
<button aria-label="Close menu"><X /></button>
❌ <button><Icon/></button> без aria-label
41. Keyboard Navigation — High
Весь функционал доступен через клавиатуру.
<a href="#" tabindex="0">Link</a>
❌ Недоступные элементы (tabindex не совпадает с визуальным порядком)
42. Screen Reader — Medium
Контент должен иметь смысл при чтении вслух.
<nav>...</nav><main>...</main><article>...</article>
❌ <div> для всего — "div soup"
43. Form Labels — High
Каждый input должен иметь associated label.
<label for="email">Email</label>
<input type="email" id="email" />
❌ Только placeholder='Email'
44. Error Messages — High
Ошибки должны анонсироваться.
<div role="alert" class="text-red-600">Error message</div>
❌ Только красная рамка — screen reader не прочитает
45. Skip Links — Medium
Клавиатурные пользователи должны пропускать навигацию.
<a href="#main" className="sr-only focus:not-sr-only">
Skip to main content
</a>
❌ 100 тапов до контента
Performance (8 правил)
46. Image Optimization — High
Большие изображения замедляют загрузку.
<img src="small.webp" srcset="small.webp 400w, medium.webp 800w, large.webp 1600w"
sizes="(max-width: 640px) 100vw, 50vw" alt="..." />
❌ 4000px изображение для 400px display
47. Lazy Loading — Medium
Загружать контент по мере необходимости.
<img src="below-fold.jpg" loading="lazy" alt="..." />
❌ Все изображения loading="eager"
48. Code Splitting — Medium
Большие бандлы замедляют начальный рендер.
const Dashboard = lazy(() => import('./Dashboard'));
❌ Весь код в main bundle
49. Caching — Medium
Повторные визиты должны быть быстрыми.
Cache-Control: public, max-age=31536000, immutable
❌ Каждый запрос на сервер
50. Font Loading — Medium
Шрифты не должны блокировать рендер.
font-display: swap;
❌ FOIT (Flash of Invisible Text)
51. Third Party Scripts — Medium
Внешние скрипты блокируют рендер.
<script async src="https://analytics.js/tracker.js"></script>
❌ <script src="..."> в head без async
52. Bundle Size — Medium
Большой JavaScript замедляет интерактивность.
# Bundle analyzer
npx webpack-bundle-analyzer stats.json
❌ Без мониторинга размера бандла
53. Render Blocking — Medium
CSS/JS могут блокировать первый рендер.
<link rel="preload" href="/critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
❌ Весь CSS в head блокирует paint
Forms (9 правил)
54. Input Labels — High
Каждый input — видимый label.
<label class="block text-sm font-medium mb-1" for="email">Email</label>
<input id="email" type="email" />
❌ Только placeholder='Email'
55. Error Placement — Medium
Ошибки — рядом с полем.
<input /><div class="text-red-500 text-sm mt-1">Invalid email</div>
❌ Все ошибки вверху формы
56. Inline Validation — Medium
Валидация при blur (не только при submit).
input.addEventListener('blur', validate);
❌ Только onSubmit валидация
57. Input Types — Medium
Использовать правильные типы input.
<input type="email" />
<input type="tel" />
<input type="number" />
❌ type='text' для email
58. Autofill Support — Medium
Помогать браузерам автозаполнять.
<input autocomplete="email" />
<input autocomplete="current-password" />
❌ autocomplete='off' везде
59. Required Indicators — Medium
Обозначать обязательные поля.
<label><span class="after:content-['*'] after:text-red-500">Email</span></label>
❌ Без индикации — пользователь гадает
60. Password Visibility — Medium
Позволять видеть пароль при вводе.
<input type={showPassword ? 'text' : 'password'} />
<button onClick={() => setShowPassword(!showPassword)}>
{showPassword ? 'Hide' : 'Show'}
</button>
❌ Пароль всегда скрыт
61. Submit Feedback — High
Подтверждать статус отправки формы.
{loading && <span>Submitting...</span>}
{success && <span className="text-green-600">Saved!</span>}
❌ Клик — нет ответа
62. Input Affordance — Medium
Inputs должны выглядеть интерактивными.
<input class="border rounded px-3 py-2 bg-white" />
❌ Borderless inputs — выглядят как текст
63. Mobile Keyboards — Medium
Показывать правильную клавиатуру.
<input inputmode="numeric" pattern="[0-9]*" />
❌ Текстовая клавиатура для чисел
Responsive (8 правил)
64. Mobile First — Medium
Сначала мобильный, потом улучшаем.
/* Default mobile styles */
.container { padding: 1rem; }
@media (min-width: 768px) {
.container { padding: 2rem; } /* tablet+ */
}
❌ Desktop-first с max-width query
65. Breakpoint Testing — Medium
Тестировать на всех экранах.
<!-- Test at: 320, 375, 414, 768, 1024, 1440 -->
❌ Только на своём устройстве
66. Touch Friendly — High
Мобильные лейауты — большие touch targets.
<button class="md:min-h-[48px] min-h-[56px]">
❌ Desktop-sized targets на мобильных
67. Readable Font Size — High
Минимум 16px body на мобильных.
<p class="text-base md:text-lg">...</p> <!-- 16px+ -->
❌ text-xs для body текста
68. Viewport Meta — High
Установить viewport для мобильных.
<meta name="viewport" content="width=device-width, initial-scale=1">
❌ Нет viewport meta
69. Horizontal Scroll — High
Избегать горизонтального скролла.
<div class="max-w-full overflow-x-hidden">
❌ Горизонтальный скролл на мобильных
70. Image Scaling — Medium
Изображения — пропорционально контейнеру.
<img class="max-w-full h-auto" />
❌ width='800' fixed — overflow
71. Table Handling — Medium
Таблицы — горизонтальный скролл на мобильных.
<div class="overflow-x-auto">
<table class="min-w-full">...</table>
</div>
❌ Таблица выходит за viewport
Typography (6 правил)
72. Line Height — Medium
Адекватный line-height улучшает читаемость.
<p class="leading-relaxed">...</p> <!-- 1.625 -->
❌ leading-none (1) для body
73. Line Length — Medium
Длинные строки трудно читать.
<p class="max-w-prose">...</p> <!-- ~65ch -->
❌ Текст на всю ширину viewport
74. Font Size Scale — Medium
Консистентный тип-масштаб.
<!-- 12 14 16 18 24 32 40 48 56 64 -->
❌ Произвольные размеры
75. Font Loading — Medium
Шрифты без сдвигов layout.
font-display: swap;
/* + похожий fallback */
font-family: 'Inter', system-ui, -apple-system, sans-serif;
❌ Нет fallback шрифта
76. Contrast Readability — High
Body текст — хороший контраст.
<p class="text-gray-900 bg-white">...</p>
❌ text-gray-400 на gray-100
77. Heading Clarity — Medium
Заголовки — отличаются от body.
<h2 class="text-2xl font-bold">...</h2>
<p class="text-base font-normal">...</p>
❌ Заголовок того же размера, что body
Feedback (6 правил)
78. Loading Indicators — High
Показать статус системы во время ожидания.
{isLoading && <Skeleton className="h-4 w-3/4 animate-pulse" />}
❌ Замороженный UI
79. Empty States — Medium
Направлять пользователя, когда нет контента.
<div className="text-center py-12">
<p className="text-gray-500">No items yet. <a href="/create" className="text-blue-600">Create one!</a></p>
</div>
❌ Пустое белое пространство
80. Error Recovery — Medium
Помогать восстанавливаться после ошибок.
<div className="text-red-600">
Failed to load. <button className="underline">Try again</button>
</div>
❌ Сообщение об ошибке без пути назад
81. Progress Indicators — Medium
Показывать прогресс multi-step.
<div className="flex gap-2">
<div className="h-2 flex-1 bg-blue-600 rounded"></div>
<div className="h-2 flex-1 bg-gray-200 rounded">Step 2 of 4</div>
</div>
❌ Нет step info
82. Toast Notifications — Medium
Всплывающие сообщения для не-критичной инфы.
<div className="fixed bottom-4 right-4 bg-gray-800 text-white px-4 py-3 rounded shadow-lg"
autoDismiss={3000}>
Item saved!
</div>
❌ Toast, который не исчезает
83. Confirmation Messages — Medium
Подтверждать успешные действия.
<div className="text-green-600 flex items-center gap-2">
<CheckIcon /> Saved successfully
</div>
❌ Без подтверждения
Content (4 правила)
84. Truncation — Medium
Обрезать длинный контент.
<p className="line-clamp-2 cursor-pointer" onClick={expand}>
Long text...
</p>
❌ Overflow: hidden — обрезка без expand
85. Date Formatting — Low
Использовать локализованные форматы дат.
new Date().toLocaleDateString('ru-RU', { dateStyle: 'medium' })
// "20 июн 2026 г."
❌ 01/02/03 — неоднозначно
86. Number Formatting — Low
Форматировать большие числа.
(1234567).toLocaleString('ru-RU') // "1 234 567"
// или (1.2M)
❌ 1234567 — без разделителей
87. Placeholder Content — Low
Использовать реалистичный placeholder.
<input defaultValue="john@example.com" />
❌ Lorem ipsum везде
Onboarding / Search / Data Entry (3 правила)
88. User Freedom — Medium
Пользователь должен уметь пропустить туториал.
<button className="text-gray-500 underline">Skip Tutorial</button>
❌ Запертый overlay до конца
89. Search Autocomplete — Medium
Помогать находить результаты быстрее.
<input type="search" debounced onChange={showSuggestions} />
❌ Полное вбивание + Enter
90. No Results — Medium
Показывать «Нет результатов» с подсказками.
<div>
<p>Try searching for: shoes, hats, bags</p>
</div>
❌ «No results found.» — тупик
91. Bulk Actions — Low
Массовое редактирование.
<div className="flex items-center gap-4">
<input type="checkbox" className="row-checkbox" />
<div className="flex gap-2">
<button className="btn-sm">Delete Selected</button>
<button className="btn-sm">Archive</button>
</div>
</div>
❌ Одиночные действия на каждую строку
AI Interaction (4 правила)
92. AI Disclaimer — High
Пользователи должны знать, что общаются с ИИ.
<div className="flex items-center gap-2 text-sm text-gray-500 mb-4">
<BotIcon /> AI Assistant
</div>
❌ Фейковое человеческое имя без лейбла
93. Streaming — Medium
Потоковая подача текста вместо ожидания 100%.
<div className="typewriter">
{streamedText}
<span className="animate-pulse">▌</span>
</div>
❌ Spinner до 100% completion
94. Spatial UI — High (VisionOS)
Элементы должны реагировать на gaze.
// VisionOS
.hoverEffect(.scale, enabled: true)
❌ Статичный элемент до pinch
95. Depth Layering — Medium (VisionOS)
Z-глубина для контента.
.material(.thin)
.offsetZ(10)
❌ Плоские непрозрачные панели
Sustainability (2 правила)
96. Auto-Play Video — Medium
Видео потребляет данные и энергию.
<video playsInline muted preload="none" poster="cover.jpg">
<source src="video.mp4" type="video/mp4" />
</video>
❌ autoplay loop — трафик
97. Asset Weight — Medium
Тяжёлые 3D/изображения увеличивают carbon footprint.
const Model = lazy(() => import('./model.glb?draco')); // Draco compression
❌ Raw .obj файлы 50MB
Additional AI Interaction (1 правило)
98. Feedback Loop — Low
ИИ нуждается в обратной связи для улучшения.
<div className="flex gap-2 mt-4">
<button className="btn-sm">👍 Helpful</button>
<button className="btn-sm">👎 Not helpful</button>
<button className="btn-sm">Regenerate</button>
</div>
❌ Только текст, без возможности оценки
Accessibility (1 правило)
99. Motion Sensitivity — High
Параллакс/Scroll-jacking вызывает тошноту.
@media (prefers-reduced-motion: reduce) {
.parallax { transform: none !important; }
}
❌ ScrollTrigger.create() без проверки prefers-reduced-motion
Quick Reference by Category
| Category | Count | High Severity |
|---|---|---|
| Navigation | 6 | 1 |
| Animation | 8 | 2 |
| Layout | 7 | 1 |
| Touch | 6 | 1 |
| Interaction | 8 | 2 |
| Accessibility | 11 | 7 |
| Performance | 8 | 1 |
| Forms | 10 | 2 |
| Responsive | 8 | 3 |
| Typography | 6 | 1 |
| Feedback | 6 | 1 |
| Content | 4 | 0 |
| Onboarding/Search/Data | 4 | 0 |
| AI Interaction | 4 | 1 |
| Sustainability | 2 | 0 |
| Spatial UI | 2 | 1 |
| Total | 99 | 27 🔴 |