Skip to content

Аудит руководств по веб-дизайну интерфейсов

Чему вы научитесь

  • 🎯 Позволить AI автоматически анализировать UI-код, обнаруживая проблемы доступности, производительности и UX
  • ♿ Применять лучшие практики Web Accessibility (WCAG), повышая доступность сайта
  • ⚡ Оптимизировать производительность анимации и загрузку изображений, улучшая пользовательский опыт
  • 🎨 Обеспечить правильную реализацию темного режима и адаптивного дизайна
  • 🔍 Исправлять распространенные UI-антипаттерны (например, transition: all, отсутствие aria-label и другие)

Текущие проблемы

Вы написали UI-компоненты, но чувствуете, что что-то не так:

  • Сайт прошел функциональные тесты, но неясно, соответствует ли он стандартам доступности
  • Плохая производительность анимации, пользователи сообщают о лагах на странице
  • В темном режиме некоторые элементы трудно различимы
  • Код, сгенерированный AI, работает, но отсутствуют необходимые aria-labels или семантический HTML
  • Каждый раз при анализе кода вручную проверяете 17 категорий правил, низкая эффективность
  • Не знаете, когда использовать CSS-свойства prefers-reduced-motion, tabular-nums и другие

На самом деле, инженерная команда Vercel уже разработала набор из 100 руководств по веб-дизайну интерфейсов, охватывающих все сценарии от доступности до оптимизации производительности. Теперь эти правила упакованы в Agent Skills, и вы можете позволить AI автоматически помогать вам анализировать и исправлять UI-проблемы.

Что такое "Web Interface Guidelines"

Web Interface Guidelines — это коллекция стандартов качества UI от Vercel, содержащая 100 правил в 17 категориях. Эти правила основаны на стандартах доступности WCAG, лучших практиках производительности и принципах UX-дизайна, обеспечивая, чтобы качество веб-приложений соответствовало производственному уровню.

Когда использовать этот метод

Типичные сценарии использования навыков руководств по веб-дизайну:

  • Не применимо: чисто серверная логика, простые прототипы страниц (без пользовательского взаимодействия)
  • Применимо:
    • Написание новых UI-компонентов (кнопки, формы, карточки и другие)
    • Реализация интерактивных функций (модальные окна, выпадающие меню, перетаскивание и другие)
    • Анализ или рефакторинг UI-компонентов
    • Проверка качества UI перед запуском
    • Исправление проблем доступности или производительности, о которых сообщили пользователи

🎒 Подготовка перед началом

Предварительная проверка

Перед началом убедитесь, что вы:

  1. Установили Agent Skills (см. Руководство по установке)
  2. Знакомы с основами HTML/CSS/React
  3. Имеете UI-проект для аудита (может быть один компонент или вся страница)

Основная идея

Руководства по веб-дизайну интерфейсов охватывают 17 категорий, разделенных по приоритетам на три блока:

Блок категорийФокусТипичная отдача
Доступность (Accessibility)Обеспечить доступность для всех пользователей (включая экранное чтение, клавиатуру)Соответствие стандартам WCAG, расширение аудитории
Производительность & UX (Performance & UX)Оптимизация скорости загрузки, плавности анимации, взаимодействияПовышение удержания пользователей, снижение отказов
Полнота & Детали (Completeness)Темный режим, адаптивность, валидация форм, обработка ошибокСнижение жалоб пользователей, повышение бренда

17 категорий правил:

КатегорияТипичное правилоПриоритет
Accessibilityaria-labels, семантический HTML, обработка клавиатуры⭐⭐⭐ Высший
Focus StatesВидимый фокус, :focus-visible вместо :focus⭐⭐⭐ Высший
Formsautocomplete, валидация, обработка ошибок⭐⭐⭐ Высший
Animationprefers-reduced-motion, transform/opacity⭐⭐ Высокий
Typographycurly quotes, ellipsis, tabular-nums⭐⭐ Высокий
Content Handlingусечение текста, обработка пустых состояний⭐⭐ Высокий
Imagesdimensions, lazy loading, alt text⭐⭐ Высокий
Performancevirtualization, предподключение, пакетная обработка DOM⭐⭐ Высокий
Navigation & StateURL отражает состояние, глубокие ссылки⭐⭐ Высокий
Touch & Interactiontouch-action, tap-highlight⭐ Средний
Safe Areas & Layoutбезопасные области, обработка полос прокрутки⭐ Средний
Dark Mode & Themingcolor-scheme, theme-color meta⭐ Средний
Locale & i18nIntl.DateTimeFormat, Intl.NumberFormat⭐ Средний
Hydration Safetyvalue + onChange, предотвращение несоответствия ячеек⭐ Средний
Hover & Interactive Stateshover-состояние, повышение контрастности⭐ Средний
Content & Copyактивный залог, конкретные метки кнопок⭐ Низкий
Anti-patternsпометка распространенных ошибочных шаблонов⭐⭐⭐ Высший

Основные принципы:

  1. Сначала исправляйте проблемы категории Accessibility — эти влияют на использование пользователями с ограниченными возможностями
  2. Проблемы производительности начинайте с анимации и изображений — это напрямую влияет на пользовательский опыт
  3. Проблемы полноты проверяйте в последнюю очередь — темный режим, интернационализация и другие детали

Следуйте за мной

Шаг 1: Запуск AI-аудита UI

Откройте ваш UI-проект (может быть один файл компонента или весь каталог), введите в Claude или Cursor:

Review my UI components for accessibility and UX issues

или

Check accessibility of my site

или

Audit design and apply Web Interface Guidelines

Вы должны увидеть: AI активирует навык web-design-guidelines и загрузит последние 100 правил с GitHub.

Шаг 2: Укажите файлы для аудита (если AI не обнаружил автоматически)

Если AI спрашивает, какие файлы нужно проанализировать, вы можете:

bash
# Аудит одного файла
src/components/Button.tsx

# Аудит нескольких файлов (через пробел)
src/components/Button.tsx src/components/Input.tsx

# Аудит всего каталога (с glob-шаблоном)
src/components/**/*.tsx

Шаг 3: AI автоматически обнаруживает проблемы

AI будет проверять код построчно, выводя результаты аудита в формате file:line после обнаружения проблем. Например:

typescript
// ❌ Ваш исходный код (с проблемой)
export function Button({ icon, onClick }: ButtonProps) {
  return (
    <button
      onClick={onClick}
      className="p-2 rounded hover:bg-gray-100 transition-all"
    >
      {icon}
    </button>
  )
}

Результаты аудита AI:

## src/components/Button.tsx

src/components/Button.tsx:8 - icon button missing aria-label
src/components/Button.tsx:8 - animation missing prefers-reduced-motion
src/components/Button.tsx:8 - transition: all → list properties explicitly
src/components/Button.tsx:8 - button needs visible focus

Исправленный код от AI:

typescript
// ✅ После исправления
export function Button({ icon, onClick, ariaLabel }: ButtonProps) {
  return (
    <button
      onClick={onClick}
      aria-label={ariaLabel}
      className="p-2 rounded hover:bg-gray-100
                transition-colors duration-200
                focus:outline-none focus:ring-2 focus:ring-blue-500
                motion-safe:hover:scale-105 active:scale-100
                motion-reduce:transition-none motion-reduce:transform-none"
    >
      {icon}
    </button>
  )
}

Шаг 4: Примеры распространенных проблем

Проблема 1: Форма ввода без label и autocomplete

typescript
// ❌ Ошибка: отсутствие label и autocomplete
<input
  type="text"
  placeholder="Email"
  value={email}
  onChange={(e) => setEmail(e.target.value)}
/>
typescript
// ✅ Правильно: включает label, name, autocomplete
<label htmlFor="email" className="sr-only">
  Email address
</label>
<input
  id="email"
  type="email"
  name="email"
  autoComplete="email"
  placeholder="[email protected]…"
  value={email}
  onChange={(e) => setEmail(e.target.value)}
/>

Правила:

  • Form Controls need <label> or aria-label
  • Inputs need autocomplete and meaningful name
  • Use correct type (email, tel, url, number) and inputmode

Проблема 2: Анимация не учитывает prefers-reduced-motion

css
/* ❌ Ошибка: все пользователи видят анимацию, неудобно для пользователей с вестибулярными расстройствами */
.modal {
  transition: all 0.3s ease-in-out;
}
css
/* ✅ Правильно: уважение предпочтения пользователя по уменьшению анимации */
.modal {
  transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
  .modal {
    transition: none;
  }
}

Правила:

  • Honor prefers-reduced-motion (provide reduced variant or disable)
  • Never transition: all—list properties explicitly

Проблема 3: Изображения без dimensions и lazy loading

typescript
// ❌ Ошибка: вызывает Cumulative Layout Shift (CLS)
<img src="/hero.jpg" alt="Hero image" />
typescript
// ✅ Правильно: заранее резервируем пространство, предотвращая скачок макета
<img
  src="/hero.jpg"
  alt="Hero: team working together"
  width={1920}
  height={1080}
  loading="lazy"
  fetchpriority="high"  // для ключевых изображений выше сгиба
/>

Правила:

  • <img> needs explicit width and height (prevents CLS)
  • Below-fold images: loading="lazy"
  • Above-fold critical images: priority or fetchpriority="high"

Проблема 4: Темный режим без color-scheme

html
<!-- ❌ Ошибка: в темном режиме нативные элементы управления (например, select, input) все еще с белым фоном -->
<html>
  <body>
    <select>...</select>
  </body>
</html>
html
<!-- ✅ Правильно: нативные элементы управления автоматически адаптируются к темной теме -->
<html class="dark">
  <head>
    <meta name="theme-color" content="#0f172a" />
  </head>
  <body style="color-scheme: dark">
    <select style="background-color: #1e293b; color: #e2e8f0">
      ...
    </select>
  </body>
</html>

Правила:

  • color-scheme: dark on <html> for dark themes (fixes scrollbar, inputs)
  • <meta name="theme-color"> matches page background
  • Native <select>: explicit background-color and color (Windows dark mode)

Проблема 5: Неполная поддержка клавиатурной навигации

typescript
// ❌ Ошибка: только мышью можно кликнуть, пользователи клавиатуры не могут использовать
<div onClick={handleClick} className="cursor-pointer">
  Click me
</div>
typescript
// ✅ Правильно: поддержка клавиатурной навигации (Enter/Space активирует)
<button
  onClick={handleClick}
  className="cursor-pointer"
  // автоматически поддерживает клавиатуру, дополнительный код не нужен
>
  Click me
</button>

// или если нужно использовать div, добавьте поддержку клавиатуры:
<div
  role="button"
  tabIndex={0}
  onKeyDown={(e) => {
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault()
      handleClick()
    }
  }}
  onClick={handleClick}
  className="cursor-pointer"
>
  Click me
</div>

Правила:

  • Interactive elements need keyboard handlers (onKeyDown/onKeyUp)
  • <button> for actions, <a>/<Link> for navigation (not <div onClick>)
  • Icon-only buttons need aria-label

Проблема 6: Длинные списки без виртуализации

typescript
// ❌ Ошибка: рендеринг 1000 элементов вызывает лаги страницы
function UserList({ users }: { users: User[] }) {
  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  )
}
typescript
// ✅ Правильно: использование виртуальной прокрутки, рендер только видимых элементов
import { useVirtualizer } from '@tanstack/react-virtual'

function UserList({ users }: { users: User[] }) {
  const parentRef = useRef<HTMLUListElement>(null)

  const virtualizer = useVirtualizer({
    count: users.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 40,  // высота каждого элемента
    overscan: 5,  // предрендер нескольких элементов для предотвращения пробелов
  })

  return (
    <ul ref={parentRef} className="h-96 overflow-auto">
      <div
        style={{
          height: `${virtualizer.getTotalSize()}px`,
          position: 'relative',
        }}
      >
        {virtualizer.getVirtualItems().map((virtualItem) => (
          <div
            key={virtualItem.key}
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              transform: `translateY(${virtualItem.start}px)`,
            }}
          >
            {users[virtualItem.index].name}
          </div>
        ))}
      </div>
    </ul>
  )
}

Правила:

  • Large lists (>50 items): virtualize (virtua, content-visibility: auto)

Проблема 7: Числовые столбцы без tabular-nums

css
/* ❌ Ошибка: ширина цифр не фиксирована, вызывает скачок выравнивания */
.table-cell {
  font-family: system-ui;
}
css
/* ✅ Правильно: цифры моноширинные, выравнивание стабильное */
.table-cell.number {
  font-variant-numeric: tabular-nums;
}

Правила:

  • font-variant-numeric: tabular-nums for number columns/comparisons

Шаг 5: Исправление распространенных антипаттернов

AI автоматически пометит эти антипаттерны:

typescript
// ❌ Коллекция антипаттернов
const BadComponent = () => (
  <div>
    {/* Антипаттерн 1: transition: all */}
    <div className="transition-all hover:scale-105">...</div>

    {/* Антипаттерн 2: кнопка с иконкой без aria-label */}
    <button onClick={handleClose}></button>

    {/* Антипаттерн 3: запрет вставки */}
    <Input onPaste={(e) => e.preventDefault()} />

    {/* Антипаттерн 4: outline-none без фокуса-замены */}
    <button className="focus:outline-none">...</button>

    {/* Антипаттерн 5: изображения без dimensions */}
    <img src="/logo.png" alt="Logo" />

    {/* Антипаттерн 6: использование div вместо button */}
    <div onClick={handleClick}>Submit</div>

    {/* Антипаттерн 7: жестко заданный формат даты */}
    <Text>{formatDate(new Date(), 'MM/DD/YYYY')}</Text>

    {/* Антипаттерн 8: autofocus на мобильных устройствах */}
    <input autoFocus />

    {/* Антипаттерн 9: user-scalable=no */}
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />

    {/* Антипаттерн 10: большие списки без виртуализации */}
    {largeList.map((item) => (<Item key={item.id} {...item} />))}
  </div>
)
typescript
// ✅ После исправления
const GoodComponent = () => (
  <div>
    {/* Исправление 1: явный список переходных свойств */}
    <div className="transition-transform hover:scale-105">...</div>

    {/* Исправление 2: кнопка с иконкой включает aria-label */}
    <button onClick={handleClose} aria-label="Close dialog"></button>

    {/* Исправление 3: разрешение вставки */}
    <Input />

    {/* Исправление 4: использование focus-visible кольца */}
    <button className="focus:outline-none focus-visible:ring-2">...</button>

    {/* Исправление 5: изображения включают dimensions */}
    <img src="/logo.png" alt="Logo" width={120} height={40} />

    {/* Исправление 6: использование семантической button */}
    <button onClick={handleClick}>Submit</button>

    {/* Исправление 7: использование Intl форматирования */}
    <Text>{new Intl.DateTimeFormat('en-US').format(new Date())}</Text>

    {/* Исправление 8: autoFocus только на десктопе */}
    <input autoFocus={isDesktop} />

    {/* Исправление 9: разрешение масштабирования */}
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    {/* Исправление 10: виртуализация */}
    <VirtualList items={largeList}>{(item) => <Item {...item} />}</VirtualList>
  </div>
)

Контрольная точка ✅

После выполнения вышеуказанных шагов проверьте, освоили ли вы:

  • [ ] Знать, как запустить AI-аудит руководств по веб-дизайну
  • [ ] Понимать важность доступности (Accessibility) (высший приоритет Accessibility)
  • [ ] Знать, как добавить aria-label и семантический HTML
  • [ ] Понимать роль prefers-reduced-motion
  • [ ] Знать, как оптимизировать загрузку изображений (dimensions, lazy loading)
  • [ ] Понимать правильную реализацию темного режима (color-scheme)
  • [ ] Уметь распознавать распространенные UI-антипаттерны в коде

На что обратить внимание

Проблема 1: Только визуал, игнорирование доступности

Доступность не опциональна

Доступность — это юридическое требование (например, ADA, WCAG) и социальная ответственность.

Распространенные упущения:

  • Кнопки с иконками без aria-label
  • Пользовательские элементы управления (например, выпадающие меню) не поддерживают клавиатуру
  • Входы форм без <label>
  • Асинхронные обновления (например, Toast) без aria-live="polite"

Проблема 2: Чрезмерное использование transition: all

Убийца производительности

transition: all отслеживает изменения всех CSS-свойств, заставляя браузер пересчитывать множество значений.

Неправильное использование:

css
.card {
  transition: all 0.3s ease;  // ❌ будет переходить background, color, transform, padding, margin и т.д.
}

Правильное использование:

css
.card {
  transition: transform 0.3s ease, opacity 0.3s ease;  // ✅ только нужные свойства
}

Проблема 3: Забыть альтернативу outline

::: focus-visible не опционален После удаления стандартного outline необходимо предоставить видимый стиль фокуса, иначе пользователи клавиатуры не будут знать, где фокус.

Неправильная практика:

css
button {
  outline: none;  // ❌ полностью удаляет фокус
}

Правильная практика:

css
button {
  outline: none;  /* удаляет стандартный некрасивый контур */
}

button:focus-visible {
  ring: 2px solid blue;  /* ✅ добавляет пользовательский стиль фокуса (только при клавиатурной навигации) */
}

button:focus {
  /* не отображается при клике мышью (потому что focus-visible = false) */
}

:::

Проблема 4: Изображения без alt или dimensions

::: CLS — один из Core Web Vitals Отсутствие width и height вызывает скачок макета при загрузке страницы, влияя на пользовательский опыт и SEO.

Помните:

  • Декоративные изображения с alt="" (пустая строка)
  • Информативные изображения с описательным alt (например, "Team photo: Alice and Bob")
  • Все изображения включают width и height :::

Проблема 5: Интернационализация (i18n) с жестко заданным форматом

::: Используйте Intl API Не жестко задавайте форматы дат, чисел, валют, используйте встроенный API Intl браузера.

Неправильная практика:

typescript
const formattedDate = formatDate(date, 'MM/DD/YYYY')  // ❌ американский формат, другие страны будут в замешательстве

Правильная практика:

typescript
const formattedDate = new Intl.DateTimeFormat(undefined, {
  dateStyle: 'medium',
}).format(date)  // ✅ автоматически использует локаль пользователя

:::

Итоги урока

Ключевые принципы руководств по веб-дизайну интерфейсов:

  1. Доступность приоритет: обеспечить доступность для всех пользователей (клавиатура, экранное чтение)
  2. Оптимизация производительности: анимации через transform/opacity, lazy load изображений, виртуализация больших списков
  3. Уважение пользовательских предпочтений: prefers-reduced-motion, color-scheme, разрешение масштабирования
  4. Семантический HTML: использование <button>, <label>, <input> вместо <div>
  5. Проверка полноты: темный режим, интернационализация, валидация форм, обработка ошибок
  6. Автоматический аудит с AI: позвольте Agent Skills помогать вам обнаруживать и исправлять 100 правил

100 правил Vercel охватывают все сценарии от основ до деталей. Научившись запускать AI для применения этих правил, качество вашего UI достигнет производственного уровня.

Следующий урок

Далее мы изучим Развертывание в Vercel одним кликом.

Вы узнаете:

  • Как развернуть проект в Vercel одним кликом (поддержка 40+ фреймворков)
  • Автоматическое определение типа фреймворка (Next.js, Vue, Svelte и другие)
  • Получение ссылок на предварительный просмотр и передачу прав

Приложение: Справочник по исходному коду

Нажмите, чтобы раскрыть расположение исходного кода

Обновлено: 2026-01-25

ФункцияПуть к файлуСтроки
Определение навыка руководств по веб-дизайнуskills/web-design-guidelines/SKILL.mdВесь файл
Источник правил (100)https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.mdВесь файл
Обзор READMEREADME.md28-50

17 категорий правил:

КатегорияКоличество правилТипичное правило
Accessibility10aria-labels, семантический HTML, обработка клавиатуры
Focus States4видимый фокус, :focus-visible
Forms11autocomplete, валидация, обработка ошибок
Animation6prefers-reduced-motion, transform/opacity
Typography6curly quotes, ellipsis, tabular-nums
Content Handling4усечение текста, обработка пустых состояний
Images3dimensions, lazy loading, alt text
Performance6virtualization, предподключение, пакетная обработка
Navigation & State4URL отражает состояние, глубокие ссылки
Touch & Interaction5touch-action, tap-highlight
Safe Areas & Layout3безопасные области, обработка полос прокрутки
Dark Mode & Theming3color-scheme, theme-color
Locale & i18n3Intl.DateTimeFormat, Intl.NumberFormat
Hydration Safety3value + onChange, предотвращение несоответствия ячеек
Hover & Interactive States2hover-состояние, контрастность
Content & Copy7активный залог, конкретные метки кнопок
Anti-patterns20пометка распространенных ошибочных шаблонов

Ключевые константы:

  • RULE_SOURCE_URL = "https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md": источник загрузки правил
  • version = "1.0.0": версия навыка (SKILL.md)

Рабочий процесс:

  1. SKILL.md:23-27: загрузка последних правил с GitHub
  2. SKILL.md:31-38: чтение файлов пользователя и применение всех правил
  3. SKILL.md:39: если файлы не указаны, запрос у пользователя

Ключевые слова запуска:

  • "Review my UI"
  • "Check accessibility"
  • "Audit design"
  • "Review UX"
  • "Check my site against best practices"