- Главная»
- Уроки»
- CSS»
- Создание красивых сообщений с помощью CSS
- Метки урока:
- подсказки
- сообщения
В данном уроке Вы научитесь создавать красивые сообщения с помощью CSS. Кроме этого, Вы также узнаете как ими правильно пользоваться.
Давайте начнем с типов сообщений
1. Информационные сообщения
Цель этих сообщений информирования пользователя. Такие сообщения должны быть голубыми, так как люди ассоциируют этот цвет с информацией. Это может быть любая информация, которая может быть полезна юзеру.
2. Сообщения об успехе
Сообщения об успехе должны быть показаны после того, как юзер успешно выполнил какую-либо операцию. Успешно — означает полностью и без ошибок. Обычно такие сообщения зеленого цвета.
3. Сообщения-предупреждения
Подобные сообщения должны быть показаны пользователю если операция не может быть завершена. Обычно они желтого цвета.
4. Сообщения об ошибке
Сообщения об ошибке должны быть показаны только в том случае, если операцию невозможно выполнить. Красный идеальный цвет для этого, так как многие ассоциируют этот цвет с тревогой
5. Сообщения проверки
Еще один тип сообщений. Я предпочел для них оранжевый цвет. Подобные сообщения показывают пользователю его ошибки (например, при заполнении форм).
Теперь давайте посмотрим как такие сообщения создать
Нам понадобится следующий код CSS:
body{
font-family:Arial, Helvetica, sans-serif;
font-size:13px;
}
.info, .success, .warning, .error, .validation {
border: 1px solid;
margin: 10px 0px;
padding:15px 10px 15px 50px;
background-repeat: no-repeat;
background-position: 10px center;
}
.info {
color: #00529B;
background-color: #BDE5F8;
background-image: url('info.png');
}
.success {
color: #4F8A10;
background-color: #DFF2BF;
background-image:url('success.png');
}
.warning {
color: #9F6000;
background-color: #FEEFB3;
background-image: url('warning.png');
}
.error {
color: #D8000C;
background-color: #FFBABA;
background-image: url('error.png');
}
.validation {
color: #D63301;
background-color: #FFCCBA;
background-image: url('validation.png');
}
Данный код можно вставить как в тот же файл, так и вынести в таблицу стилей.
Теперь нам достаточно в теле документа создать слой с необходимым классом:
<div class="info">Info message</div>
<div class="success">Successful operation message</div>
<div class="warning">Warning message</div>
<div class="error">Error message</div>
<div class="validation">Validation message</div>
Заключение
Сообщения очень важный элемент любого интерфейса. Очень часто их вообще не используют. Не повторяйте эту ошибку и пользуйтесь подобными сообщениями! И желаю Вашим пользователям как можно меньше сообщений об ошибках!!!
5 последних уроков рубрики «CSS»
-
Забавные эффекты для букв
Небольшой эффект с интерактивной анимацией букв.
-
Реализация забавных подсказок
Небольшой концепт забавных подсказок, которые реализованы на SVG и anime.js. Помимо особого стиля в примере реализована анимация и трансформация графических объектов.
-
Анимированные буквы
Эксперимент: анимированные SVG буквы на базе библиотеки anime.js.
-
Солнцезащитные очки от первого лица
Прикольный эксперимент веб страницы отображение которой осуществляется “от первого лица” через солнцезащитные очки.
-
Раскрывающаяся навигация
Экспериментальный скрипт раскрывающейся навигации.
Перевод краткого руководства от UX-писателя BBC Эми Лик.
Ошибки на сайте возникают и по вине системы, а иногда и по вине пользователя. Чтобы их было легко исправить, важно писать чёткие, логичные и доступные сообщения.
Определите, с какой ошибкой столкнулся пользователь
Прежде чем составлять сообщение, убедитесь, что знаете ответы на эти вопросы:
- Что произошло?
- Как это случилось?
- Как это исправить?
- Ошибся пользователь, система или все вместе?
- Можно ли изменить текст этого сообщения? Операционная система может контролировать некоторые сообщения об ошибках.
Структура текста
Чтобы исправить ошибку, сначала нужно узнать, в чём она состоит. Сообщение будет выглядеть примерно так: ошибка → как её исправить.
Довольно простая структура. Вот пример реального сообщения об ошибке в одну строчку.
Бывает, система не может указать, что именно произошло.
В примере ниже мы специально описываем ошибку в общих чертах. Лучшее, что можно сделать при проблемах с интернетом, — подсказать пользователю, как он может всё исправить.
Пишите коротко и ясно
Нужно помочь пользователям быстро исправить ошибку, чтобы они могли дальше заниматься своими делами.
Сообщение должно быть кратким и лаконичным. Избавьтесь от лишних слов, оставьте только нужные. Главное — не перестарайтесь: краткость не должна ставить под угрозу ясность сообщения. Не вырезайте из текста важные детали.
Системная ошибка
Если ошибка произошла по вине системы, извинитесь перед пользователем. Но если в этом виноват пользователь — будьте аккуратны. Извинения звучат неискренне там, где им не место. К тому же неуместные извинения могут сбить с толку — пользователь подумает, что не виноват в ошибке, раз система говорит «простите».
Чтобы принять ответственность за случившееся, используйте активный залог. Пишите: «Мы не можем сохранить ваши изменения», а не «Ваши изменения не могут быть сохранены».
Ошибка пользователя
Иногда ошибки появляются по вине пользователя. Но сообщить об этом можно мягко и без осуждения.
В примере ниже сделали акцент на том, как исправить ситуацию, а не на забывчивости пользователя.
Пассивный залог удобно использовать, когда ошибка произошла по вине пользователя. Он поможет смягчить неприятную ситуацию, например, когда «Ваша карта была отклонена».
Используйте правильный тон
Тон сообщения будет зависеть от серьёзности ошибки. Мягкость в словах отлично подходит для мелких ошибок, но для более критических стоит подбирать слог построже.
Избегайте спецтерминов и всегда изъясняйтесь просто. Пользователь должен чувствовать, что вы стараетесь помочь ему и понятно объяснить, что делать. Помните, мы говорим с людьми, а не с машинами.
Пожалуйста, не пытайтесь умничать. Не время для шуток и креатива, когда у пользователя проблема. Шутки или креатив только испортят текст сообщения и усилят чувство разочарования.
Что случится, если нажать на кнопку
Для устранения некоторых ошибок могут потребоваться СТА-кнопка или ссылка. Иногда бывает нужна кнопка отмены.
Всегда объясняйте, что будет, если нажать на кнопку или ссылку. Их текст должен быть понятным, даже если прочитать его отдельно, вне сообщения об ошибке. Это поможет незрячим пользователям перемещаться по интерактивным элементам. Тем, кто бегло прочитал сообщение, тоже будет легче сориентироваться.
Не используйте просто слово «Ок». Что оно значит? С помощью «Ок» можно подтвердить отмену действия или его совершение. Сделайте так, чтобы пользователю было понятно, с чем он соглашается.
Время и место
Сообщения об ошибках должны принимать во внимание все действия пользователя. Время и место появления сообщения помогают понять, что произошло. Это помогает пользователю исправить ошибку.
- Что вызывало это сообщение?
- Когда оно появилось?
- Где появилось?
- Понятно ли, с чем оно связано?
Задавая эти вопросы, не забывайте, что есть пользователи с ограниченными возможностями. Это подталкивает к новым вопросам:
- Как мы можем помочь всем пользователям перейти к решению?
- Может ли ошибка слишком встревожить пользователя или быть навязчивой, появившись в этот конкретный момент?
- Как связать сообщение с соответствующим разделом визуально и не визуально?
Помните, что сообщения об ошибках — не барьеры. Они существуют, чтобы расширять возможности, успокаивать и направлять пользователей.
Ключевые рекомендации
- Определите, с какой ошибкой столкнулся пользователь и как её исправить.
- Пишите коротко и ясно.
- Используйте нужный тон и только уместные извинения.
- Дайте понять, что будет, если нажать на кнопку или ссылку.
- Учитывайте время и место появления сообщения. Не забывайте про то, как воспримут его пользователи с ограниченными возможностями.
Любая система допускает ошибки. Это может быть как человеческий фактор, так и ошибка самой системы. В обоих случаях, нужно правильно эти ошибки отображать, так как они являются очень важным элементом пользовательского опыта.
Вот 3 жизненно важных части любого хорошего сообщения об ошибке:
- Четкое текстовое сообщение
- Правильное размещение
- Хороший визуальный дизайн
Четкое текстовое сообщение
1. Сообщение об ошибке должно быть понятным
Сообщение об ошибке должно четко говорить о том, какая именно ошибка произошла, почему она произошла, и что с этим делать. Думайте об этом сообщении, как об общении с пользователем — оно должно звучать так, будто оно написано для человека, а не для машины. Убедитесь, что ваше сообщение вежливо, понятно, дружественно, и не содержит жаргона.
2. Сообщение об ошибке должно быть полезным
Не достаточно просто написать, что что-то пошло не так. Покажите пользователю, как он может исправить проблему.
Например, Microsoft описывает проблему, и прямо в сообщении об ошибке предоставляет вариант ее решения.
3. Сообщение об ошибке должно подходить под определенную ситуацию
Очень часто, веб-сайты используют одно сообщение об ошибке для всех схожих состояний. Оставили пустым поле ввода электронного адреса — «Введите правильный электронный адрес», пропустили символ «@» — «Введите правильный электронный адрес». MailChimp решает эту проблему иначе — они используют 3 разных сообщения об ошибке для каждого состояния процесса подтверждения электронной почты. Сначала проверяется, заполнено ли поле ввода. Затем проверяется введены ли символы «@», и «.».
4. Сообщение об ошибке должно быть вежливым
Не вините пользователей в том, что они что-то не так сделали, даже если это так. Будьте вежливы, дайте им почувствовать себя комфортно.
5. Используйте юмор, если он уместен
Но будьте осторожны. Сообщение об ошибке, в первую очередь, должно быть информативным и полезным. И уже затем, можете улучшить пользовательский опыт, добавив немного юмора, но только если он уместен.
Правильное размещение
Хорошее сообщение об ошибке — это такое сообщение, которое вы увидите. Размещайте его рядом с элементами интерфейса, с которыми ошибка непосредственно связана.
Правильный визуальный дизайн
Сообщение об ошибке должно быть заметным. Используйте контрастный текст и фоновые цвета, чтобы пользователь мог легко его рассмотреть и прочесть.
Обычно, используется красный цвет. В некоторых случаях желтый или оранжевый (некоторые ресурсы утверждают, что красный цвет нервирует пользователей). Как бы то ни было, убедитесь, что ваш текст разборчив, и хорошо контрастирует с фоном. Не забудьте внедрить в сообщение связанную с ним иконку — это улучшит доступность сообщения для людей с нарушенным восприятием цветов.
Заключение
Сообщения об ошибках — это отличный способ улучшить пользовательский опыт. Чтобы ваше сообщение стало действительно идеальным, уделите внимание всем аспектам — языку, размещению, и визуальному дизайну.
Предыдущая статья
F-паттерн: как пользователи просматривают контент
Следующая статья
Метрики, за которыми должен следить любой SEO аналитик
Источник изображения
Бесперебойное время работы веб-сайта (website up-time) – важнейший показатель надежности функционирования ресурса в сети, параметр, который непременно должны отслеживать веб-маркетологи, интернет-предприниматели и IT-специалисты.
Однако независимо от величины средств, которые вы вложили в обеспечение надежной непрерывной работы вашего сайта/целевой страницы/коммерческого веб-портала, надеясь на то, что «уж теперь-то больше ничего и никогда не выйдет из строя», ваш ресурс все равно может «упасть». Да, это печально, но разного рада неприятности имеют обыкновение происходить в жизни чаще, чем нам бы хотелось.
Примем этот факт как непреодолимое обстоятельство, и подумаем о реакции посетителей, которые при посещении веб-ресурса увидят в окне своего браузера печально знаменитое «сообщение об ошибке 404» (сервер не может найти данные согласно запросу пользователя, «страница не найдена»).
Диапазон чувств посетителей может простираться от понимающего «ну ничего, зайду попозже» до разгневанного «я просто обезумел от горя, ноги моей больше не будет на этом сайте!».
В последнем случае вы явно бессильны что-либо изменить, но вот менее раздражительным посетителям вы можете заметно смягчить чувство разочарования от временной недоступности вашего ресурса или отсутствия на сервере запрашиваемой страницы, показав им забавные, оригинальные, остроумные сообщения об «ошибке 404». Посетители непременно высоко оценят ваш творческий подход к оформлению печальных известий о недоступности запрошенных данных.
1. Digg
Digg – социальный новостной сайт, который собирает новости со всего интернета и компилирует их на одном сайте для удобства своих читателей. У сайта Digg множество поклонников, на самом деле ждущих публикации подборки свежих новостей, так что когда новостной ресурс «падает», его создателям приходится искренне извиняться за причиненные неудобства, вывешивая вот это забавное сообщение:
«У нашей повозки сломалась колесная ось, но мы можем продать скот для оплаты ремонта и скорейшего возвращения к вам».
2. Tumblr
У вас проблемы с сервисом Tumblr? В этом виноваты Тумбестии (Tumbeasts)! Замечательные анимационные персонажи, созданные командой рисовальщиков комиксов The Oatmeal, от имени администрации Tumblr сообщают посетителям, что сервис временно недоступен, поскольку «Гадкие Тумбестии погрызли все серверы».
3. Google Wave
В 2009 году Google создал сервис Google Wave, объединяющий электронную почту, систему обмена мгновенными сообщениями, веб-чаты, социальные сети и инструменты для совместного управления проектами. Google Wave прекратил свое существование в 2010 году, а для тех, кто все еще не в курсе произошедших событий, была заготовлена такая вот «страница 404», сообщающая о прекращении проекта:
«Серфинга не будет, чувак. Волна улеглась навсегда. Время расслабиться».
4. Blippy
Некогда в Глобальной сети существовал сайт Blippy, позволявший потребителям обмениваться отзывами о товарах и услугах. Прежде чем он был окончательно «снесен» в мае 2011 года, он сообщал пользователям о своей недоступности вот такой картинкой.
5. Grooveshark
Grooveshark в своем сообщении об ошибке продвигается на шаг дальше, чем другие веб-сервисы: посетители могут ознакомиться с увлекательной историей о том, как гигантская панда и маринованные огурчики будто бы стали причиной недоступности сайта. Пользователи улыбаются забавному рассказу и меняют гнев на милость.
6. Reddit
Reddit – еще один социальный новостной сайт, собирающий интересную информацию по всему Интернету, и позволяющий посетителям оценивать ее путем голосования. Привыкшие работать с развлекательным контентом, владельцы Reddit сделали великолепную «страницу 404», позволяющую посетителям их сайта не скучать даже в то время, когда основное содержимое этого ресурса недоступно для просмотра.
7. Mint.com
Mint.com – сайт, собирающий все финансовые документы пользователей «в одном месте», тем самым помогая контролировать, например, семейный бюджет. Финансы – это очень серьезно. Поэтому клиенты, не могущие получить доступ к важной финансовой информации, приходят в негодование практически мгновенно. Для того, чтобы поднять настроение недовольных посетителей, Mint сделал одну из самых веселых «страниц ошибки» в Глобальной сети. Персонажа, «проживающего» на ней, зовут Джастин, и он уже обзавелся целой армией преданных поклонников.
8.Taptaptap
Taptaptap – это компания, которая создает приложения для iPhone, и знает, что всем нравятся забавные детские фотографии, вроде той, что показывается посетителям их сайта при возникновении «ошибки 404».
9. Twitter
Уведомление об ошибке от сервиса микроблогов Twitter, возможно, самое известное из подобных сообщений. Когда Twitter перегружен запросами, появляется вот этот симпатичный кит. Увы, но он так часто предстает перед глазами посетителей, что скоро станет популярней знаменитой птички Twitter!
10. HubSpot
Да, подобные неприятности случаются и с признанными специалистами в области интернет-технологий! Когда сервис HubSpot «ложится в даун», на странице сообщения об «ошибке 404» посетители могут видеть неподдельное раскаяние, написанное на лице главного IT-специалиста HubSpot Тома Каттанео (Tom Cattaneo). Все видят, как ему стыдно?
Помните, что творческий подход полезен во всем, даже в создании страницы «ошибки 404»!
- Основные элементы продающей целевой страницы
- Анатомия идеальной целевой страницы
- 19 причин, по которым вы должны использовать визуальные материалы в ваших маркетинговых стратегиях
09-11-2012
За последние 24 часа нас посетили 8828 программистов и 850 роботов. Сейчас ищут 402 программиста …
Страница 3 из 4
-
вовсе нет. смотри третий скрин и пояснение к нему.
-
Хочу поделиться своими результатами обработки ошибок в графическом интерфейсе. Раньше у меня была проблема, что ошибка в любой модели обрывала все и отображалась в виде красного X-Debuga. Круто да?
Следующим этапом был перехват ошибок в set_error_handler() если я не ошибаюсь и отображение в балее меннее красивом окне сообщения об ошибке. Но у этого метода есть недостатоки. Во- первых он не видет форму, чтобы смотреть то что он ввел и одновременно читать в чем не прав, а во- вторых, когда он нажмет кнопку «Назад» все данные, которые он ввел теряются. Маты были жуткие.
На третьем этапе борьбы появились конструкции try catch вокруг всех пользовательских действий. Вывод стал красивым вверху страницы и данные сохранялись. Это уже была победа. Но неудобно, что на кождом действии приходится писать этот try — catch и обрабатывать эти исключения одним и тем же кодом. Поэтому появилась идея вывести этот код за пределы экшена.
И только сейчас можно сказать, что я победил эту проблему раз и навсегда. Данные теперь сохраняются, страница отображается с сообщением для пользователя, я для этого ничего не делаю. Мечта программиста. Доволен как слон.
у меня у контроллера (класс Cont) контрол есть такой метод, который связывает пользовательское действие с обработчиком. выгладит это так:
-
* связывает событие с обработчиком. срабатывает на EVENT | EVENT_x | EVENT[ ]
-
* @param string $event ключ массива $_REQUEST input_key => key
-
* @param string $handler название функции- обработчика
-
* @param bool $continue продолжать после обработчика дальнейшую обработку? может быть насильственно проделжен возвратом return ‘continue’
-
public function bindAction($event, $handler, $continue= false){
-
if (isset($_REQUEST[$this->input().‘_’.$event]) || isset($_REQUEST[$this->input().‘_’.$event.‘_x’])){
-
$result= $this->$handler();
-
if (!$continue && $result!=‘continue’)
-
foreach ($_REQUEST as $PARAM=>$value)
-
if (eregi(«^{$event}[[.*]]$», $PARAM)){
-
$result= $this->$handler();
-
if (!$continue && $result!=‘continue’)
А для того чтобы автоматизировать передачу исключений пользователю, я переопределил этот метод у контралера страницы вот так
-
* необработанная ошибка приводит к отображению формы на момент ошибки с соответствующим сообщением
-
* @param string $event событие
-
* @param string $handler обработчик
-
* @param bool $continue продолжить после обработки события может быть насильственно проделжен возвратом return ‘continue’
-
function bindAction($event, $handler, $continue= false){
-
parent::bindAction($event, $handler, $continue);
-
//после PDOException на повтор отправлять нельзя, т.к. транзакция все равно оборвалясь
-
//ошибка во время акшэна -> на повтор
-
unset ($_REQUEST[$this->input().‘_’.$event]);
-
unset ($_REQUEST[$this->input().‘_’.$event.‘_x’]);
-
unset ($_REQUEST[$this->input().‘_’.$event.‘_y’]);
-
$page->show($this->input());
-
// //варнинги во время сохранения — показать, но не обрывать
-
// $page->error= new WarningException(ob_get_clean());
При этом, что очень важно, все данные, которые ввел пользователь, включая выбранные фaйлы, сами собой сначала пихаются в модель, а потом повторно отображаются на странице. Ну и естественно, поскольку контроллеры всех страниц пронаследованы от PageCont, на всем сайте сам собой получился однообразный вывод ошибок. очень стильно, очень предсказуемо для пользователя. И конечно радует, что я пишу только код, а если возникает ошибки, то они сами обрабатываются и отображаются пользователю.
Вот несколько примеров, когда действия пользователя дергают модели и натыкаются там на эксепшины. И вот как это отображаются (в принципе вьюшку эксепшена можно нафантазировать как угодно):
Понимаете в чем фокус такого трюка? сколько эксепшенов наберется во всех моделях? наверное сотни. Они могут добавляться и удаляться. Но я ни разу не беспокоюсь чтобы их обрабатывать и отображать пользователю. Сюда же входят эксепшены чужих библиотек на сотом уровне вложенности, про которые я ничего не знаю и знать не хочу. меня вообще больше эта проблема не волнует. Если, к примеру даже добавлю новый эксепшен внутри какого- то метода модели, и пользователь на него нарвется, то он и увидет этот эксепшен в верхней части формы, и его данные сохранятся на форме, все это произойдет автоматически, для этого ни строчки не надо писать в форме.
-
-
Koc
Активный пользовательесть файл
ob_start();
какой-то код
var_dump(smth);
бросаем исключение
еще какой-то кодесть обработчик исключения, установленный через set_exception_handler, который выводит бектрейс, код ошибки и тд. В нем 1 строкой прописано ob_end_flush(); (что б увидеть что var_dump нам скажет). Но выводится только бектрейс. Что я делаю не так?
если в конструктор класса с исключениями запихнуть ob_end_flush(); то вывод работает. Это так задумано шоле? Фича такая?
-
Костян
Активный пользователь- С нами с:
- 12 ноя 2009
- Сообщения:
- 1.724
- Симпатии:
- 1
- Адрес:
- адуктО
Koc
да, точно не скажу, но вроде исключения убивают буфер… -
Костян
Активный пользователь- С нами с:
- 12 ноя 2009
- Сообщения:
- 1.724
- Симпатии:
- 1
- Адрес:
- адуктО
хотя не должны, а ты уверен что буферизация стартовала?
-
Koc
Активный пользовательокей, если буферизация не стартовала, то куда делся мой вар_дамп? Кто его съел?
-
А ты уверен что до него дошло дело?
-
Koc
Активный пользовательгарантирую это. Кроме того половина страницы должна отрендериться была. Если я отказываюсь от этого обработчика исключений (удаляю или комментирую строку с его назначением) то var_dump показывает то, что нужно, и пол-страницы видно.
Кроме того:
function debug_exception_handler($ex) {
echo «<b>Error :</b>», $ex->getMessage().»<br />n»;
}
сообщение пустое. Убираю этот ссаный обработчик — сообщение выводится.Пошел я спать. Не заладилось как-то программирование сегодня.
-
Ммм, а как ты его повесил?
Если через error_handler, то там не 1 параметр надо передавать. -
Koc
Активный пользовательset_exception_handler(‘debug_exception_handler’);
-
Все отлично работает.
Можешь раскомментировать echo $r и убедиться.-
function exception_handler($exception) {
-
echo «Uncaught exception: « , $exception->getMessage(), «n«;
-
set_exception_handler(‘exception_handler’);
-
echo ‘гарантирую это. Кроме того половина страницы должна отрендериться была. Если я отказываюсь от этого обработчика исключений (удаляю или комментирую строку с его назначением) то var_dump показывает то, что нужно, и пол-страницы видно.
-
function debug_exception_handler($ex) {
-
echo «<b>Error :</b>», $ex->getMessage().»<br />n»;
-
сообщение пустое. Убираю этот ссаный обработчик — сообщение выводится.
-
Пошел я спать. Не заладилось как-то программирование сегодня.’;
-
$a = array(‘nothing’, ‘to’, ‘output’);
-
throw new Exception(‘Uncaught Exception’);
-
-
Koc
Активный пользовательгага!! Вот разгадка почему так происходило
-
public function render(array $context)
-
$this->display($context);
это шаблонизатор буйствовал.
-
-
Koc
Активный пользовательчерез register_shutdown_function отлавливаю fatal error’ы. Хочу сделать backtrace — но он пуст. Вернее не то что бы полностью пуст, но в нем только мои обработчики ошибок находятся.
Как быть?
-
Koc
Активный пользовательПо всей видимости это действительно невозможно. Что ж, придется довольствоваться get_included_files
-
Koc
код выложи.
Обработчик + вызов Fatal error -
Koc
Активный пользователь-
public static function c()
-
D::c(); // тут кой-че будет
хотя я наверно некорректно понимаю что такое backtrace. Это ж не просто какие-то последние действия, а именно действия по вызову этой функции? Тогда логично, что ничего оно мне не покажет.
-
-
-
public static function c() {
-
D::c(); // тут кой-че будет
-
-
-
‘message’ => string ‘Using $this when not in object context’ (length=38)
-
‘file’ => string ‘/home/simpliest/work/test/host1/eh.php’ (length=35)
-
‘function’ => string ‘{main}’ (length=6)
-
‘file’ => string ‘/home/simpliest/work/test/host1/eh.php’ (length=35)
-
‘function’ => string ‘b’ (length=1)
-
‘file’ => string ‘/home/simpliest/work/test/host1/eh.php’ (length=35)
-
‘function’ => string ‘a’ (length=1)
-
‘file’ => string ‘/home/simpliest/work/test/host1/eh.php’ (length=35)
-
‘function’ => string ‘p’ (length=1)
-
‘class’ => string ‘D’ (length=1)
-
‘file’ => string ‘/home/simpliest/work/test/host1/eh.php’ (length=35)
-
‘function’ => string ‘eh’ (length=2)
-
‘file’ => string ‘/home/simpliest/work/test/host1/eh.php’ (length=35)
-
-
Koc
Активный пользовательну, круто конечно, но мне б более универсальное решение, без xDebug’а. Про error_get_last я знаю.
В общем это баг backtrace или все нормально?
-
Понятия не имею.
Поищи в баглисте.Хотя вряд ли баг. Можешь посмотреть еще APD, как альтернативу xdebug, возможно там тоже есть более глубокий трейс.
-
Костян
Активный пользователь- С нами с:
- 12 ноя 2009
- Сообщения:
- 1.724
- Симпатии:
- 1
- Адрес:
- адуктО
-
Костян
Нахрена?-
for ($i = 1; $i < 5; $i++) {
-
echo ‘started ‘ . $i . ‘<br>’;
-
-
Костян
Активный пользователь- С нами с:
- 12 ноя 2009
- Сообщения:
- 1.724
- Симпатии:
- 1
- Адрес:
- адуктО
-
for ($i = 1; $i < 5; $i++) {
-
echo ‘started ‘ . $i . ‘<br>’;
-
throw new Exception(‘OOOOOpss’);
-
И?
что изменилось?
Страница 3 из 4
Перевод краткого руководства от UX-писателя BBC Эми Лик.
Ошибки на сайте возникают и по вине системы, а иногда и по вине пользователя. Чтобы их было легко исправить, важно писать чёткие, логичные и доступные сообщения.
Определите, с какой ошибкой столкнулся пользователь
Прежде чем составлять сообщение, убедитесь, что знаете ответы на эти вопросы:
- Что произошло?
- Как это случилось?
- Как это исправить?
- Ошибся пользователь, система или все вместе?
- Можно ли изменить текст этого сообщения? Операционная система может контролировать некоторые сообщения об ошибках.
Структура текста
Чтобы исправить ошибку, сначала нужно узнать, в чём она состоит. Сообщение будет выглядеть примерно так: ошибка → как её исправить.
Довольно простая структура. Вот пример реального сообщения об ошибке в одну строчку.
Бывает, система не может указать, что именно произошло.
В примере ниже мы специально описываем ошибку в общих чертах. Лучшее, что можно сделать при проблемах с интернетом, — подсказать пользователю, как он может всё исправить.
Пишите коротко и ясно
Нужно помочь пользователям быстро исправить ошибку, чтобы они могли дальше заниматься своими делами.
Сообщение должно быть кратким и лаконичным. Избавьтесь от лишних слов, оставьте только нужные. Главное — не перестарайтесь: краткость не должна ставить под угрозу ясность сообщения. Не вырезайте из текста важные детали.
Системная ошибка
Если ошибка произошла по вине системы, извинитесь перед пользователем. Но если в этом виноват пользователь — будьте аккуратны. Извинения звучат неискренне там, где им не место. К тому же неуместные извинения могут сбить с толку — пользователь подумает, что не виноват в ошибке, раз система говорит «простите».
Чтобы принять ответственность за случившееся, используйте активный залог. Пишите: «Мы не можем сохранить ваши изменения», а не «Ваши изменения не могут быть сохранены».
Ошибка пользователя
Иногда ошибки появляются по вине пользователя. Но сообщить об этом можно мягко и без осуждения.
В примере ниже сделали акцент на том, как исправить ситуацию, а не на забывчивости пользователя.
Пассивный залог удобно использовать, когда ошибка произошла по вине пользователя. Он поможет смягчить неприятную ситуацию, например, когда «Ваша карта была отклонена».
Используйте правильный тон
Тон сообщения будет зависеть от серьёзности ошибки. Мягкость в словах отлично подходит для мелких ошибок, но для более критических стоит подбирать слог построже.
Избегайте спецтерминов и всегда изъясняйтесь просто. Пользователь должен чувствовать, что вы стараетесь помочь ему и понятно объяснить, что делать. Помните, мы говорим с людьми, а не с машинами.
Пожалуйста, не пытайтесь умничать. Не время для шуток и креатива, когда у пользователя проблема. Шутки или креатив только испортят текст сообщения и усилят чувство разочарования.
Что случится, если нажать на кнопку
Для устранения некоторых ошибок могут потребоваться СТА-кнопка или ссылка. Иногда бывает нужна кнопка отмены.
Всегда объясняйте, что будет, если нажать на кнопку или ссылку. Их текст должен быть понятным, даже если прочитать его отдельно, вне сообщения об ошибке. Это поможет незрячим пользователям перемещаться по интерактивным элементам. Тем, кто бегло прочитал сообщение, тоже будет легче сориентироваться.
Не используйте просто слово «Ок». Что оно значит? С помощью «Ок» можно подтвердить отмену действия или его совершение. Сделайте так, чтобы пользователю было понятно, с чем он соглашается.
Время и место
Сообщения об ошибках должны принимать во внимание все действия пользователя. Время и место появления сообщения помогают понять, что произошло. Это помогает пользователю исправить ошибку.
- Что вызывало это сообщение?
- Когда оно появилось?
- Где появилось?
- Понятно ли, с чем оно связано?
Задавая эти вопросы, не забывайте, что есть пользователи с ограниченными возможностями. Это подталкивает к новым вопросам:
- Как мы можем помочь всем пользователям перейти к решению?
- Может ли ошибка слишком встревожить пользователя или быть навязчивой, появившись в этот конкретный момент?
- Как связать сообщение с соответствующим разделом визуально и не визуально?
Помните, что сообщения об ошибках — не барьеры. Они существуют, чтобы расширять возможности, успокаивать и направлять пользователей.
Ключевые рекомендации
- Определите, с какой ошибкой столкнулся пользователь и как её исправить.
- Пишите коротко и ясно.
- Используйте нужный тон и только уместные извинения.
- Дайте понять, что будет, если нажать на кнопку или ссылку.
- Учитывайте время и место появления сообщения. Не забывайте про то, как воспримут его пользователи с ограниченными возможностями.
Здесь вы не увидите ни строчки кода. Мы поговорим об обычных людях — о наших пользователях, точнее о том, как сообщать им, если в системе возникла какая-то непредвиденная ситуация.
В основе статьи доклад Антонины Хисаметдиновой с Heisenbug 2017 Moscow, которая занимается проектировкой пользовательских интерфейсов в компании Собака Павлова.
Кроме того, на Медиуме есть цикл статей «Руководство по проектированию ошибок». Цикл еще не дописан до конца, но дает более полную и цельную картину по теме статьи.
Ошибочный сценарий
Раз за разом мы проектируем основные сценарии самых разнообразных сервисов. В случае интернет-магазина основной будет таким:
Человек заходит на сайт, выбирает товар, заказывает его доставку; оплачивает и получает заказ.
Мы так концентрируемся на основных сценариях, что забываем одну очень важную вещь: есть альтернативные сценарии и тысячи способов того, как основной сценарий может прерваться.
Всё это — ошибочные сценарии, возникающие, когда что-то идет не так.
Продуктовые команды часто не уделяют достаточно внимания таким сценариям. Например, очень типичная история: «Что-то пошло не так. У нас проблемы, поэтому просто закройте это сообщение».
Еще пример: «У нас ошибка. Повторите вашу попытку позже»:
И еще одна категория ошибок — моя любимая: неизвестные ошибки.
Зачем работать над ошибочными сценариями?
Обосновать бизнесу необходимость проработки ошибочных сценариев бывает очень сложно. Зачем нам возвращаться назад и что-то исправлять, когда впереди у нас новые фичи? Но у меня есть четыре железных аргумента, которые помогут продемонстрировать вашему product owner’у или бизнесу необходимость такой работы.
Хорошее сообщение об ошибке снижает нагрузку на техническую поддержку и персонал
На слайде представлены некоторые цифры одного из наших клиентов. Это количество звонков пользователей в техподдержку в месяц. Звонки связаны с проблемами определенного рода:
Обратите внимание, 400 человек в месяц звонят просто из-за того, что не могут войти или корректно ввести логин / пароль в соответствующей форме на сайте.
Хорошее сообщение об ошибке помогает пользователю не потеряться в воронке конверсии
Если сообщение об ошибке составлено грамотно, оно возвращает его к основному сценарию, даже если произошел разрыв сессии.
Хорошее сообщение об ошибке обучает работе с сервисом
Возможно, вам даже не потребуется создавать onboarding или какие-то обучающие видео, разработка которых, кстати говоря, тоже стоит приличных денег.
Хорошее сообщение об ошибке позволяет сохранить доверие к сервису в трудную минуту
Это последний, но немаловажный аргумент.
Вообще тема доверия «человек-технология» исследуется довольно давно. Сейчас мы уже достаточно доверяем технологиям. Например, мы никогда не будем перепроверять, отправил ли мессенджер сообщение адресату, или как калькулятор сложил или умножил трехзначные числа (к сожалению, правда, не все сервисы могут похвастаться таким уровнем доверия, как калькуляторы).
Мы доверяем свою жизнь десяткам видов разного программного обеспечения, летая в самолетах. Но это доверие очень легко разрушить. Сделать это может даже самая маленькая ошибка. И такие ошибки случаются как в маленьких, так и в очень больших компаниях.
Из-за чего возникают ошибки
Я несколько раз упомянула «хорошее сообщение об ошибке». Настала пора поговорить о том, что это значит. И для начала разберемся, из-за чего в принципе возникают ошибки.
- первое, что приходит в голову, это какие-то глобальные сбои или технические работы на сервисе;
- специфические баги;
- ошибки пользователя.
Но это далеко не всё. Еще есть:
- проблемы на стороне подключенных сервисов;
- внешние проблемы;
- крайне необычное поведение пользователей или сервиса.
Это не попытка классификации. На самом деле видов ошибок далеко не шесть, их может быть сотня или даже больше. Но в контексте проектирования интерфейсов эти ошибки самые значимые.
Глобальные сбои
Давайте начнем с ситуации, когда ваш сервис полностью недоступен.
К сожалению, такие ошибки могут возникнуть в любых сервисах, от онлайн игр до сложных биржевых профессиональных инструментов.
Хороший вопрос: что в такой ситуации делать?
Пока разработчики спешно чинят какие-то инструменты, несчастные пользователи получают странные сообщения об ошибках и достают вашу техподдержку, пишут неприятные посты в твиттере:
Давайте посмотрим на сообщения, которые в этот момент выводятся:
Они достаточно простые и некоторые из них даже честно извиняются. Но пользователи все равно чувствуют себя некомфортно и пытаются понять, в чем же дело; повторяют вход далеко не через 15 минут; тыкают, куда попало.
Как им помочь?
Подумайте о последствиях
Если вы не знаете, каковы последствия глобального сбоя, просто сходите в техподдержку. Потому что в этот момент ребята там огребают по полной. И они с удовольствием с вами этой болью поделятся.
Многие в таких ситуациях ограничиваются сообщением: да, у нас есть проблема и мы скоро ее поправим:
Но «скоро» — это когда?
Пользователю не нужно знать, когда вы всё поправите, с точностью до минуты. Но им нужно понимать какие-то значимые временные ориентиры, например, 15 минут, один час, пять часов или даже сутки. Это поможет им сориентироваться в пространстве и спланировать управление своими деньгами.
Еще один резонный вопрос (в ракурсе финансового сервиса): работают ли карточки?
И хорошее сообщение об ошибке сможет на него ответить. Даже если карточки не работают, лучше всё равно об этом сказать, потому что это очень важная информация.
Еще одна история — тут зарплата или перевод должны быть; а когда придут эти деньги?
Вроде бы ничего критичного, но когда человек не может проверить баланс, он начинает сильно паниковать. Поэтому предложите проверить баланс альтернативными методами, если это, конечно, возможно.
И последняя, очень серьезная ситуация, когда действительно человеку срочно нужны его деньги. Если это возможно, сообщите, как снять деньги или найти ближайший офис, если у вас есть такой сервис:
Важно понимать, что глобальный сбой — это проблема ваша, а не пользователя. Не нужно перекладывать на него мыслительные процессы. Предложите сразу готовые варианты.
Предупредите заранее
Не все пользователи готовы зайти в личный кабинет прямо сейчас, и далеко не все пользователи в принципе зайдут и заметят ошибку. Но если вы предупредите их заранее (например, постом в Twitter, SMS-сообщением или по электронной почте), то когда они столкнутся с сообщением об ошибке, будут готовы.
Отдельно стоит сказать про профессиональные сервисы, от которых ежедневно зависит работа пользователей. Например, сервис Антиплагиат иногда выводит такое сообщение о проведении технических работ:
Обратите внимание, что указана точная дата и точный диапазон времени — это поможет пользователю спланировать свою работу в вашем сервисе.
Тема предупреждений об ошибках косвенно связана с сохранением доверия. Может показаться, что очередное предупреждение об ошибке заставит часть пользователей усомниться в надежности сервиса (возможно, они бы в этот момент и не воспользовались сервисом, т.е. в принципе не узнали бы об ошибке). Но восприятие предупреждения как заботы или как лишнего камня в огород сервиса зависит в том числе и от того, как часто вы говорите, что у вас проблемы. Плюс есть совершенно разные сервисы. Интернет-банк — это одно. Но, к примеру, если у вас интернет-магазин, не нужно каждый раз писать пользователю о проблемах, потому что он заходит к вам не так часто.
Однако если же мы говорим о профессиональных инструментах, от которых пользователь реально зависит каждый день с утра и до вечера, очень странно не предупредить о проблеме (а частота, с которой допустимо сообщать пользователю о проблемах, при этом сильно зависит от отрасли).
Специфические баги
Тестировщики и продуктовые команды в целом вовремя отлавливают и не допускают вывода на пользователя очень большой доли багов. Но, к сожалению, ошибки случаются везде, и не всегда возможно их избежать.
Для нас баги — это знакомая история. Мы четко классифицируем их по разным параметрам: степени опасности, необходимости исправления и т.п.
Но пользователи когда замечают баг, в принципе не понимают, с чем они столкнулись. Многие даже не знают этого термина. Для них баги на самом деле выглядят вот так:
Мы предполагаем, что если пользователь вдруг заметил что-то странное, он конечно же нам об этом сообщит. У него есть для этого пять или даже больше способов:
- раздел «Контакты» и обратная связь;
- онлайн-консультант и звонок в техподдержку;
- социальные сети и чаты компании;
- отзывы (App Store и Play Market)!!!
- блоги и форумы.
Мы предполагаем, что пользователь когда-нибудь проскролит страницу вниз до подвала, найдет там вкладку «Контакты». В разделе контактов найдет среди карт, отделов, офисов продаж и прочего маленькую кнопочку «Обратная связь», нажмет на нее, выберет тему обращения. Напишет подробное письмо о том, как воспроизвести эту ошибку, приложит скриншоты и отправит.
Да, действительно, такие письма приходят. Но если ошибка очень плохая, человек может сразу оставить отзыв с низкой оценкой на App Store, где также подробно распишет, чем ему ваш сервис не нравится.
У всех перечисленных каналов обращений есть одна очень большая проблема: они вырывают пользователя из контекста, заставляют его отвлекаться на то, чтобы, по сути, помочь вам. Поэтому большинство пользователей предпочитают подождать, пока проблема исчезнет сама (пока вы сами ее заметите):
Или могут вообще перестать пользоваться вашим сервисом, как неработающим.
Поэтому в багтрекере ВКонтакте висит такой вот тикет, который называется «отсутствие кнопки «Сообщить о баге»»:
Действительно, это проблема очень многих сервисов.
Создайте специальные окна для сбора обратной связи
Но есть и позитивные примеры, например, Semrush. Почти по всему сервису размещены специальные окна, которые нацелены на то, чтобы забирать фидбэк от человека.
В такой ситуации пользователю стоит меньших усилий написать вам о какой-то ошибке или о фидбеке. Особенно это актуально для бета-тестирования.
Если нельзя исправить баг быстро, предупредите о нем
К сожалению, бывают такие ситуации, когда вы не можете исправить баг быстро. Можно просто предупредить об этом пользователя — как и в предыдущей части доклада.
В качестве примера здесь приведен скриншот, когда с помощью совершенно обычных окошек разработчики иконочного шрифта material design предупреждают пользователей, что есть проблема совместимости, и приносят свои извинения:
Обратите внимание, что они приводят ссылку для тех, у кого возникли эти проблемы. По ссылке инструкция, как всё исправить.
Самое главное, что нужно запомнить про специфические баги, — это необходимость качественного фидбэка. Поэтому создавайте специальные окна, чтобы как можно быстрее получать от пользователей эту информацию. Ну и второе — конечно, предупреждайте, если вам какой-то баг известен, но вы не можете его поправить.
Ошибки пользователей
К сожалению, многие разработчики считают, что ошибки пользователей — это дело пользователя. Но на самом деле, чем больше пользователи ошибаются в определенной точке продукта, тем сильнее в этой точке виноват сам сервис. В контексте проектирования ошибок я могу предложить пять фишек, которые помогут вам улучшить пользовательский опыт в подобных местах.
Первый пример узкого места многих сервисов — это, конечно, вход / регистрация:
Например, поле входа в InVision. Маленькая красная полосочка — это, в принципе, всё сообщение об ошибке. Наверное, когда дизайнер его рисовал, думал, что пользователь без труда прочитает сообщение: «Упс, комбинация email и пароля не верна». Проверит сначала email, затем пароль, и снова нажмет кнопочку войти. Но статистика подсказывает, что пользователь делает несколько попыток входа и ввода пароля, прежде чем догадывается, что проблема в email-адресе.
Это происходит, потому что внимание пользователя в момент входа сосредоточено в одной очень узкой области — она называется фокусом внимания:
Как вы видите, сообщение об ошибке, достаточно высоко и пользователь может его просто не заметить при обновлении страницы. К тому же InVision стирает пароль (надо же помочь пользователю…). И шевеление в области пароля еще больше фокусирует внимание пользователя; он думает, что ошибка именно там.
Фишка 1. Разместите сообщение в фокусе внимания
Те же ребята из InVision в другой части продукта предоставили информацию об ошибке немного по-другому. Во-первых, они подсветили оба поля. Во-вторых, не стирают пароль, потому что он может быть правильный (они предполагают, что пользователь заметит, где именно ошибка, и сам примет решение):
Фишка 2. Показывайте, где именно ошибка
Подсвечивание обоих полей — это и есть вторая фишка.
Но и это не всегда помогает.
Например, дизайнеры компании Adobe считают, что пользователи действительно это всё читают:
Еще один классический пример предлагает Xiaomi:
Или, например, сайт Госуслуги (как и многие другие) просто дублирует название поля заголовка в ошибку:
Фишка 3. Используйте понятные и короткие формулировки
В примерах выше вся проблема в буквах. Поэтому нужно подумать над тем, как сделать формулировки короче и понятнее. Мы можем легко прочитать это сообщение, когда видим его на огромном экране и фокусируемся на чтении:
Но в окружении интерфейса и текущих задач у пользователей это выглядит вот так:
И они не дочитывают до конца. Когда пользователь читает строку, он фокусируется на начале строки. А чтобы прочитать дальше, ему надо приложить усилия:
Ему неохота читать ваши тексты, он хочет дальше решать свои задачи.
Поэтому, сокращая формулировку и размещая сообщение в зоне фокусировки, мы можем быстрее донести смысл.
Фишка 4. Подскажите, как исправить ошибку
Кто сталкивался с кассами самообслуживания?
Современные кассы самообслуживания, конечно, построены по-разному. Но самые первые из них были построены по такому сценарию: я кладу корзинку на одну сторону, беру по очереди товары, сканирую штрих-код и кладу их на другую сторону, чтобы система знала, что я действительно всю корзину просканировала (по весу). В тот момент, когда я складываю товар на левую сторону, система понимает, что я его отсканировала, и добавляет его в чек. Разработчики касс обратили внимание на очень интересную проблему: люди берут маленький товар (например, бутылку воды), сканируют его, затем сразу берут второй товар и пытаются его провести. При этом система никак не реагирует, сканер не работает, а пользователи ищут глазами помощников и напрягают персонал ритейлера.
В чем была проблема? Пользователи забывают положить маленькие товары на другую сторону. Поэтому разработчики добавили звуковой сигнал, после чего в 90% таких ситуаций покупатели стали обходиться без помощника. Сигнал заставлял человека поднимать глаза на экран кассы и выходить из состояния, когда он сканирует свою огромную корзину покупок: «Точно, я не положил воду».
У этого сообщения об ошибке есть две из перечисленных «фишек»: оно подсказывает, где именно ошибка, и обучает работе с сервисом.
Фишка 5. Сохраняйте работу пользователя
Последнее, но самое интересное.
Давайте сразу на примере. Это кусочек пути регистрации (в очередной раз напоминаю, что регистрация — достаточно слабое место у очень многих сервисов):
Чтобы вообще начать пользоваться финансовым сервисом Revolut, я должна сначала подтвердить свой номер телефона. Обратите внимание, они уже автоматически определили и подставили код страны. Спасибо ребятам.
Дальше я должна ввести свое имя и фамилию. Ну раз они определили мою страну, то я начинаю вводить автоматически по-русски, и когда я уже нажимаю «Далее», заполнив всю форму, сервис мне говорит: «Пожалуйста, используйте латинские буквы». Автоматическая валидация уже давно всем известна, и ее нужно обязательно применять! Но на этом дело не заканчивается. Мне нужно заполнить адресную информацию, причем, обратите внимание, страна уже подставлена автоматически и написана кириллицей.
Но меня не обманешь — я ввожу адрес латиницей, нажимаю Continue. И, как вы думаете, что происходит?
В такие моменты действительно хочется выкинуть телефон куда-нибудь. Но это, конечно, исключительный случай. Однако этот пример также показывает, что лишние и любые повторные действия очень сильно напрягают пользователя, заставляют его нервничать и негативно сказываются на имидже вашего продукта.
Поэтому не заставляйте пользователя вводить какие-то поля заново, используйте как можно больше автоматизации.
Проблемы подключенного сервиса
Тестируйте API подключенных сервисов
На днях мне попался интересный отчет на сайте APIFortress. Там был рассказ про компанию, которая поставляла стоковые изображение своим партнерам. Одним из них было агентство, которое занималось сувениркой с мопсами.
Однажды этот мопс-партнер позвонил в стоковую компанию и пожаловался на поломку сервиса.
Оказалось, что стоковая компания в тот день выпустила с утра минорное обновление API, которое не затронуло большую часть клиентов, но очень сильно ударило по мопс-компании. Сайт у них был построен таким образом, что обновление вызвало какой-то критический сбой работы поиска. Конечные пользователи видели, что ничего не найдено или какую-то неизвестную ошибку. Поэтому на подключенные сервисы надо обращать пристальное внимание.
Учите их различать проблемы
Иногда недостаточно просто знать, что где-то там у вас проблема, потому что пользователи будут видеть странные окна, которые не будут им помогать:
И в интерфейсе эту проблему не решить.
Поэтому очень важно потратить усилия, чтобы научить ваш сервис различать причины проблем с API.
Предусмотрите в интерфейсе оповещение о проблемах
Очень хороший пример — сервис-автоматизатор ifthisthenthat. С помощью связок API различных сервисов (например, умного дома или социальных сетей) они заставляют сторонние сервисы делать определенные вещи. Например, если я опубликовала пост в Instagram, он автоматически уходит в мой Facebook. Или, если я вышла из дома, сервис определяет по моей геопозиции, что я нахожусь в офисе, и проверяет, выключила ли я все свои смарт-утюги. А если не выключила, то выключает.
Эти ребята проделали очень большую работу, и не только в интерфейсе.
Во-первых, они выделяют отдельную вкладку для ошибок. Все неудавшиеся операции собираются в этот лог.
Они определяют разные типы ошибок:
В первом случае — сервис Instagram офлайн, и мы понимаем, в чем проблема. Возможно, мы временно вышли из зоны действия сети.
В случае, если пользователь никак не может поспособствовать решению проблемы, выводится просто оповещение.
Внешние проблемы
Что такое внешние проблемы в моем пользовательском понимании?
Весь software завязан на аппаратуру, на датчики и т.п. Всё это тоже создано людьми и может не работать. Поэтому очень важно сообщать об этом пользователю. Хороший сервис может сообщать о таких ошибках, как о своих.
Дайте понять, какие действия в вашем сервисе недоступны из-за внешних проблем
Хороший пример — отсутствие интернет-соединения в коммуникаторе Slack. Если во время работы у меня отвалился интернет, я вижу вот такое сообщение сверху:
Как мы помним про сообщения об ошибках пользователей, в момент ввода какого-то текста пользователь сконцентрирован в этой области:
Slack об этом не забывает и подсвечивает поле желтеньким.
При этом он не блокирует мне набор сообщения. Я могу продолжить писать его дальше, но при попытке отправить Slack-бот отправляет мне вот такое сообщение:
И в принципе очень доступно объясняет, с чем именно проблема. Такую ошибку я замечу достаточно быстро.
Большая проблема с внешними ошибками, которая пришла к нам еще из «древних» времен, когда продукты создавались инженерами для инженеров, — это содержание текстов об ошибках:
Они написаны таким языком, как будто мы сейчас до сих пор подразумеваем, что пользователь знает, что такое firewall, ftp, dll, ядро, kernel и так далее.
Четко разделите уровни компетенции
Техническому специалисту мы показываем одну информацию, а пользователю — другую.
Наверное, стоит отдельно сказать про то, как люди в принципе общаются с техподдержкой.
Для многих это действительно большой стресс. Большая часть сообщений об ошибках совершенно не подразумевает, что они должны быть поняты. Человек, который даже не знает английского языка, пытается как-то объяснить: у меня там что-то сломалось. Он испытывает очень сильный дискомфорт. И всё это влияет в целом на его опыт общения с вашим сервисом. Поэтому старайтесь создавать такие сообщения, которые пользователь сможет осознать и своими словами передать техподдержке.
Например, это фото 3D-принтера, который четко и ясно (с помощью маленького экранчика) говорит, что температурный сенсор испортился — произошла ошибка, поэтому он остановился. Свяжитесь с техподдержкой. Пользователь легко может понять, в чем дело, и для него не сложно описать эту проблему своими словами без технических терминов:
Помогите пользователю оценить приоритет проблемы
Что это значит?
Рассмотрим такой пример: большая часть машин уже имеет экранчики, где мы можем выводить текст (не то, что раньше). Но такое ощущение, будто разработчики копипастят текст описания ошибок из старых инструкций, которые совершенно непонятны и требуют долгого вчитывания:
В такой ситуации пользователь не понимает, что делать. Некоторые водители-новички вместо того, чтобы прочитать инструкцию, просто продолжают ездить, думая, что всё в порядке. А у других, наоборот, начинается паника — они пытаются вызвать эвакуатор.
А есть еще такая категория: «У меня там до зарплаты неделька… ничего же не случится?»
Поэтому очень важно дать возможность пользователю оценить опасность этой проблемы. Пользователь в этот момент не хочет лезть в какие-то сложные инструкции. Если действительно произошло что-то страшное, важно указать одно — серьезность проблемы. Иногда «эксплуатацию продолжать нельзя», а иногда и правда можно подождать до зарплаты.
Крайне необычное поведение пользователей или сервисов.
Бывает ситуация, как на графике. Что вызвало такой резкий скачок? К примеру, это температура в двигателе повысилась? Или это просто датчик какой-то забарахлил?
В таких ситуациях лучше всего пользователю дать возможность самому принять решение о том, что же это было.
В качестве примера — хорошая длинная история. В сентябре этого года видеоблогер PewDiePie во время стрима на несколько сотен тыс. человек обозвал своего чернокожего противника словом, которое в англоязычном мире называть в принципе не стоит. Он, конечно, потом извинился, но все равно произошел скандал. Производители разных игр, в том числе, Шон Ванаман, подали жалобу в YouTube с просьбой удалить все видеозаписи того, как PewDiePie играл в их игры.
Но за PewDiePie тоже стояла большая армия поддержки. И на игры Шона Ванамана в Steam (сервис, который продает эти игры) посыпались сотни негативных отзывов. Эти отзывы не отражали качество игры, но могли негативно сказаться на ее продажах. И Steam проделал просто потрясающую работу: они обратили внимание пользователя, что произошло, что замечен нетипичный объем отрицательных отзывов с 11 сентября:
При этом они позволяют пользователю самому решить, исключать эти отзывы или учитывать. Пользователь может сам принять решение, насколько эти отзывы для него важны в контексте покупки игры. Такая работа над ошибками восхищает меня и как usabilist’а, и как пользователя этого сервиса.
Дополнительные возможности — скрытый потенциал
Не все ошибки — просто баги. У многих есть скрытый потенциал. Давайте про это немного поговорим.
Обучайте через ошибки
Во-первых, как я уже говорила ранее, через ошибки можно и нужно обучать.
Например, сервис Skyeng — это онлайн школа английского языка, которая работает только через браузер Google Chrome. Этот браузер автоматически (по дефолту) иногда блокирует входящие видеозвонки или аудиозаписи. И в такой ситуации Skyeng вешает кнопочку, которая ведет на вполне подробную инструкцию:
У этого решения тоже есть некоторые проблемы. Если таких кнопочек в вашем сервисе будет очень много, все эти инструкции будет просто невыносимо, дорого и сложно поддерживать в актуальном виде. А пользователь на самом деле не сильно любит читать какие-то инструкции.
Еще один пример — SEMrush. Это окно входа в сервис:
Оно отображается в том случае, если я пошла по ссылке, которая требует от меня авторизации. Большая часть сервисов в такой ситуации выдает ошибку 404, пользователь уходит и больше не возвращается по этой ссылке. Но в SEMrush не ограничиваются просто формой входа. Они показывают дополнительные картинки и описание работы в той части сервиса, куда ведет эта ссылка. Таким образом пользователь входит в контекст. Он понимает, куда пойдет, если сервис ему знаком. А если сервис не знаком, получит беглое представление о том, что его ждет после входа.
Выводите из тупика
Еще один потенциал сообщений об ошибках — это вывод из тупика.
Часто ошибки являются абсолютно тупиковыми сценариями. Пользователю нужно вспоминать контекст и возвращаться по сценарию выше.
Например, возьмем сервис Avito. Там есть вкладка «Сохраненные поиски»:
Если там ничего нет, пользователь вынужден возвращаться обратно к строке поиска. В соответствии с представленной здесь инструкцией, которую он должен каким-то образом запомнить, он должен выполнить сохранение поиска где-то там на странице.
А можно было сделать вот так:
Мы знаем (сохраняем) историю и выводим ее здесь, чтобы пользователь, не отрываясь от контекста, нажал звездочку и сохранил какой-то нужный ему поиск. Таким образом мы превращаем тупиковый сценарий в возврат к основному пути.
Доступность
Есть еще одна важная тема, которую я хотела обсудить, это доступность интерфейсов.
Меня очень радует, что в последнее время об этом стали много говорить, и много в этом направлении стали делать. Например, недавно UsabilityLab проводили тестирование доступности интернет-банков для людей с нарушениями зрения и слуха.
Но в контексте ошибок мы иногда забываем про разницу восприятия и делаем некоторые вещи, которых делать нельзя.
Например, многие используют только цветовую индикацию ошибки. Так делать не стоит, потому что есть дальтоники:
Многие дизайнеры скажут: «Я всё проверил в специальном сервисе, который показывает, как видит дальтоник». Но на самом деле эти сервисы никогда не покажут точной картины, потому что все дальтоники видят по-разному. И даже если вы подберете яркость / контрастность, всё равно существует риск, что пользователь-дальтоник эту ошибку не распознает.
Например, поле регистрации во Wrike содержит как раз такую ошибку:
У них реализована чисто цветовая дифференциация — при ошибке красным подсвечивается обводка и текст внутри поля. Лучше всего добавить какое-то текстовое сообщение или символ.
Еще одна проблема — это серые или слишком мелкие надписи. Если вы увидите в своем интерфейсе мелкий серый курсивный шрифт на сером фоне, можете смело идти к дизайнеру и заставлять его переделывать, потому что существуют разные мониторы и на дешевых такие вещи иногда не видны:
Человек просто сломает глаза при попытке прочитать такой текст.
Проводите Accessibility testing для сценариев с ошибками
Бизнес-ценность
Когда я показала этот доклад своему коллеге-менеджеру, он сказал: «Не убедила». Потому что для бизнеса долго, дорого и совсем не выгодно делать такую большую работу над ошибками. В контексте проектирования интерфейсов я бы хотела сказать, что я не призываю вас так прорабатывать вообще все ошибочные ситуации.
Что нужно делать? Мой коллега выстроил работу в своем коллективе следующим образом. Все ошибки, которые возникают, сначала собираются в какой-то один большой мешок (log). Оттуда вычленяются только те ошибки, которые повторяются.
Повторяющиеся ошибки уже имеют бизнес-ценность. Это те ошибки, на которые стоит потратить время.
Но далеко не всегда нужно торопиться и сразу лепить ошибку на интерфейс, потому что очень часто возникновение таких ошибок вообще можно предотвратить, переписав немножко код, сходив к фронтенду и поправив что-то. И только если не получается избежать выхода ошибки на пользователя, действительно стоит задуматься о каких-то интерфейсных сообщениях.
Я понимаю, что интерфейс — это не всегда часть вашей работы. И даже далеко не все product owner’ы горят желанием выстраивать работу с ошибками в своей команде, потому что это не всегда выгодно (выгода, если и есть, иногда не видна сразу). Но моя цель — немного расширить ваш образ мышления и задать вопрос: вы делаете только свою работу или вы делаете классный продукт?
Потому что классный продукт умеет сообщать об ошибках. Он заботится о пользователе, даже когда что-то идет не так.
Резюме
Что я предлагаю вам делать со всей этой информацией?
- Когда вы придете на работу, обсудите доклад с командой и владельцем продукта. Особенно полезно зайти к UX’ерам или к дизайнерам.
- Проверьте, насколько ваши сообщения об ошибках полезны пользователям.
- После этого вы сможете комплексно посмотреть на свой продукт, найти его слабые места, которых раньше, возможно, не замечали, и улучшить ошибочные сценарии.
- И еще один очень важный пункт в контексте тестирования — ошибочные сценарии тоже нужно тестировать и часто на равных правах с остальными.
Что почитать?
Здесь есть несколько ссылок:
- «Release It!: Design and Deploy Production-Ready Software», Michael T. Nygard
- «How to write a great error message», Thomas Fuchs, https://goo.gl/4L8YWo
- Architecting Your Software Errors For Better Error Reporting, Nick Harley, https://goo.gl/7em6cQ
В заключение я хочу сказать, наверное, только одну вещь: ошибки — это тоже опыт. Проектируйте его.
Если тема тестирования и обработки ошибок вам так же близка, как и нам, наверняка вас заинтересуют вот эти доклады на нашей майской конференции Heisenbug 2018 Piter:
- Пишем UI тесты для Web, iOS и Android одновременно # python (Игорь Балагуров, Uptick)
- Web Security Testing Starter Kit (Андрей Леонов, SEMrush)
- Бета-тестирование ВКонтакте (Анастасия Семенюк, ВКонтакте)
Валидация форм на стороне клиента
- Назад (en-US)
- Обзор: Forms
- Далее
Перед отправкой данных на сервер важно убедиться, что все обязательные поля формы заполнены данными в корректном формате. Это называется валидацией на стороне клиента и помогает убедиться, что данные, введённые в каждый элемент формы, соответствуют требованиям. Данная статья проведёт вас через основные концепци и примеры валидации на стороне клиента.
Начальные требования: | Владение компьютером, достаточное понимание HTML, CSS, и JavaScript. |
---|---|
Цель: | Понять, что такое валидация на стороне клиента, почему это важно и как применять различные техники для её реализации. |
Валидация на стороне клиента — это первичная проверка введённых данных, которая существенно улучшает удобство взаимодействия с интерфейсом; обнаружение некорректных данных на стороне клиента позволяет пользователю немедленно их исправить. Если же проверка происходит только на сервере, процесс заполнения может быть более трудоёмким, так как требует повторения одних и тех же действий отправки данных на сервер для получения обратного ответа с сообщением о том, что нужно исправить.
Однако, не следует рассматривать валидацию на стороне клиента как достаточную меру безопасности! Любые данные, отправляемые через форму, необходимо дополнительно проверять на безопасность и на стороне сервера, поскольку валидацию на стороне клиента достаточно просто обойти и она может не остановить злоумышленников. Чтобы лучше понимать потенциальные угрозы, рекомендуем ознакомиться с разделом Безопасность вебсайтов; валидация на стороне сервера выходит за рамки этого модуля, но о ней следует помнить.
Что такое валидация формы?
Зайдите на любой популярный сайт, имеющий форму регистрации. Вы заметите, что при вводе данных в неправильном формате, пользователя сразу уведомляют о наличии проблемы. Вы получите примерно такое сообщение:
- «Обязательное поле» (Вы не можете оставить поле пустым).
- «Пожалуйста, введите номер телефона в формате xxx-xxxx» (Чтобы данные считались корректными, их необходимо указать в определённом формате).
- «Пожалуйста, введите корректный email-адрес» (вы ввели данные в неправильном формате).
- «Длина пароля должна быть от 8 до 30 символов и включать одну заглавную букву, один символ, и одну цифру.» (Требования к формату данных достаточно конкретные).
Это называется валидацией формы. По мере ввода, браузер и/или сервер проверяют данные, чтобы определить, соответствуют ли они требуемому формату. Валидация, выполняемая в браузере, называется валидацией на стороне клиента, а выполняемая на сервере — валидацией на стороне сервера. В этом разделе мы сосредоточимся на валидации, выполняемой на стороне клиента.
Если формат корректен, приложение позволяет отправить данные на сервер и (обычно) сохранить в базу данных; в противном случае выводится сообщение с описанием того, что нужно исправить, позволяя ввести данные снова.
Мы хотим максимально упростить заполнение веб-форм. Тогда почему мы настаиваем валидации данных? На это есть три основные причины:
- Мы хотим получать правильные данные в правильном формате. Наши приложения не будут работать должным образом, если данные от пользователей хранятся в неправильном формате, некорректны сами по себе или вовсе пропущены.
- Мы хотим защитить данные пользователей. Принуждение пользователей вводить надёжные пароли облегчает защиту их аккаунтов.
- Мы хотим защитить себя. Существует множество способов, позволяющих злоумышленникам с помощью незащищённых форм навредить приложению (смотрите Безопасность вебсайтов).
Предупреждение: Никогда не доверяйте данным, передаваемым на сервер клиентской программой. Даже если ваша форма правильно валидируется и не допустит введение потенциально вредоносных данных на стороне клиента, злоумышленники по-прежнему могут изменить сетевой запрос.
Типы валидации на стороне клиента
Существует два типа валидации на стороне клиента, с которыми вы столкнётесь в Интернете:
- Встроенная валидация форм использует функционал валидации HTML5, который мы неоднократно обсуждали в этом модуле. HTML5-валидация обычно не требует большого количества JavaScript-кода и демонстрирует лучшую производительность, но не настолько настраиваема, как валидация с помощью JavaScript.
- JavaScript-валидация кодируется с помощью JavaScript. Она полностью настраиваема, но требует программирования всей логики (или использования библиотеки).
Использование встроенной валидации форм
Одной из самых важных функций элементов форм HTML5 (en-US) является способность валидировать бóльшую часть пользовательских данных без использования JavaScript. Это выполняется с помощью атрибутов валидации у элементов формы. Многие из них мы уже рассмотрели в этом курсе:
required
: Определяет, что для отправки формы данное поле предварительно должно быть заполнено.minlength
иmaxlength
: Задаёт минимальную и максимальную длину текстовых данных (строк)min
иmax
: Задаёт минимальное и максимальное значение для поля, расчитанного на числовой тип данныхtype
: Определяет тип данных, на который рассчитано поле: число, email-адрес или какой-то другой предустановленный типpattern
: С помощью регулярного выражения, определяет шаблон, которому должны соответствовать вводимые данные.
Если данные, введённые в поле формы, соответствуют правилам перечисленных выше атрибутов, они считаются валидными, если нет — не валидными
Когда элемент валиден, справедливы следующие утверждения:
- Элемент соответствует CSS-псевдоклассу
:valid
, позволяющему стилизовать только валидные элементы. - Если пользователь пытается отправить данные, браузер отправит форму при условии, что ничто другое (например, JavaScript) не помешает ему это сделать
Когда элемент не валиден, справедливы следующие утверждения:
- Элемент соответствует CSS-псевдоклассу
:invalid
или, в зависимости от ошибки, другим псевдоклассам (например,:out-of-range
), которые позволяют применять определённые стили к элементам, не являющимся валидными. - Если пользователь пытается отправить данные, браузер заблокирует форму и выведет сообщение об ошибке.
Примеры встроенной валидации форм
В этом разделе мы протестируем некоторые из атрибутов, которые обсуждали выше.
Простой начальный файл
Давайте начнём с простого примера: поле, позволяющее указать своё предпочтение — банан или вишня. Этот пример включает обычное текстовое поле <input>
, связанный с ним элемент <label>
и кнопку отправки формы <button>
. Исходный код можно найти на GitHub по адресу fruit-start.html, а ниже приведён рабочий пример.
<form>
<label for="choose">Would you prefer a banana or cherry?</label>
<input id="choose" name="i_like">
<button>Submit</button>
</form>
input:invalid {
border: 2px dashed red;
}
input:valid {
border: 2px solid black;
}
Для начала скопируйте файл fruit-start.html
в новую папку на вашем жёстком диске.
Атрибут required
Самым простым в HTML5-валидации является атрибут required
. Добавьте его к элементу, чтобы сделать заполнение обязательным. Элемент с данным атрибутом соответствует CSS-псевдоклассу :required
, а если поле ввода пустое, вместо отправки формы отобразится сообщение об ошибке. Пока поле пустое, оно также будет соответствовать CSS-псевдоклассу :invalid
.
Добавьте к полю атрибут required
, как показано ниже.
<form>
<label for="choose">Would you prefer a banana or cherry? (required)</label>
<input id="choose" name="i_like" required>
<button>Submit</button>
</form>
Обратите внимание на CSS, который включён в файл примера:
input:invalid {
border: 2px dashed red;
}
input:invalid:required {
background-image: linear-gradient(to right, pink, lightgreen);
}
input:valid {
border: 2px solid black;
}
Данный CSS задаёт полю красную пунктирную рамку, когда оно не валидно, а когда валидно — сплошную чёрную. Мы также добавили фоновый градиент для обязательных не валидных полей. Проверьте новое поведение в примере ниже:
Попробуйте отправить форму без введения значения. Обратите внимание, что не валидное поле получает фокус, появляется сообщение об ошибке («Заполните это поле») и блокируется отправка формы.
Наличие атрибута required
у любого элемента, который его поддерживает, означает, что элемент соответствует CSS-псевдоклассу :required
, независимо от того, имеет он значение или нет. Если элемент <input>
не содержит значение, он будет соответствовать псевдоклассу :invalid
.
Примечание: Для повышения удобства взаимодействия указывайте пользователям, какие поля являются обязательными. К тому же, этого требует руководство по обеспечению доступности WCAG. Требуйте обязательного ввода только тех данных, которые вам действительно нужны: например, так ли важно знать пол или должность пользователя?
Валидация с помощью регулярного выражения
Ещё одной полезной функцией валидации является атрибут pattern
, который в виде значения принимает Регулярное выражение. Регулярное выражение (regex) — это шаблон, который может быть использован для сопоставления набора символов в текстовой строке, поэтому они идеально подходят для валидации формы и используются для множества других целей в JavaScript.
Регулярные выражения достаточно сложны, и мы не будем подробно рассматривать эту тему в данной статье. Ниже приведены несколько примеров, чтобы дать вам представление о том, как они работают.
a
— Соответствует одному символуa
(неb
, неaa
, и так далее).abc
— Соответствует символуa
, за которой следуетb
, за которой следуетc
.ab?c
— Соответствует символуa
, за которым опционально может следоватьb
, за которым следуетc
. (ac
илиabc
)ab*c
— Соответствует символуa
, за которым опционально может следовать любое количество символовb
, за которыми следуетc
. (ac
,abc
,abbbbbc
, и так далее).a|b
— Соответствует символуa
илиb
.abc|xyz
— Соответствует в точностиabc
или в точностиxyz
(но неabcxyz
илиa
илиy
, и так далее).
Есть еще много возможностей, которые мы не упомянули. Полный список со множеством примеров можно найти в документации по Регулярным выражениям
Давайте рассмотрим пример. Добавьте в атрибут pattern
следующий шаблон:
<form>
<label for="choose">Would you prefer a banana or a cherry?</label>
<input id="choose" name="i_like" required pattern="[Bb]anana|[Cc]herry">
<button>Submit</button>
</form>
input:invalid {
border: 2px dashed red;
}
input:valid {
border: 2px solid black;
}
Это даёт нам следующее обновление — опробуйте его:
В этом примере элемент <input>
принимает одно из четырёх возможных значений: строку «banana», «Banana», «cherry», или «Cherry». Регулярные выражения чувствительны к регистру, но с помощью шаблона «Aa», вложенного в квадратные скобки, мы сделали поддержку написания слова как с большой, так и с маленькой буквы.
Подставьте в атрибут pattern
приведённые выше примеры регулярных выражений, и посмотрите, как это повлияет на валидацию введённого в поле значения. Попробуйте написать свои шаблоны проверки и посмотрите, что получится. По возможности, делайте их связанными с фруктами, чтобы примеры имели смысл.
Если не пустое значение элемента <input>
не соответствует шаблону регулярного выражения, input
будет соответствовать псевдоклассу :invalid
.
Примечание: Некоторым типам элементов <input>
для валидации с помощью регулярного выражения не требуется атрибут pattern
. Например, поле с типом email
валидирует значение по шаблону одного email-адреса или, если присутствует атрибут multiple
(en-US), шаблону списка email-адресов, разделённых запятыми.
Ограничение длины вводимых значений
Можно ограничить максимально допустимое количество символов для текстовых полей <input>
или <textarea>
(en-US) используя атрибуты minlength
(en-US) и maxlength
. Поле будет не валидным, если количество символов его содержимого будет меньше minlength
(en-US) или больше maxlength
.
Зачастую браузеры не позволяют пользователям вводить в текстовое поле значение, длина которого превышает максимально допустимую. Можно существенно повысить удобство использования, если помимо ограничения в атрибуте maxlength
добавить доступный индикатор, отображающий текущее и максимально допустимое количество символов, что даст пользователю возможность уместить содержимое в заданные рамки. Хорошим примером является окно написания твита в Twitter. Для реализации такого функционала можно использовать JavaScript, включая решения, использующие maxlength
.
Ограничение допустимых значений
В полях, предназначенных для ввода чисел (например, <input type="number">
), диапазон допустимых значений можно определить с помощью атрибутов min
и max
. Если поле содержит значение за пределами данного диапазона, оно будет не валидным.
Давайте рассмотрим другой пример. Создайте новую копию файла fruit-start.html.
Содержимое элемента <body>
замените на:
<form>
<div>
<label for="choose">Would you prefer a banana or a cherry?</label>
<input type="text" id="choose" name="i_like" required minlength="6" maxlength="6">
</div>
<div>
<label for="number">How many would you like?</label>
<input type="number" id="number" name="amount" value="1" min="1" max="10">
</div>
<div>
<button>Submit</button>
</div>
</form>
- Здесь мы в поле с типом
text
атрибутамminlength
иmaxlength
, задали одинаковое значение 6, что соответствует количеству символов в словах banana и cherry. - В поле с типом
number
атрибутуmin
мы задали значение 1, а атрибутуmax
значение 10. При вводе чисел за пределами данного диапазона, поле будет становиться не валидным; с помощью стрелок увеличения/уменьшения пользователи не смогут выйти за границы диапазона. Текущее поле не является обязательным для заполнения, поэтому даже после очистки будет оставаться валидным.
input:invalid {
border: 2px dashed red;
}
input:valid {
border: 2px solid black;
}
div {
margin-bottom: 10px;
}
Демонстрационный пример:
Примечание: <input type="number">
(и другие типы, такие как range
и date
) могут также принимать атрибут step
(en-US), который задаёт шаг увеличения или уменьшения значения при использовании кнопок вверх и вниз. В примере выше мы явно не указывали атрибут step
, поэтому он получает значение по умолчанию, равное 1
. Это значит, что дробные числа, такие как 3.2, будут не валидными.
Полный пример
Ниже представлен полный пример, демонстрирующий использование встроенного функционала валидации. Сначала немного HTML:
<form>
<p>
<fieldset>
<legend>Do you have a driver's license?<abbr title="This field is mandatory" aria-label="required">*</abbr></legend>
<!-- Так как в группе радио-кнопок, имеющих одинаковое имя, выбранной может быть
только одна, то и атрибут "required" достаточно задать хотя бы одной кнопке,
чтобы сделать всю группу обязательной для заполнения -->
<input type="radio" required name="driver" id="r1" value="yes"><label for="r1">Yes</label>
<input type="radio" required name="driver" id="r2" value="no"><label for="r2">No</label>
</fieldset>
</p>
<p>
<label for="n1">How old are you?</label>
<!-- Атрибут "pattern" может выступать фолбэком для браузеров, которые
не поддерживают поля ввода c числовым типом данных. Те браузеры,
которые такие поля поддерживают, будут просто игнорировать его.
Как раз, ниже атрибут "pattern" выполняет роль фолбека.
-->
<input type="number" min="12" max="120" step="1" id="n1" name="age"
pattern="d+">
</p>
<p>
<label for="t1">What's your favorite fruit?<abbr title="This field is mandatory" aria-label="required">*</abbr></label>
<input type="text" id="t1" name="fruit" list="l1" required
pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range">
<datalist id="l1">
<option>Banana</option>
<option>Cherry</option>
<option>Apple</option>
<option>Strawberry</option>
<option>Lemon</option>
<option>Orange</option>
</datalist>
</p>
<p>
<label for="t2">What's your e-mail address?</label>
<input type="email" id="t2" name="email">
</p>
<p>
<label for="t3">Leave a short message</label>
<textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
</p>
<p>
<button>Submit</button>
</p>
</form>
И немного CSS для стилизации HTML:
form {
font: 1em sans-serif;
max-width: 320px;
}
p > label {
display: block;
}
input[type="text"],
input[type="email"],
input[type="number"],
textarea,
fieldset {
width : 100%;
border: 1px solid #333;
box-sizing: border-box;
}
input:invalid {
box-shadow: 0 0 5px 1px red;
}
input:focus:invalid {
box-shadow: none;
}
Получим следующее:
В статье Атрибуты валидации (en-US) можно найти полный список атрибутов, которые можно использовать для ограничения допустимых значений ввода и типов полей input
, которые их поддерживают.
Валидация форм с помощью JavaScript
Если нужно управлять внешним видом встроенных сообщений об ошибке или работать с устаревшими браузерами, которые не поддерживают встроенную валидацию форм HTML, вам следует использовать JavaScript. В данном разделе мы рассмотрим различные способы делать это.
Constraint Validation API
Большинство браузеров поддерживают Constraint Validation API, который состоит из набора свойств и методов, доступных на DOM-интерфейсах следующих элементов форм:
HTMLButtonElement
(представляет элемент<button>
)HTMLFieldSetElement
(представляет элемент<fieldset>
)HTMLInputElement
(представляет элемент<input>
)HTMLOutputElement
(представляет элемент<output>
)HTMLSelectElement
(представляет элемент<select>
)HTMLTextAreaElement
(представляет элемент<textarea>
)
Для перечисленных выше элементов Constraint Validation API делает доступными следующие свойства.
validationMessage
: Возвращает локализованное сообщение, описывающее ограничения валидации (если таковые имеются), которым не удовлетворяет определённый элемент. Если элемент не участвует в валидации (willValidate
установлено вfalse
) или значение элемента удовлетворяет установленным ограничениям (является валидным), будет возвращена пустая строка.validity
: Возвращает объектValidityState
, который содержит несколько свойств, описывающих состояние валидности элемента. Подробное описание всех свойств доступности можно найти на странице справочникаValidityState
; ниже приведён список наиболее используемых:patternMismatch
: Возвращаетtrue
, если значение не соответствует шаблону, указанному в атрибутеpattern
, иfalse
если соответствует. Если true, элемент соответствует CSS-псевдоклассу:invalid
.tooLong
: Возвращаетtrue
, если значение длиннее максимальной длины, указанной в атрибутеmaxlength
, иfalse
если оно короче или равно ей. Если true, элемент соответствует CSS-псевдоклассу:invalid
.tooShort
: Возвращаетtrue
, если значение короче минимальной длины, указанной в атрибутеminlength
, иfalse
если оно длинее или равно ей. Если true, элемент соответствует CSS-псевдоклассу:invalid
.rangeOverflow
: Возвращаетtrue
, если значение больше указанного в атрибутеmax
максимума, иfalse
если меньше или равно ему. Если true, элемент соответствует CSS-псевдоклассам:invalid
и:out-of-range
rangeUnderflow
: Возвращаетtrue
, если значение меньше указанного в атрибутеmin
, иfalse
если больше или равно ему. Если true, элемент соответствует CSS-псевдоклассу:invalid
и:out-of-range
.typeMismatch
: Возвращаетtrue
, если значение не соответствует требуемому синтаксису (когда дляtype
задано значениеemail
илиurl
), иfalse
если синтаксис корректный. Еслиtrue
, элемент соответствует CSS-псевдоклассу:invalid
.valid
: Возвращаетtrue
, если элемент соответствует всем ограничениям валидации — следовательно, считается валидным, иfalse
если не соответствует какому-то ограничению. Если true, элемент соответствует CSS-псевдоклассу:valid
; иначе:invalid
.valueMissing
: Возвращаетtrue
, если у элемента есть атрибутrequired
, но не введено значенение, иначе возвращаетfalse
. Если true, элемент соответствует CSS-псевдоклассу:invalid
.
willValidate
: Возвращаетtrue
, если элемент будет участвовать в валидации при отправке формы; иначе возвращаетfalse
.
Также для перечисленных выше элементов Constraint Validation API делает доступными следующие методы.
checkValidity()
: Возвращаетtrue
, если значение элемента проходит валидацию, иначе возвращаетfalse
. Если элемент не валиден, данный метод также запускает на нём событиеinvalid
.setCustomValidity(message)
: Позволяет добавить в элемент кастомное сообщение об ошибке; при этом элемент будет считаться не валидным и отобразится указанная ошибка. Это позволяет использовать JavaScript-код, чтобы представить ошибку валидации иначе, чем это предусмотрено стандартными средствами валидации HTML5. При сообщении об ошибке данное кастомное сообщение показывается пользователю.
Реализация кастомного сообщения об ошибке
Как вы видели в примерах HTML5-валидации выше, каждый раз, когда пользователь пытается отправить не валидную форму, браузер отображает сообщение об ошибке. Способ отображения сообщения зависит от браузера.
У этих автоматических сообщений есть два недостатка:
- Не существует стандартного способа их стилизации с помощью CSS.
- Они зависят от локали браузера, из-за чего страница может быть на одном языке, а сообщение об ошибке — на другом, как показано на следующем скриншоте браузера Firefox.
Настройка таких сообщений об ошибках является одной из наиболее распространённых причин использования Constraint Validation API. Давайте рассмотрим простой пример, как это делается.
Начнём с простого HTML (Не стесняйтесь поместить это в пустой HTML-файл. Вы можете взять за основу свежую копию fruit-start.html, если хотите):
<form>
<label for="mail">I would like you to provide me with an e-mail address:</label>
<input type="email" id="mail" name="mail">
<button>Submit</button>
</form>
Добавьте на страницу следующий JavaScript:
const email = document.getElementById("mail");
email.addEventListener("input", function (event) {
if (email.validity.typeMismatch) {
email.setCustomValidity("I am expecting an e-mail address!");
} else {
email.setCustomValidity("");
}
});
Здесь мы сохраняем ссылку на поле email, а затем добавляем к нему обработчик события, который запускает код обработчика каждый раз, когда в поле меняется значение.
В коде обработчика мы проверяем, возвращает ли свойство поля email validity.typeMismatch
значение true
, что значит, что содержащееся значение не соответствует шаблону корректного email-адреса. Если возвращается true
, мы вызываем метод setCustomValidity()
(en-US) с кастомным сообщением. Это делает поле не валидным, поэтому попытка отправить форму приводит к ошибке и отображается кастомное сообщение об ошибке.
Если свойство validity.typeMismatch
возвращает false
, мы вызываем метод setCustomValidity()
с пустой строкой. Это делает поле валидным, поэтому форма может быть успешно отправлена.
Попробовать пример можно ниже:
Более подробный пример
Теперь, когда мы разобрали простой пример, давайте посмотрим, как можно использовать данный API для создания более сложной валидацию.
Во-первых, HTML. Опять же, не стесняйтесь писать его вместе с нами:
<form novalidate>
<p>
<label for="mail">
<span>Please enter an email address:</span>
<input type="email" id="mail" name="mail" required minlength="8">
<span class="error" aria-live="polite"></span>
</label>
</p>
<button>Submit</button>
</form>
Эта простая форма использует атрибут novalidate
, который отключает автоматическую валидацию браузером; это позволяет нашему скрипту взять управление валидацией на себя. Однако, это не отменяет поддержку Constraint Validation API или псевдоклассов, таких как :valid
или ему подобных. Это значит, что хотя браузер автоматически и не проверяет валидность формы перед отправкой данных, вы можете сделать это самостоятельно и соответствующим образом стилизовать форму.
Объектом валидации является обязательный для заполнения <input type="email">
, длина которого не должна быть меньше 8 символов. Давайте напишем код, проверяющий эти критерии, и покажем кастомное сообщение об ошибке в случае несоблюдения какого-то из них.
Мы хотим показывать сообщение об ошибке внутри элемента <span>
. Данному элементу задан атрибут aria-live
, чтобы гарантировать, что наше кастомное сообщение об ошибке будет доступно всем, включая пользователей скринридеров.
Примечание: Ключевым моментом здесь является то, что добавление к форме атрибута novalidate
отключает отображение встроенных сообщений об ошибке и позволяет вместо этого добавлять в DOM кастомные сообщения.
Перейдём к базовому CSS, чтобы немного улучшить внешний вид формы и обеспечить визуальную обратную связь при введении не валидных данных:
body {
font: 1em sans-serif;
width: 200px;
padding: 0;
margin : 0 auto;
}
p * {
display: block;
}
input[type=email]{
-webkit-appearance: none;
appearance: none;
width: 100%;
border: 1px solid #333;
margin: 0;
font-family: inherit;
font-size: 90%;
box-sizing: border-box;
}
/* Это стили для не валидных полей */
input:invalid{
border-color: #900;
background-color: #FDD;
}
input:focus:invalid {
outline: none;
}
/* Это стили для кастомных сообщений об ошибке */
.error {
width : 100%;
padding: 0;
font-size: 80%;
color: white;
background-color: #900;
border-radius: 0 0 5px 5px;
box-sizing: border-box;
}
.error.active {
padding: 0.3em;
}
Теперь давайте рассмотрим JavaScript, который реализует кастомную валидацию.
// Существуют разные способы получить DOM-узел; здесь мы определяем саму форму и
// поле ввода email и элемент span, в который поместим сообщение об ошибке
const form = document.getElementsByTagName('form')[0];
const email = document.getElementById('mail');
const emailError = document.querySelector('#mail + span.error');
email.addEventListener('input', function (event) {
// Каждый раз, когда пользователь что-то вводит,
// мы проверяем, являются ли поля формы валидными
if (email.validity.valid) {
// Если на момент валидации какое-то сообщение об ошибке уже отображается,
// если поле валидно, удаляем сообщение
emailError.textContent = ''; // Сбросить содержимое сообщения
emailError.className = 'error'; // Сбросить визуальное состояние сообщения
} else {
// Если поле не валидно, показываем правильную ошибку
showError();
}
});
form.addEventListener('submit', function (event) {
// Если поле email валдно, позволяем форме отправляться
if(!email.validity.valid) {
// Если поле email не валидно, отображаем соответствующее сообщение об ошибке
showError();
// Затем предотвращаем стандартное событие отправки формы
event.preventDefault();
}
});
function showError() {
if(email.validity.valueMissing) {
// Если поле пустое,
// отображаем следующее сообщение об ошибке
emailError.textContent = 'You need to enter an e-mail address.';
} else if(email.validity.typeMismatch) {
// Если поле содержит не email-адрес,
// отображаем следующее сообщение об ошибке
emailError.textContent = 'Entered value needs to be an e-mail address.';
} else if(email.validity.tooShort) {
// Если содержимое слишком короткое,
// отображаем следующее сообщение об ошибке
emailError.textContent = `Email should be at least ${ email.minLength } characters; you entered ${ email.value.length }.`;
}
// Задаём соответствующую стилизацию
emailError.className = 'error active';
}
Комментарии объясняют логику хорошо, но кратко:
- При каждом изменении значения поля, мы производим его валидацию. Если данные валидны, удаляем ранее отображаемые сообщения об ошибках. Если данные не валдны, запускаем
showError()
, чтобы показать соответствующую ошибку. - При каждой попытке отправить форму, мы снова производим валидацию. Если данные валидны, позволяем отправку формы. Если данные не валидны, запускам
showError()
, чтобы показать соответствующее сообщение об ошибке, а также предотвращаем отправку формы с помощьюpreventDefault()
. - Функция
showError()
использует различные свойства объектаvalidity
поля ввода, чтобы определить тип ошибки и отобразить соответсвущее сообщение.
Рабочий пример:
Constraint Validation API явяется мощным инструментом валидации форм, позволяющим получить контроль над пользовательским интерфейсом, существенно превосходящий возможности HTML и CSS.
Проверка форм без встроенного API
В некоторых случаях, например, при необходимости поддержки устаревших браузеров или кастомных элементов формы, вы не сможете или не захотите использовать Constraint Validation API. Вы по-прежнему сможете использовать JavaScript для валидации форм, но для этого всё нужно будет писать самостоятельно.
Для создания своего валидатора формы, задайте себе несколько вопросов:
- Какую тип валидации я должен выполнить?
-
Вам нужно определить, как данные будут валидироваться: с помощью строковых операций, преобразования типов, регулярных выражений и так далее. Решать вам.
- Что мне нужно делать, если форма не проходит валидацию?
-
Это явно вопрос пользовательского интерфейса. Вы должны решить, как в этом случае будет себя вести форма. Будет ли она в любом случае отправлять данные? Нужно ли выделять поля, содержащие ошибки? Нужно ли отображать сообщения об ошибках?
- Как я могу помочь пользователю исправить не валидные данные?
-
Чтобы снизить степень разочарования пользователя, очень важно предоставить как можно больше полезной информации, чтобы помочь исправить данные, которые он ввёл неправильно. Нужно предложить правильные варианты, чтобы дать понять, какие данные вы ожидаете от него получить, а также сообщение, чётко описывающее ошибку. Если вы хотите подробнее ознакомиться с требованиями к пользовательскому интрефейсу при валидации форм, предлагаем прочитать следующие статьи:
- SmashingMagazine: Form-Field Validation: The Errors-Only Approach
- SmashingMagazine: Web Form Validation: Best Practices and Tutorials
- WebFX: 10 Tips for Optimizing Web Form Submission Usability
- A List Apart: Inline Validation in Web Forms
Пример без использования Constraint Validation API
Чтобы проиллюстрировать это дальше приводится упрощённая версия предыдущего примера, которая работает с устаревшими браузерами.
HTML почти тот такой же; мы только удалили функционал валидации HTML5.
<form>
<p>
<label for="mail">
<span>Please enter an email address:</span>
<input type="text" id="mail" name="mail">
<span class="error" aria-live="polite"></span>
</label>
</p>
<!-- Для некоторых устаревших браузеров элементу `button` нужно добавлять
атрибут `type` с явно заданным значением `submit` -->
<button type="submit">Submit</button>
</form>
CSS также не требует особых изменений; мы только заменили CSS-псевдокласс :invalid
на реальный класс и не использовали селектор по атрибутам, так как он не работает в Internet Explorer 6.
body {
font: 1em sans-serif;
width: 200px;
padding: 0;
margin : 0 auto;
}
form {
max-width: 200px;
}
p * {
display: block;
}
input.mail {
-webkit-appearance: none;
width: 100%;
border: 1px solid #333;
margin: 0;
font-family: inherit;
font-size: 90%;
box-sizing: border-box;
}
/* Стилизация не валидных полей */
input.invalid{
border-color: #900;
background-color: #FDD;
}
input:focus.invalid {
outline: none;
}
/* Стилизация сообщений об ошибках */
.error {
width : 100%;
padding: 0;
font-size: 80%;
color: white;
background-color: #900;
border-radius: 0 0 5px 5px;
box-sizing: border-box;
}
.error.active {
padding: 0.3em;
}
Существенно изменился только JavaScript-код, который теперь должен выполнять гораздо больше работы.
// Устаревшие браузеры поддерживают несколько способов получения DOM-узла
const form = document.getElementsByTagName('form')[0];
const email = document.getElementById('mail');
// Ниже приведён способ получения узла следующего родственного DOM-элемента
// Он опасен, потому что можно создать бесконечный цикл.
// В современных браузерах лучше использовать `element.nextElementSibling`
let error = email;
while ((error = error.nextSibling).nodeType != 1);
// Согласно спецификации HTML5
const emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$/;
// Многие устаревшие браузеры не поддерживают метод `addEventListener`
// Есть простой способ заменить его; и далеко не единственный
function addEvent(element, event, callback) {
let previousEventCallBack = element["on"+event];
element["on"+event] = function (e) {
let output = callback(e);
// Колбэк, который возвращает `false`, останавливает цепочку колбэков
// и прерывает выполнение колбэка события
if (output === false) return false;
if (typeof previousEventCallBack === 'function') {
output = previousEventCallBack(e);
if(output === false) return false;
}
};
}
// Теперь мы можем изменить наши критерии валидации
// Поскольку мы не полагаемся на CSS-псевдокласс, для поля email
// нужно явно задать валидный / не валидный класс
addEvent(window, "load", function () {
// Проверка, является ли поле пустым (помните, оно не являтеся обязательным)
// Если поле не пустое, проверяем содержимое на соответствует шаблону email
const test = email.value.length === 0 || emailRegExp.test(email.value);
email.className = test ? "valid" : "invalid";
});
// Здесь определяется поведение при вводе пользователем значения поля
addEvent(email, "input", function () {
const test = email.value.length === 0 || emailRegExp.test(email.value);
if (test) {
email.className = "valid";
error.textContent = "";
error.className = "error";
} else {
email.className = "invalid";
}
});
// Здесь определяется поведение при попытке отправить данные
addEvent(form, "submit", function () {
const test = email.value.length === 0 || emailRegExp.test(email.value);
if (!test) {
email.className = "invalid";
error.textContent = "I expect an e-mail, darling!";
error.className = "error active";
// Некоторые устаревшие браузеры не поддерживают метод event.preventDefault()
return false;
} else {
email.className = "valid";
error.textContent = "";
error.className = "error";
}
});
Результат выглядит следующим образом:
Как вы можете видеть, сделать собственную валидацию не так уж и сложно. Сложность состоит лишь в том, чтобы сделать его кроссплатформенным и работающим с любой формой, которую можно создать. Для проверки формы доступно множество библиотек, например Validate.js.
Проверьте свои навыки!
Вы дошли до конца этой статьи, но можете ли вы вспомнить самую важную информацию? Вы можете найти дополнительные тесты, чтобы убедиться, что вы сохранили эту информацию, прежде чем двигаться дальше — Test your skills: Form validation (en-US).
Заключение
Для проверки формы на стороне клиента иногда требуется JavaScript, если вы хотите настроить стилизацию и сообщения об ошибках, но это всегда требует от вас внимательного отношения к пользователю. Всегда помните о необходимости помогать пользователям исправлять данные, которые они вводят. Для этого обязательно нужно:
- Отображать явные сообщения об ошибках.
- Снисходительно относиться к формату ввода.
- Указывать, где именно возникла ошибка. Особенно в больших формах.
После того, как вы убедились, что форма заполнена правильно, ее можно отправлять. Дальше мы рассмотрим отправку данных формы.
- Назад (en-US)
- Обзор: Forms
- Далее
In this module
Продвинутые темы
От автора: в этой серии статей я буду излагать свои мысли после тщательного изучения современной валидации форм в CSS и JS. Я расскажу про нативные сообщения в HTML-валидации, CSS псевдоклассы :invalid и :valid, а также про Constraint Validation API, которое должно было упростить валидацию форм, но получилось слегка иначе.
В этой статье мы попробуем провести валидацию формы в стиле user-friendly с помощью нативных возможностей HTML, CSS и JS и написания пары небольших скриптов для вытягивания якобы простых строк в Constraint Validation API.
У нас ничего не получится. Мы поймем, что в дизайне были допущены серьезные ошибки, и что не просто так веб-разработчики не используют ни одну из этих техник. Современная валидация форм страдает от следующих проблем:
Между спецификациями HTML, CSS и JS нет четкой связи. Иногда они работают в совершенно разных целях.
Не существует декларативного способа вставки сообщений об ошибках в отдельные поля формы. (есть JS-способ, но он плохо спроектирован)
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее
Сообщения HTML-валидации невозможно стилизовать, а их отвратительное и непостоянное поведение невозможно изменить. Можно только работать с командами show и hide, которые совсем не похожи не отображение и скрытие.
Псевдоклассы CSS – отличная штука, но когда вы начинаете их использовать, все становится не так гладко. Также все способы вставки сообщений об ошибках на псевдоклассах довольно сложные.
Эти проблемы кажутся еще более странными, когда узнаешь, что валидация форм буквально самый старый трюк в JS: когда JS был представлен в Netscape 2, он только и умел делать валидацию форм. У нас было 20 лет, чтобы все исправить, но все осталось как есть.
В своих статьях я обычно расплывчато говорю о совместимости с браузерами, так как вся информация представлена в таблице совместимости. Там можно все подробно посмотреть.
И прежде чем мы начнем еще кое-что: всегда помимо клиентской проверки делайте валидацию не сервере. Если скрипты поломаются, а фолбека под рукой не будет, может случиться что-то очень нехорошее.
И еще кое-что. Огромное спасибо Stéphanie Walter и Geoffrey Crofte за их крайне полезные комментарии к черновику этой статьи.
UI валидации полей формы
Прежде чем окунуться с головой в API и псевдоклассы, мы должны понять, чего хотим добиться. В теории все просто: мы хотим предложить пользователю хороший UX, т.е. понятные и короткие сообщения об ошибках в правильное время в правильном месте.
onsubmit, т.е. когда пользователь пытается отправить форму;
onblur, т.е. когда пользователь переходит на другое поле формы;
onkeypress, т.е. когда пользователь меняет значение поля формы (это может происходить по 10 или 12 раз, прежде чем пользователь перейдет к следующему полю).
Какой сценарий лучше? Christian Holst подробно рассматривает UI и customer experience валидации форм. Его главные советы заключается в том, что сообщения об ошибках необходимо показывать рядом с полями, в которых они возникают. Сообщения необходимо показывать сразу, как только пользователь заполнил поля. Другими словами, лучше всего по событию onblur.
Luke Wroblewski соглашается с такими утверждениями и добавляет замечание, что пользователям лучше постоянно показывать сообщения, а не так, чтобы они со временем пропадали. (Угадайте, как все браузеры показывают сообщения за исключением Firefox на Android?) Это же относится и к сообщениям о положительной проверке.
(Luke также протестировал четвертый вариант: focus + keypress. Сообщения показываются, когда пользователь вводит текст в поле формы. Его тесты убедительно показали, что это плохая идея)
Adrian Roselli также говорит: сообщения об ошибках следует показывать над полем формы, а не снизу, так как на маленьких экранах мобильных устройств сообщения под полем могут закрываться экранной клавиатурой или другими UI-элементами.
Есть и контраргумент – пользователи привыкли к тому, что сообщения об ошибках показываются рядом с полем или под ним. Ширины экрана мобильного устройства может не хватить для показа сообщения рядом с полем, поэтому такое расположение крайне нежелательно. Если разместить сообщение снизу, такой проблемы не возникнет.
Что лучше, решайте сами. Но я замечу, что почти все браузеры размещают сообщения об ошибках под полем формы, хотя некоторые мобильные браузеры нарушают это правило.
С размещением сообщения об ошибке не все так ясно, но появляться оно должно по событию onblur, т.е. когда пользователь дает понять, что он заполнил поле и переходит на следующее. Также должен быть легкий способ добавления своих сообщений об ошибке к отдельным полям формы.
CSS, API и браузеры не выполняют эти простые правила. Невозможно добавить сообщения об ошибках простым декларативным методом. Constraint Validation API основано на событии onsubmit, а CSS :invalid и :valid на событии onkeypress.
Валидация форм на чистом CSS
Валидация форм на чистом CSS работает на псевдоклассах :invalid и :valid. (Есть и другие псевдоклассы типа out-of-range, но мы опустим их, так как их принцип работы точно такой же, и это более частные случаи invalid)
Поиграться с псевдоклассами можете в первом примере на тестовой странице. Валидация перезапускается при каждом нажатии клавиш. Не самый красивый способ и, возможно, запутанный. Пользователю не нужно знать о состоянии введенного значения на каждом этапе: нужно одно четкое сообщение, когда поле будет заполнено целиком. (Пользователь пока не видит сообщения об ошибке. Чуть ниже мы к этому вернемся)
Вне фокуса
К счастью, перейти на onblur довольно легко. Потребуется задействовать немного сложный селектор (спасибо, Krijn, за этот трюк):
input:invalid:not(:focus) |
Смотрите второй пример на тестовой странице. Теперь невалидные и валидные стили видны только, когда поле вне фокуса, т.е. когда пользователь не вводит в него значение. Уже лучше.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее
Сообщения об ошибках на чистом CSS
Такие сообщения решают проблему тайминга, но не решают проблему показа самих сообщений. Теоретически решение будет следующим:
input:invalid:not(:focus):before { content: attr(data—error—message); } |
Показывайте контент невалидного атрибута data-error-message перед полем, если пользователь не печатает текст. Звучит хорошо, правда?
Увы, увы, но :before и :after нельзя использовать на замененных элементах типа input.
Это нужно исправить. :before и :after не заточены под замененные элементы, однако в Chrome и Safari они работают с диапазонами, чекбоксами и радиокнопками. В Chrome Safari/iOS, но не в Safari/Mac они также работают с полями типа date. (Почему именно эти типы? Я не знаю. Возможно, парочка разработчиков браузеров были пьяны)
Это не работает. Нужно передвинуть сообщение об ошибке за пределы поля. Что-то типа:
span.errorMessage { display: none; } input:invalid:not(:focus) + span.errorMessage { display: block; } |
Это работает, но сложность объявления сообщений сбивает с толку. Вы можете сказать, что сообщения не относятся к CSS, но, как мы позже увидим, их нет и в HTML и JS. Это фундаментальная проблема спецификация на данный момент.
Проблема с required
Нам может показаться, что мы прошли достойный путь, и валидация на чистом CSS у нас в руках, но все разваливается, когда необходимо учесть обязательные поля формы. Пустые обязательные поля считаются невалидными.
Смотрите псевдоклассы в третьем примере на тестовой странице. Проблема заключается в том, что поле становится невалидным сразу после загрузки страницы. Говорить пользователю, что он ошибся, даже не дав ему возможность взаимодействия с формой – плохой UX.
Можете использовать решение Krijn (добавить текст в плейсхолдер в виде одного пробела!), но тогда придется использовать псевдокласс :placeholder-shown.
:not(:focus):not(:placeholder—shown):invalid |
Вам еще не смешно? Мы же не просим какой-то скрытый функционал, который нужен только для пары полей. Нам лишь нужно подождать сигнала от пользователя, что он готов, прежде чем проверять поле на валидность.
Другими словами, валидация на чистом CSS вам не подойдет, если у вас есть обязательные поля. А так как почти каждая форма имеет минимум пару обязательных полей, CSS валидация – не вариант.
:user-invalid и :user-error
Эта проблема признана всеми, кто работает с CSS. Решение – сделать в форме псевдоклассы :user-invalid (W3C) или :user-error (WHATWG). Оба значат «поле невалидно после взаимодействия с пользователем». Эти псевдоклассы решили бы большую часть описанных выше проблем.
В настоящее время оба псевдокласса не поддерживаются, но в будущем они будут реализованы и продвинут валидацию в CSS еще дальше. Тем не менее, проблема нативной и простой системы сообщений об ошибках никуда не девается.
:valid и :invalid на других элементах
Мало кто знает, но :invalid и :valid работают не только на input. Эти псевдоклассы можно использовать на fieldset и form. :invalid срабатывает, если fieldset или form содержит минимум одно невалидное поле.
Еще круче, fieldset поддерживает :before и :after. Эта техника может пригодиться:
fieldset:invalid { border—color: red; } fieldset:invalid:before { content: attr(data—error—message); } |
К сожалению, она не поддерживается в Edge и парочке старых мобильных браузеров.
И если fieldset и form могут быть невалидными, если внутри них есть хотя бы одно невалидное поле, то почему лейблы с невалидными полями не могут быть невалидными? Ну, потому что не могут. Браузеры не поддерживают такой функционал. Мы не можем иметь что-то хорошее, потому что тогда все будет хорошо. Поэтому такой функционал и не поддерживается.
Так завершается часть 1. В следующей статье (скоро) мы поговорим о парочке опций HTML и JS API.
Автор: Peter-Paul Koch
Источник: //medium.com/
Редакция: Команда webformyself.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее
PSD to HTML
Практика верстки сайта на CSS Grid с нуля
Смотреть
Любая система допускает ошибки. Это может быть как человеческий фактор, так и ошибка самой системы. В обоих случаях, нужно правильно эти ошибки отображать, так как они являются очень важным элементом пользовательского опыта.
Вот 3 жизненно важных части любого хорошего сообщения об ошибке:
- Четкое текстовое сообщение
- Правильное размещение
- Хороший визуальный дизайн
Четкое текстовое сообщение
1. Сообщение об ошибке должно быть понятным
Сообщение об ошибке должно четко говорить о том, какая именно ошибка произошла, почему она произошла, и что с этим делать. Думайте об этом сообщении, как об общении с пользователем — оно должно звучать так, будто оно написано для человека, а не для машины. Убедитесь, что ваше сообщение вежливо, понятно, дружественно, и не содержит жаргона.
2. Сообщение об ошибке должно быть полезным
Не достаточно просто написать, что что-то пошло не так. Покажите пользователю, как он может исправить проблему.
Например, Microsoft описывает проблему, и прямо в сообщении об ошибке предоставляет вариант ее решения.
3. Сообщение об ошибке должно подходить под определенную ситуацию
Очень часто, веб-сайты используют одно сообщение об ошибке для всех схожих состояний. Оставили пустым поле ввода электронного адреса — «Введите правильный электронный адрес», пропустили символ «@» — «Введите правильный электронный адрес». MailChimp решает эту проблему иначе — они используют 3 разных сообщения об ошибке для каждого состояния процесса подтверждения электронной почты. Сначала проверяется, заполнено ли поле ввода. Затем проверяется введены ли символы «@», и «.».
4. Сообщение об ошибке должно быть вежливым
Не вините пользователей в том, что они что-то не так сделали, даже если это так. Будьте вежливы, дайте им почувствовать себя комфортно.
5. Используйте юмор, если он уместен
Но будьте осторожны. Сообщение об ошибке, в первую очередь, должно быть информативным и полезным. И уже затем, можете улучшить пользовательский опыт, добавив немного юмора, но только если он уместен.
Правильное размещение
Хорошее сообщение об ошибке — это такое сообщение, которое вы увидите. Размещайте его рядом с элементами интерфейса, с которыми ошибка непосредственно связана.
Правильный визуальный дизайн
Сообщение об ошибке должно быть заметным. Используйте контрастный текст и фоновые цвета, чтобы пользователь мог легко его рассмотреть и прочесть.
Обычно, используется красный цвет. В некоторых случаях желтый или оранжевый (некоторые ресурсы утверждают, что красный цвет нервирует пользователей). Как бы то ни было, убедитесь, что ваш текст разборчив, и хорошо контрастирует с фоном. Не забудьте внедрить в сообщение связанную с ним иконку — это улучшит доступность сообщения для людей с нарушенным восприятием цветов.
Заключение
Сообщения об ошибках — это отличный способ улучшить пользовательский опыт. Чтобы ваше сообщение стало действительно идеальным, уделите внимание всем аспектам — языку, размещению, и визуальному дизайну.
Предыдущая статья
F-паттерн: как пользователи просматривают контент
Следующая статья
Метрики, за которыми должен следить любой SEO аналитик