← HTML & CSS/Типы полей формы#9 из 383← ПредыдущийСледующий →+15 XP
Полезно по теме:Гайд: старт в frontendПрактика: DOM и событияТермин: DOMМаршрут: старт с нуля

Типы полей формы

Форма регистрации на Wildberries включает: поле для имени, email, пароль, выбор пола, дату рождения. Каждое из этих полей — разный тип <input>. Правильный тип поля улучшает UX: на мобильном появляется нужная клавиатура, браузер проверяет данные автоматически.

Текстовые типы

<!-- Обычный текст -->
<input type="text" name="username" placeholder="Введи имя" />

<!-- Email — браузер проверяет наличие @ -->
<input type="email" name="email" placeholder="you@example.com" />

<!-- Пароль — символы скрыты точками -->
<input type="password" name="password" placeholder="Минимум 8 символов" />

<!-- Число — на мобильном показывает цифровую клавиатуру -->
<input type="number" name="age" min="1" max="120" />

<!-- Телефон -->
<input type="tel" name="phone" placeholder="+7 (999) 123-45-67" />

<!-- URL -->
<input type="url" name="website" placeholder="https://example.com" />

Выбор из вариантов

Чекбокс — множественный выбор

<label>
  <input type="checkbox" name="agree" value="yes" />
  Согласен с условиями
</label>

<label>
  <input type="checkbox" name="newsletter" checked />
  Подписаться на рассылку
</label>

checked — атрибут без значения, означает «отмечен по умолчанию».

Radio — один из нескольких

<p>Пол:</p>
<label><input type="radio" name="gender" value="male" /> Мужской</label>
<label><input type="radio" name="gender" value="female" /> Женский</label>
<label><input type="radio" name="gender" value="other" /> Другой</label>

Все radio с одинаковым name — одна группа. Выбрать можно только один.

Select — выпадающий список

<label for="city">Город:</label>
<select id="city" name="city">
  <option value="">Выбери город</option>
  <option value="moscow">Москва</option>
  <option value="spb" selected>Санкт-Петербург</option>
  <option value="ekb">Екатеринбург</option>
</select>

Textarea — многострочный текст

<textarea name="message" rows="4" cols="50" placeholder="Напиши отзыв...">
</textarea>

Атрибуты валидации

<!-- required — поле обязательно -->
<input type="email" name="email" required />

<!-- minlength / maxlength — длина строки -->
<input type="text" name="username" minlength="3" maxlength="20" />

<!-- min / max — диапазон для числа -->
<input type="number" name="age" min="18" max="100" />

<!-- pattern — регулярное выражение -->
<input type="text" name="phone" pattern="+7[0-9]{10}" placeholder="+71234567890" />

Браузер проверяет эти условия при отправке формы — без JavaScript. Но серверная валидация обязательна — клиентскую можно обойти.

placeholder vs label

placeholder — это подсказка внутри поля, которая исчезает при вводе. Его нельзя использовать вместо <label>! Пользователь забывает что именно нужно ввести, а скринридеры могут пропустить placeholder.

<!-- Плохо — нет label -->
<input type="email" placeholder="Введи email" />

<!-- Хорошо — есть и label, и placeholder -->
<label for="email">Email</label>
<input type="email" id="email" name="email" placeholder="you@example.com" />

Типичные ошибки

Ошибка 1: Разные name у radio-кнопок

<!-- Неверно — разные name = разные группы -->
<input type="radio" name="gender_m" value="male" />
<input type="radio" name="gender_f" value="female" />

<!-- Верно — одинаковый name = одна группа -->
<input type="radio" name="gender" value="male" />
<input type="radio" name="gender" value="female" />

Ошибка 2: Числовой input для телефона

<!-- Неверно — телефон начинается с +, не является числом -->
<input type="number" name="phone" />

<!-- Верно -->
<input type="tel" name="phone" />

Ошибка 3: Полагаться только на HTML-валидацию

HTML-валидация — это UX-фича. Для безопасности всегда валидируй данные на сервере.

В реальных проектах

React, Vue и Angular добавляют состояние и события поверх нативных input, но HTML-атрибуты (type, name, required, pattern) передаются напрямую в DOM-элемент. Библиотеки react-hook-form и Zod добавляют мощную валидацию на основе всё тех же принципов.

Примеры

Создание разных типов input и чтение их свойств

// Разные типы полей формы
const inputTypes = [
  { type: 'text', name: 'username', placeholder: 'Имя пользователя' },
  { type: 'email', name: 'email', placeholder: 'you@example.com' },
  { type: 'password', name: 'password', placeholder: 'Пароль' },
  { type: 'number', name: 'age', min: '18', max: '100' },
  { type: 'checkbox', name: 'agree', value: 'yes' },
]

inputTypes.forEach(config => {
  const input = document.createElement('input')
  input.type = config.type
  input.name = config.name
  if (config.placeholder) input.placeholder = config.placeholder
  if (config.min) input.min = config.min
  if (config.max) input.max = config.max
  if (config.value) input.value = config.value

  console.log('type=' + input.type + ', name=' + input.name)
})

// Создаём select
const select = document.createElement('select')
select.name = 'city'

const cities = ['Москва', 'Санкт-Петербург', 'Казань']
cities.forEach((city, i) => {
  const option = document.createElement('option')
  option.value = city.toLowerCase().replace(' ', '-')
  option.textContent = city
  if (i === 0) option.selected = true
  select.appendChild(option)
})

console.log('select name:', select.name)
console.log('Вариантов:', select.options.length)
console.log('Выбранный:', select.options[select.selectedIndex].textContent)

Валидация полей формы — проверка типов и required

// Имитируем HTML5-валидацию формы
const fields = [
  { name: 'username', type: 'text', required: true, minlength: 3, value: 'Jo' },
  { name: 'email', type: 'email', required: true, value: 'not-an-email' },
  { name: 'age', type: 'number', min: 18, max: 100, value: 15 },
  { name: 'password', type: 'password', required: true, minlength: 8, value: 'secret12' },
  { name: 'agree', type: 'checkbox', required: true, checked: false },
]

function validateField(field) {
  const errors = []

  if (field.required && !field.value && !field.checked) {
    errors.push('поле обязательно для заполнения')
  }
  if (field.minlength && field.value && field.value.length < field.minlength) {
    errors.push('минимум ' + field.minlength + ' символов (сейчас ' + field.value.length + ')')
  }
  if (field.type === 'email' && field.value && !field.value.includes('@')) {
    errors.push('некорректный email')
  }
  if (field.type === 'number' && field.value) {
    const val = Number(field.value)
    if (field.min && val < field.min) errors.push('минимум ' + field.min)
    if (field.max && val > field.max) errors.push('максимум ' + field.max)
  }

  return errors
}

fields.forEach(field => {
  const errors = validateField(field)
  if (errors.length) {
    console.log('ОШИБКА [' + field.name + ']: ' + errors.join(', '))
  } else {
    console.log('OK [' + field.name + ']')
  }
})

Типы полей формы

Форма регистрации на Wildberries включает: поле для имени, email, пароль, выбор пола, дату рождения. Каждое из этих полей — разный тип <input>. Правильный тип поля улучшает UX: на мобильном появляется нужная клавиатура, браузер проверяет данные автоматически.

Текстовые типы

<!-- Обычный текст -->
<input type="text" name="username" placeholder="Введи имя" />

<!-- Email — браузер проверяет наличие @ -->
<input type="email" name="email" placeholder="you@example.com" />

<!-- Пароль — символы скрыты точками -->
<input type="password" name="password" placeholder="Минимум 8 символов" />

<!-- Число — на мобильном показывает цифровую клавиатуру -->
<input type="number" name="age" min="1" max="120" />

<!-- Телефон -->
<input type="tel" name="phone" placeholder="+7 (999) 123-45-67" />

<!-- URL -->
<input type="url" name="website" placeholder="https://example.com" />

Выбор из вариантов

Чекбокс — множественный выбор

<label>
  <input type="checkbox" name="agree" value="yes" />
  Согласен с условиями
</label>

<label>
  <input type="checkbox" name="newsletter" checked />
  Подписаться на рассылку
</label>

checked — атрибут без значения, означает «отмечен по умолчанию».

Radio — один из нескольких

<p>Пол:</p>
<label><input type="radio" name="gender" value="male" /> Мужской</label>
<label><input type="radio" name="gender" value="female" /> Женский</label>
<label><input type="radio" name="gender" value="other" /> Другой</label>

Все radio с одинаковым name — одна группа. Выбрать можно только один.

Select — выпадающий список

<label for="city">Город:</label>
<select id="city" name="city">
  <option value="">Выбери город</option>
  <option value="moscow">Москва</option>
  <option value="spb" selected>Санкт-Петербург</option>
  <option value="ekb">Екатеринбург</option>
</select>

Textarea — многострочный текст

<textarea name="message" rows="4" cols="50" placeholder="Напиши отзыв...">
</textarea>

Атрибуты валидации

<!-- required — поле обязательно -->
<input type="email" name="email" required />

<!-- minlength / maxlength — длина строки -->
<input type="text" name="username" minlength="3" maxlength="20" />

<!-- min / max — диапазон для числа -->
<input type="number" name="age" min="18" max="100" />

<!-- pattern — регулярное выражение -->
<input type="text" name="phone" pattern="+7[0-9]{10}" placeholder="+71234567890" />

Браузер проверяет эти условия при отправке формы — без JavaScript. Но серверная валидация обязательна — клиентскую можно обойти.

placeholder vs label

placeholder — это подсказка внутри поля, которая исчезает при вводе. Его нельзя использовать вместо <label>! Пользователь забывает что именно нужно ввести, а скринридеры могут пропустить placeholder.

<!-- Плохо — нет label -->
<input type="email" placeholder="Введи email" />

<!-- Хорошо — есть и label, и placeholder -->
<label for="email">Email</label>
<input type="email" id="email" name="email" placeholder="you@example.com" />

Типичные ошибки

Ошибка 1: Разные name у radio-кнопок

<!-- Неверно — разные name = разные группы -->
<input type="radio" name="gender_m" value="male" />
<input type="radio" name="gender_f" value="female" />

<!-- Верно — одинаковый name = одна группа -->
<input type="radio" name="gender" value="male" />
<input type="radio" name="gender" value="female" />

Ошибка 2: Числовой input для телефона

<!-- Неверно — телефон начинается с +, не является числом -->
<input type="number" name="phone" />

<!-- Верно -->
<input type="tel" name="phone" />

Ошибка 3: Полагаться только на HTML-валидацию

HTML-валидация — это UX-фича. Для безопасности всегда валидируй данные на сервере.

В реальных проектах

React, Vue и Angular добавляют состояние и события поверх нативных input, но HTML-атрибуты (type, name, required, pattern) передаются напрямую в DOM-элемент. Библиотеки react-hook-form и Zod добавляют мощную валидацию на основе всё тех же принципов.

Примеры

Создание разных типов input и чтение их свойств

// Разные типы полей формы
const inputTypes = [
  { type: 'text', name: 'username', placeholder: 'Имя пользователя' },
  { type: 'email', name: 'email', placeholder: 'you@example.com' },
  { type: 'password', name: 'password', placeholder: 'Пароль' },
  { type: 'number', name: 'age', min: '18', max: '100' },
  { type: 'checkbox', name: 'agree', value: 'yes' },
]

inputTypes.forEach(config => {
  const input = document.createElement('input')
  input.type = config.type
  input.name = config.name
  if (config.placeholder) input.placeholder = config.placeholder
  if (config.min) input.min = config.min
  if (config.max) input.max = config.max
  if (config.value) input.value = config.value

  console.log('type=' + input.type + ', name=' + input.name)
})

// Создаём select
const select = document.createElement('select')
select.name = 'city'

const cities = ['Москва', 'Санкт-Петербург', 'Казань']
cities.forEach((city, i) => {
  const option = document.createElement('option')
  option.value = city.toLowerCase().replace(' ', '-')
  option.textContent = city
  if (i === 0) option.selected = true
  select.appendChild(option)
})

console.log('select name:', select.name)
console.log('Вариантов:', select.options.length)
console.log('Выбранный:', select.options[select.selectedIndex].textContent)

Валидация полей формы — проверка типов и required

// Имитируем HTML5-валидацию формы
const fields = [
  { name: 'username', type: 'text', required: true, minlength: 3, value: 'Jo' },
  { name: 'email', type: 'email', required: true, value: 'not-an-email' },
  { name: 'age', type: 'number', min: 18, max: 100, value: 15 },
  { name: 'password', type: 'password', required: true, minlength: 8, value: 'secret12' },
  { name: 'agree', type: 'checkbox', required: true, checked: false },
]

function validateField(field) {
  const errors = []

  if (field.required && !field.value && !field.checked) {
    errors.push('поле обязательно для заполнения')
  }
  if (field.minlength && field.value && field.value.length < field.minlength) {
    errors.push('минимум ' + field.minlength + ' символов (сейчас ' + field.value.length + ')')
  }
  if (field.type === 'email' && field.value && !field.value.includes('@')) {
    errors.push('некорректный email')
  }
  if (field.type === 'number' && field.value) {
    const val = Number(field.value)
    if (field.min && val < field.min) errors.push('минимум ' + field.min)
    if (field.max && val > field.max) errors.push('максимум ' + field.max)
  }

  return errors
}

fields.forEach(field => {
  const errors = validateField(field)
  if (errors.length) {
    console.log('ОШИБКА [' + field.name + ']: ' + errors.join(', '))
  } else {
    console.log('OK [' + field.name + ']')
  }
})

Задание

Напиши HTML-форму анкеты для сервиса знакомств: поле text для имени (required, minlength="2"), number для возраста (min="18", max="99"), select с тремя городами, textarea для описания (maxlength="200"), checkbox для согласия (required). Добавь label к каждому полю и кнопку submit.

Подсказка

type="number" — числовое поле, min и max задают диапазон. minlength — минимальная длина для текстовых полей. select содержит option-элементы. textarea — отдельный тег (не input), maxlength ограничивает длину. required — обязательное поле.

Загружаем среду выполнения...
Загружаем AI-помощника...