Как проверить, что интерфейс получился таким, как задумано

2026 · Подкаст · Веб-стандарты · выпуск 512

В команде есть компонент, который уже проверили и выпустили. Другой разработчик меняет код, и кнопка становится шире, текст смещается, отступы расходятся. Как понять, что это ошибка, а не очередная интерпретация дизайна? На что опереться, кроме «мне кажется, раньше было лучше»?

В 512-м выпуске «Веб-стандартов», который вышел в феврале 2026 года, мы обсуждали это с Вадимом Макеевым, Полиной Гуртовой и Никитой Дубко. Подкасту исполнилось 10 лет. Никита принёс статью о переосмыслении pixel perfect, и выяснилось, что под одним названием мы понимаем разные вещи.

С чем сравнивать результат

Обсуждение pixel perfect мы начали со старых макетов. Дизайнер отдавал картинку, разработчик воспроизводил её в браузере, заказчик накладывал одно на другое и искал расхождения. Полина вспомнила такие проверки в начале своей карьеры: всё происходило с ощущением экзамена. Никите однажды прислали фотографию распечатанного макета, к которому приложили линейку, чтобы показать несовпадение с экраном.

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

У pixel perfect осталась другая задача: быть одним из критериев приёмки. Заказчику нужно понять, получил ли он то, о чём договорились. В обучении нужно увидеть, воспроизвёл ли студент дизайнерское решение или решил, что «и так нормально». В команде нужно заметить, что после правки кода изменился внешний вид уже работающего компонента.

Это один этап проверки. За ним остаются интерактивность, адаптивность, увеличение текста и всё остальное, что происходит с живым интерфейсом. Совпадение с макетом не отменяет эту работу.

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

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

Эталон можно менять

Хороший пример — скриншотные тесты. Мы проверяем интерфейс, принимаем его состояние и сохраняем как эталон. Следующие изменения сравниваем с ним. Если появилась разница, выясняем, откуда она взялась.

Вадим сразу уточнил: эталоном должен быть скриншот работающего интерфейса, а не экспорт из Photoshop. Согласен. Сначала мы убеждаемся, что результат нас устраивает, и только потом фиксируем его.

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

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

Мы разошлись в том, стоит ли называть этот принцип pixel perfect. Для меня сравнение с ожидаемым результатом никуда не исчезло. Оно не определяет, что делать с найденным расхождением: исправлять код, обсуждать решение или менять эталон. Это следующий шаг.

У скриншота есть границы

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

Сравнение снимков решает лишь часть задачи. Дальше нужно проверить, что произойдёт с интерфейсом в условиях, которых нет на эталонном скриншоте: при увеличении текста, задержке загрузки, изменении содержимого.

Полина рассказала и о попытке автоматизировать более содержательную проверку. В её проекте языковую модель просили описать структуру, иерархию и организацию исходного дизайна, а затем сопоставить это описание со скриншотом приложения. Так пытались проверить, сохранился ли замысел, а не только расположение пикселей. По её оценке, подход уже давал некоторый результат, хотя полноценное дизайн-ревью оставалось более надёжным.

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

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

Когда увеличивают текст

В начале выпуска Вадим рассказывал об эксперименте Chrome Canary: браузер учился учитывать системную настройку размера текста на телефоне. Страница могла явно включить это поведение через метатег text-scale. На момент разговора это ещё была экспериментальная возможность, а не настройка, которую можно без проверки разнести по всем проектам.

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

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

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

На MDN я открыл статью и увеличил страницу в Safari. Вместе со статьёй росла боковая колонка с оглавлением — в том примере всего из двух пунктов. Пока вёрстка не перестроилась, колонка забирала всё больше ширины у текста, ради которого я и открыл страницу.

Вадим справедливо заметил, что я проверял зум, а обсуждали мы увеличение текста. Это разные механизмы. Для меня пример был про следующий вопрос: что именно мы хотим сохранить при изменении масштаба? Увеличить всё пропорционально недостаточно, если вспомогательная колонка мешает читать основную. Ответ приходится искать в устройстве самой страницы.

Когда один ресурс задерживает остальные

Полина принесла ещё одну новость Chrome: в инструментах разработчика появилась возможность замедлить отдельный сетевой запрос. Раньше можно было замедлить сеть целиком или заблокировать ресурс. Проверить ситуацию, когда один ответ приходит значительно позже других, было сложнее.

Мне сразу вспомнились внешние сервисы. Приложение работает быстро, но встроенная карта долго ждёт ответа от своего API. Что в это время происходит на странице? Такой случай удобно воспроизвести отдельно, не замедляя всё приложение.

Есть и менее заметные зависимости: аналитика, счётчики, пиксели, ресурсы, которые подтягивает менеджер тегов. У пользователя их может заблокировать расширение или сетевой фильтр. Страница продолжит ждать ответа, дождётся тайм-аута или поведёт себя иначе, чем мы рассчитывали. Это стоит увидеть до того, как с такой ситуацией столкнётся пользователь.

Тот же инструмент помогает проверить загрузку большой картинки на первом экране. Можно замедлить именно её и посмотреть, что произойдёт с LCP — метрикой появления крупнейшего видимого элемента. Тогда проще разобраться, правильно ли выбраны приоритет загрузки и момент запроса изображения. Мы проверяем конкретное решение, а не пытаемся угадать причину среди всех одновременно замедлившихся запросов.

Когда браузеру не дают закончить работу

Я принёс в выпуск предложение о событии autofill и повторном заполнении формы. В январе 2026 года оно находилось на стадии прототипирования в Chromium. За ним стояла очень знакомая проблема: браузер умеет подставлять сохранённый адрес, но форма после этого может измениться.

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

На предложение сначала посмотрели с сомнением. Вадим напомнил о плохо размеченных полях, Полина — о различиях адресов. Но здесь решали более узкую задачу: дать форме возможность перестроиться в ходе автозаполнения и попросить браузер продолжить.

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

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

Мы обсуждали ошибки в разметке и работу браузерных эвристик, но в этом случае у разработчика не хватало конкретной возможности. Её и предлагали добавить: чтобы после выбора страны человек получил заполненный адрес, а не несколько новых пустых полей.