
Привет, Хабр!
Давно я не писал статей для начинающих фронтендеров. Сейчас им приходится знать ещё больше, чем раньше, но есть и хорошая новость.
Поскольку фронтендер всё ещё отвечает за интерфейсы, ему важно знать не только лучшие практики программирования, но ещё и думать о пользователе. За это во многом отвечает вёрстка.
А в ней есть хорошие привычки, которые остаются полезными независимо от того, с помощью какого стека инструментов вы разрабатываете приложение. Они помогут вам начать думать как отличный фронтендер.
В результате пользователь получит классный опыт, вы выделитесь среди коллег, а также обгоните искусственный интеллект.
Давайте посмотрим, что я вам подготовил.
Используйте пространство на благо пользователя
Одним из основных навыков дизайнера является работа с пространством. Я обучался на курсах и сам проходил основы композиции. Нас достаточно много мучали тем, как правильно расположить элементы, каких размеров они должны быть и всем подобным критериям.
Когда вы работаете с дизайнером, то чаще всего получаете достаточно проработанный макет. Но и вы можете внести важное улучшение.
Для демонстрации приёма я буду использовать модальное окно. Посмотрим на размеры кнопки «Крестик».

Ширина и высота равняются 30 пикселям. В целом это достаточно хороший показатель, который перекрывает требования стандарта WCAG по минимальным размерам. Только мы можем сделать ещё лучше. В этой задаче CSS нам поможет.
Если мы посмотрим на весь блок, то увидим достаточно пространства вокруг кнопки. Мы можем его использовать, чтобы увеличить размеры кликабельной области кнопки, сохранив визуальные размеры.
Например, это можно сделать с помощью свойства padding. Мы объявим значение 5px, но чтобы кнопка была на том же месте, где должна быть, уменьшим значения свойств top и right.

С точки зрения дизайнера нет никакой разницы. А с точки зрения пользователя теперь проще попасть по кнопке, потому что кликабельная область стала 40 на 40 пикселей.
Подумайте о том, как пользователь будет вводить данные
Пользовательский опыт — это область, где фронтендер может существенно повлиять на удобство интерфейса. Когда вы вёрстаете формы, то обязательно должны помнить о типе данных, который пользователь должен ввести. Это поможет определить правильный тип поля, а также подобрать подходящую виртуальную клавиатуру.
Давайте начнём с достаточно типичного примера. Форма авторизации, где нужно ввести электронную почту и пароль.
<body> <form class="auth-form"> <div class="auth-form__group"> <label for="auth">Электронная почта</label> <input id="auth" type="email"> </div> <div class="auth-form__group"> <label for="password">Пароль</label> <input id="password" type="password"> </div> <div class="auth-form__group"> <button>Войти</button> </div> </form> </body>
Мы с вами используем атрибут type со значением email для поля ввода электронной почты. Это помогает браузерам отобразить виртуальную клавиатуру, где есть строчные буквы, символ @ и кнопка с доменной зоной.

Давайте представим, что кроме электронной почты в это поле пользователь может ввести ещё номер телефона, т. е. у нас ещё появляется числовой тип данных. Как лучше подобрать значение для атрибута type?
Поскольку нам нужна валидация поля, то лучше оставить значение по умолчанию text. Да, это не лучший вариант, потому что мы теряем все преимущества значения email.
Но мы можем его немного улучшить, добавив атрибут autocapitalize со значением off, чтобы пользователю отобразилась виртуальная клавиатура со строчными буквами, как было при значении email.
<body> <form class="auth-form"> <div class="auth-form__group"> <label for="auth">Электронная почта или телефон</label> <input id="auth" type="text" autocapitalize="off"> </div> <div class="auth-form__group"> <label for="password">Пароль</label> <input id="password" type="password"> </div> <div class="auth-form__group"> <button>Войти</button> </div> </form> </body>

Перейдём к другому примеру. Представим, что пользователю требуется вместо пароля вводить код авторизации.
<body> <form class="auth-form"> <div class="auth-form__group"> <label for="auth">Код из пуш-уведомления</label> <input id="auth" type="text"> </div> <div class="auth-form__group"> <button>Войти</button> </div> </form> </body>
Поскольку у нас нет подходящего значения для атрибута type, позволяющего вводить цифровой тип данных, мы оставим значение по умолчанию. По этой причине у нас получилась неудобная для ввода цифр виртуальная клавиатура.

Теперь подумаем, как отобразить пользователю более удобную виртуальную клавиатуру, содержащую цифры.
В этой задаче нам поможет атрибут inputmode. Он, как атрибут type, управляет виртуальной клавиатурой. В нашем случае нужна цифровая, поэтому мы используем значение numeric.
<body> <form class="auth-form"> <div class="auth-form__group"> <label for="auth">Код из пуш-уведомления</label> <input id="auth" type="text" inputmode="numeric"> </div> <div class="auth-form__group"> <button>Войти</button> </div> </form> </body>

Отдельно вспомню про значение tel. Вы могли его встретить в различных обучающих материалах.
Раньше его добавляли, когда пользователь должен был ввести цифры, как в нашем примере. Так делали, потому что не было атрибута inputmode.
Сейчас же он есть, и лучше использовать его, потому что с помощью него пользователь получает более ожидаемую виртуальную клавиатуру.
Уверенно находите декоративные изображения
Казалось бы, в чём заключается сложность найти декоративное изображение? На любом курсе по вёрстке, видео или другом источнике расскажут об этом. Если изображение не добавляет отдельного смысла окружающему контенту, а только украшает его, то оно декоративное.
Простые слова, но на практике до сих пор есть большие проблемы с этим. И на самом деле это очень непростая задача. Но своё объяснение я начну с другого. А зачем нам в этом разбираться?
Уверен, что вы знаете, что атрибут alt существует для установки альтернативного текста. Он будет показан, если изображение по какой-либо причине не загрузится. Но у него есть ещё более важная роль.
Существуют пользователи с частичной или тотальной слепотой. Они взаимодействуют с интерфейсом при помощи скринридера. Это программное обеспечение озвучивает информацию об элементе, на котором находится пользователь. Если скринридер окажется на изображении, то он озвучит альтернативный текст, указанный в атрибуте alt.
Именно в этот момент начинаются проблемы. Большинство фронтендеров не задумываются о том, в каком контексте используется альтернативный текст. Как он повлияет на восприятие интерфейса? В результате пользователи скринридера сталкиваются с большим количеством барьеров, мешающих им взаимодействовать с интерфейсом.
Чтобы не делать так, давайте потренируемся находить декоративные изображения. Я специально подобрал примеры, где используется только элемент img. Стандарты разрешают использовать его для декоративных изображений. Только атрибут alt должен быть оставлен пустым.
Первым примером будет ссылка «Промышленный PR, вопрос» с иконкой в виде двух глаз, находящейся слева от текста.

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

<body> <!-- другие элементы --> <a class="link" href="https://effect.habr.com/" rel="noopener" target="_blank"> <img alt="Промышленный PR, вопрос" class="icon" height="20" src="https://habrastorage.org/eyes_1f440.png" width="20"> Промышленный PR, вопрос </a> <!-- другие элементы --> </body>
Они не согласны со мной. Мы видим, как текст ссылки был скопирован в атрибут alt. В итоге пользователи скринридера услышат дважды подсказку «Промышленный PR, вопрос».
Если же разработчики сделали, как я предлагаю, то подсказка «Промышленный PR, вопрос» будет озвучена один раз.
Давайте посмотрим на следующий пример, где используется несколько аватарок пользователей подряд для ссылки «Сообщество».

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

<body> <!-- другие элементы --> <div class="_avatars_14z1h_8" data-size="medium"> <div class="_container_14z1h_14" data-visible="true"> <div class="_avatar_14z1h_8" data-is-bordered="true"> <img class="_image_14z1h_80" alt="Участник сообщества 1" loading="eager" src="https://opis-cdn.tinkoffjournal.ru/ugc_njlsbm_userpic?preset=icon_30x30_2x"> </div> <div class="_avatar_14z1h_8" data-is-bordered="true"> <img class="_image_14z1h_80" alt="Участник сообщества 2" loading="eager" src="https://opis-cdn.tinkoffjournal.ru/ugc_esqa7hjeiyrv_userpic?preset=icon_30x30_2x"> </div> <div class="_avatar_14z1h_8" data-is-bordered="true"> <img class="_image_14z1h_80" alt="Участник сообщества 3" loading="eager" src="https://opis-cdn.tinkoffjournal.ru/ugc_ttjpsw_userpic?preset=icon_30x30_2x"> </div> </div> </div> <!-- другие элементы --> </body>
Для каждого элемента img объявлен текст «Участник сообщества», а в конце него добавлена цифра, обозначающая порядковый номер.
В итоге пользователь скринридера услышит подсказки «Участник сообщества 1», «Участник сообщества 2» и «Участник сообщества 3». Никакой полезной для пользователя информации.
Перейдём к самому сложному примеру. Это блок с новостью «Есть вещи, которые я не могу изменить. Почему Слуцкий покинул Китай и где его ждать?».

Может показаться, что превью не является декоративным. Даже разработчики добавили хорошую подсказку «Леонид Слуцкий покинул Шанхай Шэньхуа».

<body> <!-- другие элементы --> <img class=" lazyloaded" alt="Леонид Слуцкий покинул «Шанхай Шэньхуа»" srcset="https://img.championat.com/s/270x180/news/big/l/j/leonid-sluckij-pokinul-shanhaj-shenhua\_17857674661125631694.jpg 270w, https://img.championat.com/s/570x380/news/big/l/j/leonid-sluckij-pokinul-shanhaj-shenhua\_17857674661125631694.jpg 570w, https://img.championat.com/s/960x640/news/big/l/j/leonid-sluckij-pokinul-shanhaj-shenhua\_17857674661125631694.jpg 960w, https://img.championat.com/news/big/l/j/leonid-sluckij-pokinul-shanhaj-shenhua\_17857674661125631694.jpg 1350w" src="https://img.championat.com/news/big/l/j/leonid-sluckij-pokinul-shanhaj-shenhua_17857674661125631694.jpg"> <!-- другие элементы --> </body>
В этом и сложность. Чтобы правильно определиться с этим изображением, нужно понимать, в какой момент оно будет озвучено для пользователей скринридера.
Они перешли к изучению списка новостей. В этой ситуации им важнее найти заголовки. Если другие элементы отвлекают от них, то это сильно усложняет взаимодействие.
Получается, что в этом месте подсказка «Леонид Слуцкий покинул Шанхай Шэньхуа» не нужна пользователям скринридера. По этой причине атрибут alt нужно оставить пустым.
Заключение
Давайте подведём итог. В этой статье мы рассмотрели следующими советы:
используйте пространство вокруг элементов, чтобы увеличить их кликабельную область;
помните о том, как пользователи будут вводить данные;
не забывайте про декоративные изображения и добавляйте им пустой атрибут
alt.
Дополнительно хочу попросить вас поделиться в комментариях советами по вёрстке, которые вы считаете важными для новичков. Мне тоже будет интересно их прочитать.
На этом я прощаюсь. Спасибо за чтение!
P. S. Помогаю больше узнать про CSS и дружелюбные интерфейсы в своих ТГ‑каналах CSS isn't magic и UX + Dev = a11y. Присоединяйтесь. Как вступить, написано в профиле.
© 2026 ООО «МТ ФИНАНС»