Mobile + input[type="date"] + placeholder
Попалась в одном проекте, рассчитанном только на мобильные устройства, форма с различными полями, у которых есть плейсхолдеры. Одно из полей — дата. Конечно же, захотелось сделать это поле <input type="date">
, чтобы и нативные дейтпикеры вызывались на устройствах, и не использовать какие бы то ни было плагины, регулярные выражения и пр. Но проблема в плейсхолдере, который для данного инпута не работает.
В процессе поиска было найдено несколько решений, но все они не подходили по разным причинам, работали не так, как надо. В итоге, методом проб и ошибок сделал свой вариант.
Все поля имели обёртку, и разметка выглядит примерно так:
<div class="field">
<input type="date">
</div>
Немного стилизуем, сбрасывая дефолтные стили:
.field input[type="date"] {
font-family: sans-serif;
font-size: 14px;
line-height: 20px;
box-sizing: border-box;
width: 100%;
padding: 9px;
color: #000;
border: 1px solid #000;
background: transparent;
-webkit-appearance: none;
}
В результате, в Хроме (десктопном) получили что-то вроде этого:

В мобильных устройствах этого «неизменяего плейсхолдера» (дд.мм.гггг) нет, лишь пустое поле.
Далее для обёртки создаётся псевдоэлемент, который и будет играть роль плейсхолдера:
.field {
position: relative;
background: #fff;
}
.field::before {
font-family: sans-serif;
font-size: 14px;
line-height: 20px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 10px;
content: "Введите дату";
color: #000;
}
То, что увидим на телефоне:

Теперь надо добавить немного JS-магии. При любом изменении инпута проверяем, чему равно value
. Если оно не является пустым, то задаём ему background: #fff
, что спрячет псевдоэлемент родителя. В противном же случае меняем фон на прозрачный.
Но для срабатывания этой логики необходимо, чтобы инпут был над псевдоэлементом, поэтому добавляем инпуту position
и z-index
.
Ниже рабочий пример, который фигово смотрится в обычных браузерах, но отлично работает как на Андроидах, так и на Айосе.
UPD: А можно сделать проще. Делаем два инпута с разными типами:
<div class="field">
<input type="text">
<input type="date">
</div>
Первому задаём необходимый плейсхолдер и абсолютное позиционирование. Второму же ставим нулевую непрозрачность.
Далее при фокусе по input[type="date"]
убираем прозрачность, а при необходимости (onblur
, oninput
) её возвращаем, проверяя value
. Событие onblur
нам нужно для мобильных, а oninput
для десктопных браузеров, т. к. там после очистки поля фокус сохраняется, и onblur
не срабатывает.
Получилось универсальнее, и на десктопе тоже работает.
P. S. А популярное решение с одним инпутом и сменой его типа при фокусе не является хорошим, поскольку на мобильных устройствах в данном случае не вызывается сразу нативный пикер, приходится делать повторный тап.
{{ 'Comments (%count%)' | trans {count:count} }}
{{ 'Comments are closed.' | trans }}