Привет, Хабр.

Красивый и интуитивно понятный интерфейс — это моя личная страсть. Я тратил дни, чтобы докрутить свои проекты до нужного мне уровня. В итоге я начал систематически собирать приёмы HTML и CSS, которые мгновенно улучшают восприятие пользователя.

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

Давайте посмотрим, что я вам подготовил.

Подготовим фоновые изображения к экранам с повышенной плотностью пикселя

Недавно мне стало интересно, насколько часто используется элемент picture. Дело в том, что когда элемент только появился, то у меня были большие ожидания. Ведь он должен был помочь оптимизировать загрузку контента. Супер идея!

В общем я взял самые популярные новостные сайты и проверил код. И хочу вам сказать, что в половине элемент picture используется. Меня это очень сильно обрадовало.

Только давайте не будем на этом останавливаться. Если для контентных изображений надо использовать элемент picture, то для фоновых есть функция image-set.

Для демонстрации я объявлю фоновое изображение для экранов с обычной плотностью пикселя и с двойной.

.my-awesome-screen {
  background-image: image-set(
    url("awesome-hero-screen-1x.webp") type("image/webp") 1x,
    url("awesome-hero-screen-2x.webp") type("image/webp") 2x
  );
  background-color: #919191;
}

Я также использую дескрипторы, как это делал бы для элемента picture. По этой причине браузеры для обычного экрана загрузят изображение с названием awesome-hero-screen-1x.webp, а для устройств с двойной плотностью пикселя — awesome-hero-screen-2x.webp.

Как видите, всё как с элементом picture. Так что, думаю, вы быстро разберётесь с функцией image-set— и это поможет вам оптимизировать загрузку фоновых изображений!

Поле «Дата рождения» требует цифровую виртуальную клавиатуру

Я давно собираю свои трюки. Настолько, что не всегда успеваю их обновлять. Так у меня случилось с цифровыми полями. Я сразу начну с примера.

Мне удалось найти его. Давайте посмотри на поле ввода даты рождения.

<!-- разработчики Ламода, а где элемент label?! Добавьте его, пожалуйста -->

<div class="input-material__input-group">
  <div class="input-material__placeholder input-material__placeholder">Дата рождения</div>
  <div class="input-material__input-wrapper">
    <input name="Дата рождения" type="tel" value="03.12.1990" class="input-material__input-user-agent input-material__input" autocomplete="new-password" placeholder="">
  </div>
</div>

Понимаю разработчиков. Я делал так же! Хотел, чтобы у пользователя при вводе даты сразу отображалась цифровая виртуальная клавиатура. И ему не приходилось бы её переключать с текстовой.

Только для атрибута type нет значения, который подходит для цифровых полей. Приходилось выкручиваться. Больше всего подходило значение tel. Оно используется для полей ввода номера телефона.

Пожалуйста, не делайте так. Это был костыль. С появлением атрибута inputmode можно сделать проще. Значение numeric как раз относится к вводу цифровых значений. Соответственно, и виртуальная клавиатура будет использоваться адаптированная под такой ввод.

<body>
  <form>
    <!-- другие элементы формы -->
    <label for="bd">Дата рождения</label>
    <input type="text" id="bd" inputmode="numeric">
    <!-- другие элементы формы -->
  </form>
</body>

Теперь виртуальная клавиатура содержит клавиши только для ввода цифровых данных. Никаких ненужных символов # и *. Прекрасно!

autocapitalize="off" упрощает ввод данных для поля «Телефон или Почта»

Значение email для атрибута type у элемента input моё любимое. Это один из первых моих лайфхаков. Я настолько стар, что помню, как геморно было вводить электронную почту в обычном текстовом поле.

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

Буквы сразу строчные. Значок собачки есть. Красота!

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

<!-- разработчики Авито, а где элемент текст для элемента label?! Добавьте его, пожалуйста -->

<label data-marker="login-form/login" class="css-i6rj6u">
  <div class="css-1vey4fm">
    <input type="text" placeholder="Телефон или почта" autocorrect="off" spellcheck="false" autocomplete="username" name="login" data-marker="login-form/login/input">
  </div>
</label>

Разработчики вынуждены использовать значение text для поля. В результате мы увидим стандартную виртуальную клавиатуру, которая бесила меня в прошлом.

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

Для этого нам нужно использовать атрибут autocapitalize со значением off.

<body>
  <form>
    <!-- другие элементы формы -->
    <label for="auth">Номер телефона или почта</label>
    <input id="auth" type="text" autocapitalize="off">
    <!-- другие элементы формы -->
  </form>
</body>

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

Не всегда меня слышат. Но бывает, что да. Попробуйте и вы. Если вы не достучитесь, то уже воспользуйтесь атрибутом autocapitalize.

Улучшаем область навигации для пользователей скринридера

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

Если человек воспринимает интерфейс визуально, то он сразу это увидит. Тут проблем нет. Но а что будет, если человек использует скринридер? Тут могут быть проблемы.

В таком примере обычно на странице будет разметка из нескольких элементов nav.

<body>
  <!-- другие элементы -->
  <nav>
    <!-- здесь элементы основной навигации сайта -->
  </nav>
  <!-- другие элементы -->
  <nav>
    <!-- здесь элементы по страничной навигации -->
  </nav>
  <!-- другие элементы -->
</body>

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

Упростить жизнь — супер просто. Есть атрибут aria-label. С его помощью мы можем задать дополнительные подсказки.

<body>
  <!-- другие элементы -->
  <nav aria-label="Главная">
    <!-- здесь элементы основной навигации сайта -->
  </nav>
  <!-- другие элементы -->
  <nav aria-label="По странице">
    <!-- здесь элементы по страничной навигации -->
  </nav>
  <!-- другие элементы -->
</body>

Теперь скринридеры в первом случае скажут «Главная. Навигация». А для второй области — «По странице. Навигация».

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

Прокрутка страницы без головной боли

По моему опыту прокрутка страниц очень нравится фронтендерам. Раньше им приходилось реализовывать её с помощью JavaScript, а потом появилось отдельное свойство scroll-behavior. Значение smooth как раз позволяет плавно прокручивать страницу.

Сразу же оно было добавлено в код.

html {
  scroll-behavior: smooth;
}

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

Пожалуйста, не надо так. Я же вам ничего плохого не сделал. Наоборот, давайте помогу сделать всё так, как надо. Это очень просто. Есть медиа-функция prefers-reduced-motion. Она поможет нам.

У неё одна задача — проверять настройки операционной системы. Если там установлена опция «отключить плавные переходы», медиа-функция это поймёт. Нам достаточно объявить её со значением no-preference.

@media (prefers-reduced-motion: no-preference) {

  html {
    scroll-behavior: smooth;
  }
}

В этом случае проблем у меня не будет. А пользователи, у которых плавная прокрутка не вызывает проблем, вообще не заметят какие-то изменения. У них всё будет работать по-старому.

Заключение

Давайте подведём итог. В этой статье мы рассмотрели:

  • как нужно размечать поля ввода цифровых данных с использованием атрибута inputmode со значением `numeric;

  • атрибут autocapitalize для минимизации количество действий для полей с одновременным вводом телефона и электронной почты;

  • улучшение областей навигации с помощью дополнительной подсказки, созданной атрибутом aria-label, для помощи в ориентации по странице пользователей скринридера;

  • подключение плавной прокрутки таким способом, чтобы минимизировать вероятность головокружения у пользователей;

  • загрузку фоновых изображений, адаптированных под разные технические характеристики экрана.

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

На этом всё. Спасибо за чтение!

P. S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn't magic. Присоединяйтесь. Ссылка в профиле.

© 2025 ООО «МТ ФИНАНС»

Комментарии (1)


  1. JBFW
    28.10.2025 10:50

    Разве для ввода ДАТЫ рождения нет поля ввода даты?
    <input type="date">?

    И еще один неочевидный нюанс: некоторые люди до сих пор пользуются компьютерами, да еще с Windows, и эти люди частенько копируют мышкой строку и вставляют ее в поле.
    Как в этом случае поведет себя поле ввода с преднастроенными ограничениями?
    Это тоже надо проверять