Нестандартные текстовые поля

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

Задача

Оформить нестандартно (по задумке дизайнера) текстовые поля форм (<input type="text" />). Например:
Пример нестандартного поля

Требования:

  • кроссбраузерность
  • простота применения
  • минимум дополнительных элементов
  • без использования javascript
  • соблюдение стандартов

Решение кажется простым — задать background полю:

input {
width: 164px;
height: 29px;
background: url(images/inpTask164.gif);
border: none;
}

Вроде бы все хорошо, до тех пор пока не попробуем ввести много текста в поле в IE6 или IE7:
Фон поля уехал

background-repeat: no-repeat — не помогает, фон все равно уезжает. Для IE6 помогает background-attachment: fixed. Но это не работает в IE7. Поэтому отказываемся от фона непосредственно для input.

Решение для полей фиксированного размера

Задаем фоновый рисунок обрамляющему блоку (div):

<div class="inp164"><input type="text" /></div>

CSS:

.inp164 { /* обрамляющий блок */
width: 164px;  /* размеры нашего красивого поля */
height: 29px;
background: url(images/inpTask164.gif); /* рисунок поля */
}
input {
padding: 5px 0 5px 12px; /* размещаем поле внутри так чтобы текст красиво вписывался */
border: none; /* убираем бордюр и background у input */
background: none;
width: 140px; /* реальная ширина поля */
height: 20px; /* чтобы поле вело себя предсказуемо в IE */
}

Результат. Осталось что-то сделать с подсветкой у полей в фокусе в Safari и Chrome:
Подсветка в Safari и Chrome несколько портит картину

Для этого добавим в наш CSS свойтво:

input:focus {
outline: none;
}

Результат.

Заметка

Позиционировать поле внутри контейнера лучше через свойство padding, таким образом, при клике по любой части нестандартного поля input получит фокус.

Решение для резиновых полей

При резиновой верстке разбиваем наш фоновый рисунок на две части: основной и правый угол. Основной фон делаем достаточно длинным, чтобы наверняка при масштабировании экрана хватило для поля. Получаем:
Основной фон поля — основной фон поля
Картинка для правого угла — картинка для правого угла. HTML:

<form>
    <div class="inpRezin"><input type="text" /><div class="rightCorner"></div></div>
</form>

CSS:

form {
width: 30%; /* Задаем ширину для формы */
}
.inpRezin { /* обрамляющий блок для поля */
height: 29px;
background: url(images/forms/inputRezin.png); /* длинная картинка в фоне */
width: 100%; /* ширина = ширине формы */
position: relative; /* чтоб внутри блока можно было использовать абсолютное позиционирование с относительными координатами */
}
input {
padding: 5px 0 5px 12px;
border: none;
background: none;
width: 95%; /* делаем поле немного короче родительского блока, оставляя место для правого угла */
height: 20px;
z-index: 1; /* явно задаем z-слой, чтобы правый угол мог перекрыть поле */
}
input:focus {
outline: none;
}
.rightCorner { /* правый угол поля */
width: 12px;
height: 29px;
background: url(images/forms/inputRight.png); /* изображение правого угла */
position: absolute; /* используем абсолютное позиционирование */
top: 0;
right: -1px; /* чтобы для ие6 не использовать expression для устранения смещения на 1px */
z-index: 2; /* z-слой выше, чем у поля */
}

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

Основной недостаток метода

Требуется дополнительный элемент документа — контейнер для поля.

Возможные проблемы

В IE8 в поле тяжело попасть, а иногда просто невозможно. Лечится это добавлением прозрачного (или другого, если возможно) фонового изображения:

input {
[...]
background: (/images/empty.gif); /* прозрачный однопиксельный рисунок */
[...]
}