Xiper

Кросбраузерные input и textarea

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

Задача

Задать оформление для полей input[type="text/password"] и textarea максимально одинаковое во всех популярных браузерах.

Теория

По умолчанию разные браузеры по разному отображают текстовые поля форм — различны:

  • внутренние отступы (padding), сброс отступов через универсальный селектор тут не помогает
  • шрифт (только для <textarea>) и его размер (хорошо видно в Safari)
  • горизонтальное выравнивание текста (текст не на одной горизонтальной линии) в полях и рядом стоящих элементах (например, <label>)
поля в FF 3.5
текстовые поля в ff 3.5
поля в IE 6
текстовые поля в ie 6
поля в Opera 9.6
текстовые поля в opera 9.6
поля в Safari 3.2
текстовые поля в safari 3.2

Разница становится заметней, когда привязываем необычное оформление полей.

Решение

Явно задаем для input[type="text"], input[type="password"] и textarea размер шрифта (font-size), внутренние отступы (padding). Для textarea так же указываем имя шрифта (font-family).
Заметка: для более предсказуемого поведения полей так же можно задать оформление границ (border), но это подпортит вид полей в некоторых браузерах (например, Opera поле станет прямоугольным, без скруглений углов) — используем при необходимости.

input[type="text"], input[type="password"] {
font-size: 100%;
padding: 0;
}
textarea {
font-size: 100%;
padding: 0;
font-family: arial;
}

Код для IE 6, который не понимает в CSS атрибуты (добавляем в ie6.css и подключаем к странице условными комментариями):

.formText {
font-size: 100%;
padding: 0;
}
input {
z-index: expression(
runtimeStyle.zIndex = 1,
type == "text" ? (className += " formText") : 0,
type == "password" ? (className += " formText") : 0
)
}

Update: Дополнительные проблемы могут возникнуть, если полю нужно указать высоту и/или верхний внутренний отступ (padding-top). Для примера сделаем поле, которое должно быть высотой 24px, шириной 200px и отступом от верхней границы 3px:

input {
height: 24px;
width: 200px;
border: 1px solid #0000CC;
background: #99CCFF;
font-size: 12px;
padding: 3px 0 0 2px;
}

В итоге видим, что в разных браузерах текст в поле выравнивается по разному плюс размеры самого поля отличается:

FF 3.5opera 10ie6
текст в поле в ff текст в поле в opera текст в поле в ie6

На размерах поля останавливаться не будем — нужно вспомнить просто о блочной модели и том, что ие6 ее не так понимает. А вот чтобы выровнять текст, нужно следующее:

  • указать высоту поля
  • явно указать верхний и нижний отступы (padding-top / padding-bottom)
  • ну и не забыть явно указать размер шрифта (font-size)
  • задать высоту строки (line-height) равную высоте поля (height) — update by Константин
input {
height: 16px; /* высота с учетом бордюр, внутренних отступов */
width: 196px; /* ширина с учетом бордюр, внутренних отступов */
border: 1px solid #0000CC;
background: #99CCFF;
font-size: 12px;
padding: 3px 0 3px 2px; /* обязательно наличие как верхнего так и нижнего отступа */
font-family: Arial, Helvetica, sans-serif;
line-height: 16px; /* должно быть равно height, пригодится как минимум для ie6  */
}
* html input {
/* 
  update by Nikita Zhukov
  хак нужен только если IE6 работает в режиме обратной совместимости
  (в таком режиме он работает например, если используется xml-декларация)
*/
height: 24px;
width: 200px;
}

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

Update так же следует упомянуть, что поля в Safari и Chrome имеют по умолчанию внешние отступы (похоже на резервирование места для подсветки поля в фокусе). Иногда это мешает, например, когда требуется выровнять поля разных типов по одной линии (пример как это должно выглядеть можно увидеть в статье "Убираем отступы у checkbox и radio"). Чтобы было все тип-топ, достаточно обнулить отступы для этих полей.