Код, интерфейсы и трафик без воды
lawebbox
UX/UI дизайн

Проектирование пользовательского интерфейса: UX против UI

Прод не падает от некрасивой кнопки. Обычно. Он падает от цепочки решений, где пользователь не понимает, что система делает, дизайнер рисует «воздушный» экран без состояний ошибки, фронтенд дописывает костыль, а бэкенд получает тикет: «форма не работает».

Проектирование пользовательского интерфейса: UX против UI

Проектирование пользовательского интерфейса начинается не с выбора синего оттенка и не с поиска «референсов». Оно начинается с маршрута пользователя, ограничений системы, типов данных, ошибок, пустых состояний, прав доступа и времени отклика. UX и UI тут не конкуренты. Это два слоя одного стека. Один отвечает за то, чтобы человек дошёл до цели без кернел-паники в голове. Второй — чтобы этот путь был читаемым, консистентным и не выглядел как админка 2009 года, поднятая на коленке после релиза.

UX и UI: разные зоны ответственности, один инцидент

Путаница между UX и UI держится на простой ошибке: интерфейс принимают за картинку. Так делают менеджеры, джуны и люди, которые считают, что «добавить UX» можно отдельной задачей в конце спринта. Нельзя. Это как добавить безопасность после утечки. Можно, но будет больно и дорого.

UX — это пользовательский опыт. Не настроение. Не «приятность». Это весь путь пользователя через продукт: зачем он пришёл, что пытается сделать, где спотыкается, какие данные вводит, какие решения принимает, как система подтверждает действие и что происходит, когда всё идёт не по плану.

UI — это пользовательский интерфейс. Визуальный и интерактивный слой: сетка, типографика, цвет, кнопки, поля, иконки, состояния, адаптивность, отступы, фокус, hover, disabled, loading. Всё то, что пользователь видит и трогает.

Разработка UX/UI дизайна ломается, когда один слой подменяет другой. Нарисовали красивую форму регистрации — UI вроде есть. Но UX умер, если:

  • пользователь не понимает, зачем нужен номер телефона;
  • ошибка появляется только после отправки всей формы;
  • пароль отклоняется без объяснения правил;
  • кнопка «Далее» неактивна, но причина неизвестна;
  • после отправки нет подтверждения, а повторный клик создаёт дубль;
  • мобильная клавиатура перекрывает поле ввода;
  • сервер отвечает 500, а интерфейс пишет «Что-то пошло не так».

Это не «мелочи». Это точки отказа. Просто вместо stack trace пользователь получает раздражение и закрывает вкладку.

СлойЗа что отвечаетТипичный артефактТипичный провал
UXЛогика пути, сценарии, структура, исследование, тестированиеuser flow, прототип, карта сценариев, результаты юзабилити-тестаПользователь не понимает, что делать дальше
UIВизуальный слой, компоненты, типографика, состояния, адаптивмакет, компонентная библиотека, дизайн-токеныИнтерфейс выглядит по-разному на соседних экранах
Продуктовый дизайнСвязка задачи бизнеса, UX, UI и ограничений разработкипродуктовая гипотеза, прототип, метрики, спецификацияКоманда делает красивую штуку, которая никому не нужна
ФронтендРеализация состояния интерфейса в кодекомпоненты, маршруты, обработка событийМакет живёт в Figma, реальность — в костылях

UX без UI превращается в серую схему с правильной логикой, которую никто не хочет использовать. UI без UX — в витрину, где касса не работает. Смотрится бодро. Деньги не принимает.

Хороший интерфейс не доказывает, что он умный. Он просто не заставляет пользователя дебажить продукт вместо команды.

Этапы проектирования интерфейса: где обычно закладывают мину

Этапы проектирования интерфейса не обязаны быть бюрократическим ритуалом на 40 страниц. Но если их выкинуть совсем, получится классика: макеты готовы, API нет, ошибки не описаны, роли пользователей забыты, а на проде внезапно выясняется, что у клиента может быть 12 адресов доставки, а не один.

Нормальный процесс выглядит скучно. Поэтому работает.

1. Сначала фиксируется задача. Не «сделать личный кабинет», а «дать пользователю возможность посмотреть статус заказа, изменить адрес до отгрузки и скачать закрывающие документы». Разница не косметическая. Первая формулировка рождает набор экранов. Вторая — сценарии и ограничения.

2. Потом разбирается пользовательский путь. Откуда человек приходит, что он уже знает, какие данные есть в системе, что нужно запросить, где возможны ошибки. UX тут работает как трассировка запроса. Смотрим, где latency, где лишний редирект, где dead end.

3. Дальше строится информационная архитектура. Разделы, вложенность, навигация, группировка данных. Если в меню 17 пунктов одного веса — это не архитектура. Это дамп базы в HTML.

4. После этого появляются прототипы. Не финальная красота, а проверка логики. Кнопки, формы, переходы, состояния. На этом этапе дешевле понять, что сценарий кривой. Потом будет дороже. Особенно когда фронт уже нарезал компоненты, а бэк выкатил новые эндпоинты.

5. Затем приходит UI. Типографика, сетка, визуальная иерархия, компоненты, адаптивность. UI не должен «украшать» плохой UX. Он должен сделать структуру видимой и управляемой.

6. В конце — тестирование и сборка обратной связи. Лучше до прода. Но некоторые любят адреналин. Их право. Потом они читают логи и отзывы в саппорте.

Для проектирования интерфейсов сайтов особенно важен первый шаг. Веб живёт в грязной среде: разные устройства, браузеры, скорости сети, блокировщики, автозаполнение, странные viewport, зум 125%, пользователи с клавиатурной навигацией, screen reader. Макет на 1440 пикселей в Figma — это не продукт. Это оптимистичный скриншот.

Логи UX: где путь пользователя превращается в 500

Бэкендеру удобно думать про UX через логи. Не потому что люди — это запросы. Хотя иногда похоже. А потому что хороший интерфейс, как хороший сервис, явно обрабатывает состояние.

Классический сценарий: пользователь оплачивает подписку. UX-дизайнер должен увидеть не только happy path:

  • карта проходит с первого раза;
  • банк требует 3-D Secure;
  • платёж отклонён;
  • пользователь закрыл вкладку на редиректе;
  • деньги списались, но callback от платёжки задержался;
  • подписка активировалась, а письмо не ушло;
  • пользователь нажал «Оплатить» дважды;
  • промокод истёк между вводом и оплатой.

UI-дизайнер должен дать этим состояниям форму. Не абстрактную. Конкретную: текст, цвет, расположение, блокировку кнопки, индикатор загрузки, повторное действие, сообщение об успехе, поведение на мобильном экране.

Если этого нет, фронтенд начнёт импровизировать. А импровизация в интерфейсе — это тот же костыль, только с border-radius.

В UX/UI проектировании состояние важнее статичной картинки. Кнопка существует не в одном виде. У неё минимум есть:

  • default — обычное состояние;
  • hover — если устройство поддерживает курсор;
  • active — момент нажатия;
  • focus — клавиатурная навигация;
  • disabled — действие недоступно;
  • loading — запрос ушёл, ответа нет;
  • success — действие завершено;
  • error — действие не выполнено.

На макете часто есть только default. Остальное «и так понятно». Нет, не понятно. Если бы было понятно, прод не лежал бы от двойной отправки формы.

Визуальный слой: типографика, контрастность и WCAG без религии

UI — не про «сделать красиво». Красиво — это побочный эффект работающей визуальной системы. Главная задача визуального слоя — читаемость, иерархия, управляемость внимания и предсказуемость интеракций.

Типографика в вебе начинается с банального: текст должен читаться. На мобильных устройствах основной текст обычно не стоит делать меньше 16px. Это не универсальный закон физики. Гарнитуры разные, контекст разный. Но если основной текст 12px, а дизайнер говорит «так легче», можно сразу заводить баг.

Иерархия заголовков тоже не украшение. H1-H6 нужны не только верстальщику и поисковику. Они помогают пользователю сканировать страницу. В интерфейсах люди редко читают подряд. Они ищут опорные точки. Если всё одинаково жирное, интерфейс превращается в лог-файл без уровней severity.

Контрастность — отдельная боль. WCAG 2.1 для уровня AA требует коэффициент контрастности не менее 4.5:1 для обычного текста. Это не эстетическая рекомендация. Это минимальная санитария. Серый текст на сером фоне выглядит «дорого» ровно до момента, пока его пытается прочитать живой человек на старом ноутбуке, под солнцем, с неидеальным зрением.

Элемент интерфейсаЧто ломается чаще всегоНормальная практика
Основной текстМелкий кегль, слабый контраст, длинная строкаОт 16px на мобильных, нормальная высота строки, контраст не ниже WCAG AA
ЗаголовкиНет иерархии, всё выглядит одинаковоЯвные уровни, понятная вложенность, сканируемая структура
КнопкиЦветом показали всё, текстом — ничегоЯсный label, состояния disabled/loading/error
ФормыОшибка только после submit, текст ошибки общийВалидация по месту, конкретное сообщение, сохранение введённых данных
СсылкиОтличаются только цветом, hover не заданВидимое отличие, focus-состояние, предсказуемое поведение

Контрастность нельзя оценивать «на глаз». Глаз врёт. Монитор врёт. Презентация в переговорке врёт особенно убедительно. Нужны проверки. Инструментальные. Как в нормальной инженерии.

Ещё одна ловушка UI — цвет как единственный носитель смысла. Красный плохо, зелёный хорошо. Удобно. Пока пользователь не различает эти цвета или смотрит на экран в плохих условиях. Поэтому ошибка должна быть не только красной рамкой, но и текстом. Успех — не только зелёной галочкой, но и понятным сообщением. Никакой магии. Просто доступность.

Если интерфейс нельзя прочитать, он не минималистичный. Он сломан. Просто сломан аккуратно.

Дизайн-система: не набор иконок, а контракт между людьми и кодом

Дизайн-система — любимое место для самообмана. Команда рисует палитру, десяток кнопок, пару иконок и говорит: «У нас есть дизайн-система». Нет. У вас есть декоративный README без ответственности.

Нормальная дизайн-система — это экосистема правил и компонентов. В ней есть типографика, сетка, цвета, токены, компоненты, паттерны поведения, правила использования, состояния, документация, версии и связь с реализацией во фронтенде. Она нужна не потому, что дизайнеры любят порядок. Она нужна потому, что продукт иначе расползается.

Через полгода без дизайн-системы в интерфейсе появляются:

  • четыре вида primary button;
  • три разных модальных окна;
  • два поведения выпадающих списков;
  • бесконечные отступы «на глаз»;
  • разные тексты для одной ошибки;
  • формы, где Enter то отправляет, то ничего не делает;
  • disabled-состояния, которые выглядят как loading;
  • компоненты, которые нельзя переиспользовать без шаманства.

Это не творческое разнообразие. Это технический долг в визуальном слое.

Дизайн-система особенно важна, когда продукт растёт. Один лендинг можно собрать руками и выжить. Большой SaaS, маркетплейс, личный кабинет, банковский интерфейс или B2B-платформа без системы быстро превращаются в UI-монолит. Каждый новый экран — миграция с риском регрессии.

Хорошая дизайн-система работает как API. У неё есть контракт. Компонент Button принимает набор вариантов, размеров и состояний. FormField знает, где label, hint, error. Modal имеет правила фокуса и закрытия. Tooltip не используется как контейнер для романа на 900 символов. Таблица умеет сортировку, пустое состояние, загрузку, ошибку и переполнение.

И да, дизайн-система должна жить рядом с кодом. Иначе Figma показывает один мир, Storybook — второй, прод — третий, а пользователь оказывается в четвёртом, где кнопка «Сохранить» прыгает при загрузке шрифта.

Где дизайн-система экономит нервы

Она не нужна ради галочки. Она нужна там, где повторяемость важнее героизма.

  • Консистентность. Пользователь не должен заново учить интерфейс на каждом экране. Один паттерн — одно поведение.
  • Скорость разработки. Команда берёт готовый компонент, а не изобретает новый input с кастомным padding и проклятиями в CSS.
  • Доступность. Контраст, focus, aria-атрибуты и клавиатурная навигация не вспоминаются в конце, когда уже поздно.
  • Масштабирование. Новые команды не ломают продукт, потому что правила описаны, а не хранятся в голове одного дизайнера.
  • Контроль изменений. Обновили токен цвета — понимаем, где и что поменяется. Не руками по 180 макетам.

Но дизайн-система не должна становиться тюрьмой. Если компонент не покрывает реальный сценарий, его надо развивать. Не делать локальный костыль в одном экране. И не тащить исключение в прод молча. Исключения без учёта — будущая авария.

Микровзаимодействия: 100 мс, спиннер и человеческая нервная система

Анимация интерфейсов часто страдает от дизайнерского энтузиазма. Карточки летают, меню подпрыгивает, кнопка дышит, skeleton мерцает. Пользователь хотел скачать счёт. Получил цирк.

Микровзаимодействия нужны не для шоу. Их задача — обратная связь. Система должна подтверждать действие пользователя и показывать переход между состояниями. Нажал кнопку — увидел реакцию. Отправил форму — понял, что запрос ушёл. Удалил объект — получил подтверждение или возможность отмены. Перешёл между экранами — не потерял контекст.

Время отклика до 100 мс воспринимается как мгновенное. Это полезная граница. Если реакция есть быстро, пользователь чувствует контроль. Если интерфейс молчит дольше, начинаются повторные клики, тревога и багрепорты. Спиннер без текста — плохой собеседник. Особенно если операция занимает не секунду, а десять.

Правильные микровзаимодействия закрывают конкретные задачи:

1. Подтверждают ввод. Поле принимает значение, формат нормальный, пользователь видит это до отправки всей формы.

2. Показывают загрузку. Не «всё зависло», а «мы выполняем действие». Желательно с понятным текстом, если операция длинная.

3. Снижают риск ошибки. Удаление, отмена, платежи, смена прав доступа — всё это требует ясных состояний и иногда подтверждения.

4. Сохраняют контекст. Переходы и анимации помогают понять, откуда появился новый слой интерфейса и куда он исчез.

5. Дают результат. Success-сообщение нужно не для красоты. Оно закрывает цикл действия.

Плохая анимация маскирует задержки. Хорошая — объясняет состояние. Разница примерно как между нормальным логом и «Error: something went wrong». Второе хочется распечатать и прибить к монитору автора.

Проектирование интерфейсов сайтов: веб не обязан совпадать с макетом

В проектировании интерфейсов сайтов есть отдельная реальность: браузер. Он не спрашивает, удобно ли дизайнеру. Он просто рендерит как может, с учётом устройства, сети, шрифтов, зума, расширений и пользовательских настроек.

Макет часто показывает идеальный мир:

  • данные короткие;
  • аватар загружен;
  • цена помещается в одну строку;
  • таблица имеет пять колонок;
  • изображение всегда нужного размера;
  • пользователь авторизован;
  • API отвечает быстро;
  • ошибок нет.

Реальный веб отвечает: держи немецкую фамилию на 38 символов, пустой список, битую картинку, 320px ширины, медленную сеть, автозаполнение браузера и пользователя, который жмёт Back после оплаты.

Поэтому UX/UI проектирование для веба должно включать грязные состояния. Не после релиза. До.

Нужно проектировать:

  • пустые состояния — что видит пользователь, когда данных ещё нет;
  • ошибочные состояния — что произошло и что делать дальше;
  • загрузку — skeleton, progress, disabled, optimistic UI, если уместно;
  • переполнение текста — длинные имена, адреса, названия компаний;
  • адаптив — не только desktop и mobile, но и промежуточные ширины;
  • навигацию с клавиатуры — focus не должен пропадать в чёрную дыру;
  • возврат назад — браузерная кнопка Back не обязана ломать сценарий;
  • повторную отправку — double click не должен создавать double trouble;
  • права доступа — пользователь без роли не должен видеть мёртвые кнопки.

Особенно весело с таблицами. Дизайнер рисует аккуратные колонки, фронтенд верстает, прод получает реальные данные, и всё едет. Таблица в интерфейсе — это не прямоугольники. Это сортировка, фильтры, пагинация, пустое состояние, ошибка загрузки, sticky header, горизонтальный скролл, экспорт, массовые действия и иногда боль в глазах.

Если таблица важна для работы пользователя, её надо проектировать как инструмент, а не как картинку. Иначе команда получит очередной костыль: «Сделаем overflow auto, потом разберёмся». Потом не наступает. Это известный баг календаря.

Почему продуктовый дизайн стирает границу между UX и UI

Нет строгой стены, где заканчивается UX и начинается продуктовый дизайн. Эти области пересекаются. И это нормально. Проблема не в пересечении, а в попытке нарезать ответственность так, будто продукт — конвейер: аналитик придумал, UX разложил, UI покрасил, фронт сверстал, бэк подпер, QA нашёл, прод умер.

В реальности нормальный продуктовый дизайнер должен понимать ограничения интерфейса, бизнеса и разработки. Не обязан писать SQL-запросы ночью. Но обязан знать, что данные не появляются из воздуха, состояния надо описывать, а «покажем пользователю всё сразу» превращается в когнитивный DDoS.

UX задаёт структуру и сценарий. UI делает её видимой. Продуктовый дизайн связывает это с целью: зачем вообще существует этот экран, какую метрику он двигает, какую проблему закрывает, какой компромисс приемлем.

Главная ошибка — спорить, что важнее: UX или UI. Это детский уровень. Без UX пользователь не дойдёт до цели. Без UI он не поймёт, как идти. Взаимозависимость простая и скучная. Как сеть и DNS. Можно спорить, что важнее, но сайт всё равно не откроется.

В зрелых командах UX и UI не живут отдельными островами. Они работают с фронтендом, бэкендом, продуктом, аналитикой и саппортом. Потому что саппорт знает реальные боли. Аналитика показывает, где люди отваливаются. Фронтенд знает, какие компоненты уже есть. Бэкенд знает, какие операции быстрые, какие асинхронные, где eventual consistency, а где лучше не обещать мгновенный результат.

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

Что отличает нормальное UX/UI проектирование от красивого макета

Нормальное проектирование пользовательского интерфейса видно не по первому экрану. Первый экран все научились полировать. Смотреть надо на края системы. На неприятные места. На то, что обычно забывают.

Сильный интерфейс отвечает на вопросы до того, как пользователь начал ругаться:

  • Что сейчас происходит?
  • Что я могу сделать дальше?
  • Почему действие недоступно?
  • Что изменится после нажатия?
  • Можно ли отменить?
  • Где мои данные?
  • Ошибка моя или системы?
  • Сколько ждать?
  • Что делать, если сценарий сорвался?

Если ответы есть — UX жив. Если они ещё и визуально понятны — UI не зря ел бюджет.

Красивая кнопка без понятного сценария — мусор с тенью. Продуманная логика без нормального визуального слоя — внутренний инструмент для трёх админов, которые «уже привыкли». Коммерческий продукт не должен требовать привыкания как к боли в спине.

И ещё: интерфейс должен быть проверяемым. Не в смысле «понравилось директору». Это не метрика. Проверять можно через юзабилити-тесты, аналитику, записи сессий, конверсию по шагам, количество ошибок, обращения в саппорт, время выполнения задачи. Если после редизайна стало красивее, но пользователи дольше оформляют заказ, это не победа. Это регрессия с новым шрифтом.

Финальный дамп без украшений

UX и UI не противники. UX отвечает за путь, смысл, структуру и проверку сценария. UI отвечает за визуальную реализацию, читаемость, состояния и консистентность. Дизайн-система удерживает продукт от распада. Типографика и контрастность делают интерфейс доступным, а не «премиально бледным». Микровзаимодействия дают обратную связь, а не запускают салют после каждого клика.

Если команда пропускает UX, она строит красивый лабиринт. Если забивает на UI, она строит рабочий, но нечитаемый пульт управления. Если игнорирует состояния ошибок, загрузки и пустых данных, она просто перекладывает дебаг на пользователя.

Перед тем как тащить макеты в разработку, прогоните продукт хотя бы через сухой инженерный минимум:

1. Описаны основные сценарии и альтернативные ветки.

2. Есть состояния загрузки, ошибки, успеха и пустых данных.

3. Контраст текста проходит WCAG AA, обычный текст не ниже здравого минимума для устройства.

4. Компоненты берутся из дизайн-системы или добавляются в неё, а не живут локальным костылём.

5. Формы показывают понятные ошибки и не теряют введённые данные.

6. Адаптив проверен не только на двух красивых ширинах.

7. Повторные клики, задержки API и асинхронные операции не ломают сценарий.

8. Фокус, клавиатура и доступность не отложены «на потом».

А теперь обещанный терминал. Без него тут было бы слишком гладко:

  • git status — перед тем как править компонент, посмотрите, что уже сломали.
  • npm run storybook — проверьте состояния компонента, а не только счастливый скрин.
  • npm run test — если тестов нет, это тоже результат. Печальный.
  • npm run build — макет в Figma не гарантирует, что сборка переживёт реальность.
  • git diff — локальные костыли видны лучше, чем кажется.
  • git commit -m "fix interface states" — коммит должен говорить, что исправлено, а не «final_final_2».
  • pg_dump или нормальный backup job — потому что интерфейс можно перерисовать, а данные пользователей лучше не терять.

Делайте бэкапы. Описывайте состояния. Не называйте палитру дизайн-системой. И не заставляйте пользователя читать ваши логи глазами.

Частые вопросы

В чем разница между UX и UI?
UX — это пользовательский опыт, охватывающий логику пути, сценарии и структуру продукта. UI — это визуальный и интерактивный слой, включающий типографику, цвета, кнопки и состояния элементов.
Почему нельзя добавить UX в конце разработки?
Добавление UX после завершения разработки делает исправление ошибок болезненным и дорогим процессом, аналогичным попытке обеспечить безопасность уже после утечки данных.
Что такое дизайн-система и зачем она нужна?
Это экосистема правил, компонентов и документации, которая обеспечивает консистентность интерфейса, ускоряет разработку и упрощает масштабирование продукта.
Почему важно проектировать состояния ошибок и загрузки?
Отсутствие описанных состояний приводит к тому, что пользователь не понимает, что происходит с системой, что вызывает раздражение и приводит к закрытию вкладки.
Что такое WCAG 2.1 и зачем соблюдать контрастность?
Это стандарт доступности, требующий коэффициент контрастности не менее 4.5:1 для обычного текста, чтобы интерфейс оставался читаемым для людей с разным зрением и в различных условиях освещения.