Xiper

Текст в поле type="password"

Автор: Евгений Рыжков Дата публикации:

Скорей всего уже встречал на сайтах формы входа, у которых поля (логин / пароль) подписаны значениями в самих полях. И при этом, в поле ввода пароля сам пароль набирается скрытым текстом (звездочками).

надпись пароль в поле пароль у Яндекса
надпись пароль в поле пароль у Яндекса

Такой вид формы обычно делают для экономии места на странице.

Задача

Реализовать данную форму с учетом требований:

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

Решение

Поможет нам в этом javascript. Алгоритм приема:

  1. надписи логин и пароль делаем не в полях(<input>), а с помощью <label> — это сохранит код логически правильным (семантичным). К тому же, такой шаг сделает код понятным для программиста, т.к. не придется динамически менять тип поля (или создавать новый html-элемент)*
  2. метки (<label>) абсолютным позиционированием (position: absolute) размещаем над полями логин и пароль
  3. при получении фокуса полем (событие onfocus), удаляем текст в <label>, который над этим полем
  4. для совместимости с запоминалками паролей, при загрузке страницы анализируем значение полей, если они не пусты, удаляем текст в <label>
<form action="#">
    <fieldset>
    <legend>Форма входа</legend>
    <div>
        <label for="loginEnterToSite" class="labelLogin">логин</label>
        <input name="login" value="" id="loginEnterToSite" type="text" />
    </div>
    <div>
        <label for="passwordEnterToSite" class="labelPass">пароль</label>
        <input name="pass" value="" id="passwordEnterToSite" type="password" />
    </div>
    <div>
        <input value="Войти" type="submit" />
        </div>
    </fieldset>
</form>

Заметка: обрати внимание на использование атрибута for для <label>, который при клике по метке переводит фокус на элемент, id которого указано в for. Без этого атрибута в скрипт пришлось бы добавлять в ручную перевод фокуса в поле.

form div {
margin: 5px 20px 5px 20px;
position: relative;
}
fieldset {
border: 1px solid #0066CC;
}
label {
position: absolute;
top: 3px;
left: 6px;
color: #999999;
}
input {
margin-right: 10px;
width: 150px;
}

Привожу пример ,с использованием фреймворка jQuery, т.к. последнее время работою только с ним. По примеру уверен не составит труда подкорректировать скрипт под другой фреймворк или под чистый javascript, т.к. алгоритм очень простой.

$(document).ready(function(){
/*
    при загрузке страницы проверям заполненность полей (на случай если запоминалка паролей вставила уже значения)
    если значения вставлены, удаляем текст у label для логина и пароля
*/
if($("#loginEnterToSite").val()!='')
{
    $("#loginEnterToSite").prev().text('');
    $("#passwordEnterToSite").prev().text('');
}
/*
    тут привязано одно событие на получение фокуса полю в форме
*/
$("div > input").focus(
function(e)
{
    var clicked = $(e.target),
    clickedId = clicked.attr("id");
    /*
        если поле логин получило фокус, удаляем текст в label для логин
    */
    if(clickedId=="loginEnterToSite")
    {
         clicked.prev().text('');
    }
    /*
        если поле пароль получило фокус, удаляем текст в label для пароль
    */
    else if(clickedId=="passwordEnterToSite")
    {
         clicked.prev().text('');
     }
});
/*
    тут привязано одно событие на потерю фокуса полем в форме
*/
$("div > input").blur(
function(e)
{
    var clicked = $(e.target),
    clickedId = clicked.attr("id");
    /*
        если ушли из поля логин и его значение пусто, добавляем текст в label для логин
    */
    if(clickedId=="loginEnterToSite")
    {
        if(clicked.val()=='') clicked.prev().text('логин');
    }
    /*
        если ушли из поля пароль и его значение пусто, добавляем текст в label для пароль
    */
    else if(clickedId=="passwordEnterToSite")
    {
        if(clicked.val()=='') clicked.prev().text('пароль');
    }
});
});

Смотреть результат. Проверено в:

Недостаток этого приема — использование javascript.

* — существует еще ряд приемов реализации данной задачи:

  1. динамическое создание поля type="password"
  2. использование фоновых рисунков

Динамическое создание поля type="password"

Изначально в форму вставляем два текстовых поля (type="text"), значение (value) им присваиваем логин / пароль. Таким образом у нас получаются подписи в полях. При получении фокуса полем очищаем значение поля, а если это к тому же поле для пароля, текущий <input> удаляем из DOM и вставляем вместо него <input type="password". Недостатки данного метода:

  • нарушенная семантика кода
  • более сложный скрипт
  • недоумение программиста, который изначально видит в верстке поле type="text" там, где должно быть type="password"

Использование фоновых изображений

Принцип аналогичный принципу с использованием меток, отличие заключается, что вместо <label> используется фоновое изображение для полей (<input>). При получении фокуса убирается картинка из background'а. Скрипт практический идентичный вышеприведенному. Недостатки:

  • дополнительная картинка / картинки (что уменьшает скорость загрузки страницы)
  • менее гибко (чтобы изменить, например, первую букву с маленькой на заглавную, придется изменить в макете, вырезать заново, возможно корректировать CSS)
  • возможны некоторые отличия шрифтов (на картинке будет тот что в макете, а браузере тот, что есть в ОС)

По теме