Проверка наличия пустого ввода с помощью CSS
Можно ли узнать, пуст ли ввод только с помощью CSS?
У меня возник этот вопрос, когда я пытался создать компонент автозаполнения для Learn JavaScript. В общем, я хотел:
- Скрыть раскрывающийся список, если ввод пуст
- Показать раскрывающийся список, если ввод заполнен
Я нашел способ сделать это. Это не идеально. Есть несколько нюансов, но я хочу поделиться ими с вами.
Форма
Во-первых, давайте создадим форму, чтобы мы были на одной странице. Мы собираемся использовать простую форму с одним входом.
<form>
<label for="input"> Input </label>
<input type="text" id="input" />
</form>
Когда ввод заполнен, мы хотим изменить его border-color
до зеленого. Вот пример того, что мы создаем:
Проверка, если ввод пуст
Я полагался на проверку формы HTML, чтобы проверить, является ли ввод пустым. Это означало, что мне нужен required
атрибут.
<form>
<label> Input </label>
<input type="text" name="input" id="input" required />
</form>
На данный момент он отлично работает, когда ввод заполнен. Границы стали зелеными.
Но есть проблема: если пользователь вводит в поле пробел, границы также становятся зелеными.
Технически это правильно. Ввод заполнен, потому что пользователь что-то ввел в него.
Но я не хотел, чтобы пробелы вызывали пустое выпадающее меню (для компонента автозаполнения).
Этого было недостаточно. Мне нужна более строгая проверка.
Дальнейшие проверки
HTML дает вам возможность проверять ввод с помощью регулярных выражений с помощью pattern
атрибут. Я решил проверить это.
Так как я не хотел, чтобы пробелы распознавались, я начал с \S+
шаблон. Этот шаблон означал: один или несколько символов, не являющихся пробелами.
<form>
<label> Input </label>
<input type="text" name="input" id="input" required pattern="\S+"/>
</form>
Конечно же, это сработало. Если пользователь вводит пробел в поле, ввод не проверяется.
Но когда во ввод вводится пробел (где угодно), ввод становится недействительным.
К сожалению, этот шаблон не работал в моем случае использования.
В компоненте автозаполнения Learn JavaScript я научил студентов, как заполнять список стран. В названиях некоторых стран были пробелы…
Мне пришлось включить пробелы в микс.
Следующая лучшая альтернатива, о которой я мог подумать, это \S+.*
. Это означает 1 или более непробельных символов, за которыми следует ноль или более (любых) символов.
<form>
<label> Input </label>
<input type="text" name="input" id="input" required pattern="\S+.*"/>
</form>
Это сработало! Теперь я могу вводить пробелы в микс!
Но есть еще одна проблема… ввод не проходит проверку, если вы НАЧАЛИ с пробела…
И это проблема, которую я не мог решить. Подробнее об этом позже.
Когда я работал над этой статьей, я столкнулся с еще одним интересным вопросом: можно ли стилизовать недопустимое состояние при неправильном заполнении ввода?
Аннулирование ввода
мы не хотим использовать :invalid
потому что мы запустим ввод с недопустимым состоянием. (Когда ввод пуст, он уже недействителен).
Именно здесь Крис Койер спешил на помощь со своей « Проверка формы UX в HTML и CSS«.
В статье Крис рассказывает о :placeholder-shown
псевдокласс. Его можно использовать для проверки того, отображается ли заполнитель.
Идея такова:
- Вы добавляете заполнитель к вашему вводу
- Если ввод скрыт, это означает, что пользователь что-то ввел в поле.
- Приступить к проверке (или аннулированию)
Вот CSS (упрощенная версия. Полную версию см. статья Криса)
/* Show red borders when filled, but invalid */
input:not(:placeholder-shown) {
border-color: hsl(0, 76%, 50%);
}
Поскольку у меня были как стили проверки, так и стили недействительности, я должен был убедиться, что действительные стили идут после недопустимых стилей.
/* Show red borders when filled, but invalid */
input:not(:placeholder-shown) {
border-color: hsl(0, 76%, 50%);
}
/* Show green borders when valid */
input:valid {
border-color: hsl(120, 76%, 50%);
}
Вот демо для вас, чтобы играть с:
См. перо Чистая проверка CSS Пустая проверка Зелл Лью (@zellwk) на КодПен.
Примечание. Edge не поддерживает :placeholder-shown
, так что, вероятно, пока не рекомендуется использовать его в производстве. Нет хорошего способа обнаружить эту функцию.
Теперь вернемся к проблеме, которую я не смог решить.
Проблема с узором
pattern
атрибут замечательный, потому что он позволяет принимать регулярное выражение. Это регулярное выражение позволяет вам проверить ввод с помощью всего, что вы можете придумать.
Но… регулярное выражение должно полностью соответствовать тексту. Если текст не совпадает полностью, ввод становится недействительным.
Это создало проблему, о которой я упоминал выше. (Напоминание о проблеме: если пользователь сначала вводит пробел, ввод становится недействительным).
Я не смог найти регулярное выражение, которое работало бы для всех вариантов использования, о которых я думал. Если вы хотите попробовать свои силы в создании регулярного выражения, которое мне нужно, я буду более чем рад получить помощь!
Вот варианты использования:
// Should not match
''
' '
' '
' '
// Should match
'one-word'
'one-word '
' one-word'
' one-word '
'one phrase with whitespace'
'one phrase with whitespace '
' one phrase with whitespace'
' one phrase with whitespace '
(Опять же, я мог бы слишком много думать об этом… 🙄).
Обновление: Проблема решена!
Многие читатели были достаточно щедры, чтобы отправить мне по электронной почте свои решения. Я хочу поблагодарить всех, кто помог. Большое спасибо!
Самое чистое решение, которое я получил: .*\S.*
по Дэниел О’Коннор. Это означает:
.*
: любой символ\S
: подписано один непробельный символ.*
: За ним следует любой символ
Другие регулярные выражения, которые я получил, включают:
И многие другие!
Вот кодовая ручка с обновленным решением Даниэля.
Подведение итогов
Да, можно проверить форму с помощью чистого CSS, но есть потенциальные проблемы с проверкой, когда задействованы пробельные символы.
Если вы не возражаете против пробелов, это работает отлично. Получайте удовольствие, пробуя этот образец! (Извините, я не могу помочь).
Спасибо за чтение. Эта статья изначально была размещена на мой блог. Подписаться на моя рассылка если вы хотите больше статей, которые помогут вам стать лучшим разработчиком внешнего интерфейса.