Дай нажать
Это такой принцип в интерфейсе — называется «дай нажать».
Приведу три примера.
Группа чекбоксов с одним обязательным
В сегодняшнем совете был пример, когда у пользователя есть несколько независимых чекбоксов, из которых хотя бы один обязательно должен быть включён:
То есть нужно, чтобы человек выбрал уведомление хотя бы одним каким-то способом, но может накликать и несколько.
Среди вариантов реализации, предложенных автором вопроса, есть такой: чтобы не допустить «пустого» набора, когда остаётся только один включенный чекбокс, его уже не дают выключить:
Это плохое решение: я могу захотеть сначала отключить неподходящий вариант, а потом включить подходящий. Блокировка заставляет меня совершать действия в определённом порядке. Причём это ещё и неочевидно: если у меня останется последней определённая опция, скажем, «в чате», и она заблокируется, то это будет выглядеть так, будто уведомление в чате подключать обязательно, а это неправда. Я хочу его выключить, но интерфейс не даёт мне нажать туда, куда я хочу.
Лучше так: при отключении последнего чекбокса, сразу включать какой-то дефолтный, скажем, «письмом». А если я его отключил последним, то включать второй по предпочтительности, скажем, «по телефону». Так интерфейс не будет мне мешать нажимать куда я хочу, но и не даст оставить недопустимое состояние.
Чекбокс и поле
В настройке комментариев в Эгее есть чекбокс «присылать по почте», которому подчинено поле адреса:
Если чекбокс не включён, заполнять поле нет смысла: адрес ни для чего другого не нужен. Если чекбокс включён, а адрес не заполнен, то движок не сможет ничего присылать, потому что не знает адрес. Короче, эти элементы взаимосвязаны.
Можно было бы блокировать поле пока чекбокс выключен — всё равно заполнять его нет смысла. Но это бесит. Может, я хочу заполнить адрес, а потом включить чекбокс? Ещё хуже было бы не давать выключить чекбокс, если адрес заполнен. Я же хочу выключить, дай нажать!
Лучше так: давать заполнить поле, даже если чекбокс выключен; включать чекбокс автоматически, как только в поле что-то вписали. В обратную сторону — аккуратнее: если чекбокс сняли, стирать адрес из поля не надо, мало ли. Пользовательские данные обладают бесконечной ценностью.
Выбор даты
Вот возможный вариант реализации выбора даты рождения в интерфейсе:
Как вы знаете, некоторых дней не существует в природе, например не бывает 31 июня. А 29 февраля в некоторые годы бывает, а в некоторые — нет.
Чтобы не дать пользователю ввести несуществующую дату, некоторые разработчики убирают из поля дня несуществующие дни. То есть если выбран месяц июнь, то дня «31» просто не будет в выпадайке. Но что, если у меня день рождения 31 августа? Я хочу ткнуть в 31, а потом выбрать август. Дай нажать!
Бывает обратная проблема: разработчики дают выбрать несуществующую дату, но выводят сообщение об ошибке, когда она выбрана. Это тоже отстой: хорошая форма не засыпает пользователя сообщениями об ошибках, а деликатно помогает их не допустить.
Лучше так: при вводе дня, несовместимого с текущим выбранным месяцем, развыбирать месяц —
Если я выбрал 29 февраля, а выбранном году такого нет, развыбирать год.
Отчасти похожая мысль — кнопка «Купить» всегда доступна.
Писал когда-то про похожую штуку — временное невалидное состояние: https://t.me/sb_works/23
Этот принцип — расширение принципа о «ценности пользовательских данных» в том смысле, что ты не просто ценишь то, что пользователь _сумел ввести_, но и то, что пользователь _захотел ввести_, позволяя ему это сделать. Другой пример — интерактивные анимации переключения приложений в десятом айфоне: твоя рука хочет болтать окном как попало, а не просто переключать его между несколькими дозволенными положениями, поэтому ей нужно позволить это делать.
Продолжу мысль.
Интерфейс — это диалог между пользователем и некой системой. Как в любом диалоге, важно выслушать обе стороны. Поэтому хороший интерфейс не навязывает видение задачи с точки зрения системы, заставляя пользователя говорить на ее языке, а позволяет пользователю высказаться на своем языке (принимая и сохраняя его высказывание), отдельным шагом переводя язык пользователя на язык системы.
Еще пример: в гугл можно ввести все, что угодно. Если какое-то слово не найдено, гугл просто вычеркнет его из поиска, предложив что-то менее подходящее. А если он увидит опечатку, предложит варианты для исправленного запроса. Т. е. пользователь можно сделать запрос на своем языке, а гугл попробует перевести на свой и предложит свою точку зрения в ответ.
Кнопка «купить» которая «всегда доступна» — это то же самое «высказывание пользователя» которое не нужно затыкать потому что система там в каком-то не том состоянии.
Насчёт чекбокса и поля: зачем вообще нужен чекбокс? Не может ли его роль выполнять сам факт наличия валидного емейла в поле?
Чтобы можно было включить-выключить не стирая/переписывая адрес.
Кажется, в примере с группой чекбоксов одно плохое решение заменяется другим.
Неотключаемый последний чекбокс вводит в заблуждение и навязывает алгоритм действий.
Самовключающиеся чекбоксы делают интерфейс просто непредсказуемым: отключаешь один вариант и включается другой. Как в игре-головоломке, где надо нажать кнопки в определённом порядке, чтобы выключить все.
Думаю, лучше дать выключить все чекбоксы и где-то рядом показать сообщение «Нужно выбрать хотя бы один вариант для оформления заказа». Некрасиво, но предсказуемо. Дарит чувство контроля над интерфейсом.
Ситуация с выбором сначала 31, а потом августа понятная, так и надо. Но развыбирать месяц или год, как советует Илья, на мой взгляд, — плохое решение. Но если выбрал 31, а потом месяц, где 30 дней, надо просто менять число на 30.
Скорее скрин был вырван из контекста, в котором несколько чекбоксов. При одном смысл есть далеко не всегда.
Как быть с выбором даты рождения в айфоне, где барабаны без пустого значения? Вводить пустое значение — придётся обрабатывать ошибку на пустоту до закрытия барабана.
Не знаю, автоматом перекатываться на следующий месяц, где есть 31-е число?
В айфоне барабан откатывает на 30, если выбрать 31 в апреле, например. Или если 31 есть в мае, а выбрать апрель, то тоже откатит.