Перейти к основному содержанию Перейти к навигации по документам
Cмотреть на GitHub

Валидация

Получите мощные возможности проверки с помощью валидации форм HTML5 доступной во всех поддерживаемых браузерах по умолчанию или с использованием пользовательских стилей и JavaScript.

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

Как это работает

Вот как валидация форм работает с Bootstrap:

  • Валидация форм HTML работает на 2 псевдоклассах CSS: :invalid и :valid, применяемых к элементам <input>, <select> и <textarea>.
  • Стили этих псевдоклассов применяются к родительскому классу .was-validated, обычно применяемому к <form>. В ином случае любое другое требуемое поле без значения становится невалидным при загрузке страницы. Таким образом можно выбирать, когда активировать формы (обычно после того, как нажато подтверждение).
  • Для сброса внешнего вида формы (например, в случае отправки динамической формы с использованием AJAX) удалите класс .was-validated из <form> после отправки.
  • Как резервный вариант, классы .is-invalid и .is-valid можно использовать вместо псевдоклассов при серверной валидации. Они не требуют родительского класса .was-validated.
  • Благодаря ограничениям, заложенным в самой природе CSS, нельзя (по крайней мере, сегодня) применять стили к элементу <label>, который в DOM расположен перед элементами контроля формы, без использования JavaScript.
  • Все современные браузеры поддерживают API проверки ограничений – серию методов JavaScript для валидации органов контроля форм.
  • В качестве сообщений обратной связи в формах можно использовать таковые по умолчанию браузеров (разные для каждого браузера, и неизменяемые через CSS) или наши стандартные стили сообщений обратной связи с дополнительным HTML и CSS.
  • Вы можете создать сообщения валидации методом setCustomValidity в JavaScript.

Знаю всё это, посмотрите следующие демонстрации использования стилей валидации форм, серверных классы и настроек браузера по умолчанию.

Пользовательские стили

Для стандартных сообщений проверки форм Bootstrap вам потребуется добавить логический атрибут novalidate к <form>. Это деактивирует всплывающие сообщения обратной связи, существующие в браузере по умолчанию, но одновременно сохранит доступ JS к API валидации форм. Попробуйте войти в форму ниже, наш JavaScript выдаст вам сообщение обратной связи. При попытке входа вы увидите, как стили :invalid и :valid применятся к элементам управления формы.

В пользовательских стилях обратной связи применяются пользовательские цвета, границы, стили фокусировки и значки фона для лучшей передавачи обратной связи. Фоновые значки для <select> доступны только с .custom-select, но не с .form-control.

Все хорошо!
Все хорошо!
@
Пожалуйста, выберите имя пользователя.
Укажите действующий город.
Пожалуйста, выберите корректный город.
Пожалуйста, предоставьте действующий почтовый индекс.
Вы должны принять перед отправкой.
<form class="row g-3 needs-validation" novalidate>
  <div class="col-md-4">
    <label for="validationCustom01" class="form-label">Имя</label>
    <input type="text" class="form-control" id="validationCustom01" value="Иван" required>
    <div class="valid-feedback">
      Все хорошо!
    </div>
  </div>
  <div class="col-md-4">
    <label for="validationCustom02" class="form-label">Фамилия</label>
    <input type="text" class="form-control" id="validationCustom02" value="Петров" required>
    <div class="valid-feedback">
      Все хорошо!
    </div>
  </div>
  <div class="col-md-4">
    <label for="validationCustomUsername" class="form-label">Имя пользователя</label>
    <div class="input-group has-validation">
      <span class="input-group-text" id="inputGroupPrepend">@</span>
      <input type="text" class="form-control" id="validationCustomUsername" aria-describedby="inputGroupPrepend" required>
      <div class="invalid-feedback">
        Пожалуйста, выберите имя пользователя.
      </div>
    </div>
  </div>
  <div class="col-md-6">
    <label for="validationCustom03" class="form-label">Город</label>
    <input type="text" class="form-control" id="validationCustom03" required>
    <div class="invalid-feedback">
      Укажите действующий город.
    </div>
  </div>
  <div class="col-md-3">
    <label for="validationCustom04" class="form-label">Область</label>
    <select class="form-select" id="validationCustom04" required>
      <option selected disabled value="">Выберите...</option>
      <option>...</option>
    </select>
    <div class="invalid-feedback">
      Пожалуйста, выберите корректный город.
    </div>
  </div>
  <div class="col-md-3">
    <label for="validationCustom05" class="form-label">Индекс</label>
    <input type="text" class="form-control" id="validationCustom05" required>
    <div class="invalid-feedback">
      Пожалуйста, предоставьте действующий почтовый индекс.
    </div>
  </div>
  <div class="col-12">
    <div class="form-check">
      <input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
      <label class="form-check-label" for="invalidCheck">
        Примите условия и соглашения
      </label>
      <div class="invalid-feedback">
        Вы должны принять перед отправкой.
      </div>
    </div>
  </div>
  <div class="col-12">
    <button class="btn btn-primary" type="submit">Отправить форму</button>
  </div>
</form>
// Пример стартового JavaScript для отключения отправки форм при наличии недопустимых полей
(function () {
  'use strict'

  // Получите все формы, к которым мы хотим применить пользовательские стили проверки Bootstrap
  var forms = document.querySelectorAll('.needs-validation')

  // Зацикливайтесь на них и предотвращайте отправку
  Array.prototype.slice.call(forms)
    .forEach(function (form) {
      form.addEventListener('submit', function (event) {
        if (!form.checkValidity()) {
          event.preventDefault()
          event.stopPropagation()
        }

        form.classList.add('was-validated')
      }, false)
    })
})()

Настройки браузера по умолчанию

Не нужны стандартные сообщения обратной связи? Не хотите писать скрипты JavaScript для изменения поведения форм? Используйте умолчания браузера. Попробуйте войти в форму ниже. В зависимости от вашего браузера и ОС вы увидите немного разные стили обратной связи.

Хотя эти сообщения обратной связи нельзя настраивать CSS, их можно настроить с JavaScript.

@
<form class="row g-3">
  <div class="col-md-4">
    <label for="validationDefault01" class="form-label">Имя</label>
    <input type="text" class="form-control" id="validationDefault01" value="Иван" required>
  </div>
  <div class="col-md-4">
    <label for="validationDefault02" class="form-label">Фамилия</label>
    <input type="text" class="form-control" id="validationDefault02" value="Петров" required>
  </div>
  <div class="col-md-4">
    <label for="validationDefaultUsername" class="form-label">Имя пользователя</label>
    <div class="input-group">
      <span class="input-group-text" id="inputGroupPrepend2">@</span>
      <input type="text" class="form-control" id="validationDefaultUsername"  aria-describedby="inputGroupPrepend2" required>
    </div>
  </div>
  <div class="col-md-6">
    <label for="validationDefault03" class="form-label">Город</label>
    <input type="text" class="form-control" id="validationDefault03" required>
  </div>
  <div class="col-md-3">
    <label for="validationDefault04" class="form-label">Область</label>
    <select class="form-select" id="validationDefault04" required>
      <option selected disabled value="">Выберите...</option>
      <option>...</option>
    </select>
  </div>
  <div class="col-md-3">
    <label for="validationDefault05" class="form-label">Индекс</label>
    <input type="text" class="form-control" id="validationDefault05" required>
  </div>
  <div class="col-12">
    <div class="form-check">
      <input class="form-check-input" type="checkbox" value="" id="invalidCheck2" required>
      <label class="form-check-label" for="invalidCheck2">
        Примите условия и соглашения
      </label>
    </div>
  </div>
  <div class="col-12">
    <button class="btn btn-primary" type="submit">Отправить форму</button>
  </div>
</form>

Проверка на стороне сервера

Мы рекомендуем использовать валидацию со стороны клиента, но если вам понадобится таковая со стороны сервера, вы можете обозначать валидные и невалидные поля форм классами .is-invalid и .is-valid. Заметим, что их можно также использовать с классом .invalid-feedback.

Для недопустимых полей убедитесь, что недопустимая обратная связь или сообщение об ошибке связано с соответствующим полем формы с помощью aria-describedby (учитывая, что этот атрибут позволяет ссылаться на несколько id идентификаторов, если поле уже указывает на дополнительный текст формы).

Чтобы обойти проблему с радиусами границ, необходимо применять дополнительный класс.has-validation.

Все хорошо!
Все хорошо!
@
Пожалуйста, выберите имя пользователя.
Укажите действующий город.
Пожалуйста, выберите корректный город.
Пожалуйста, предоставьте действующий почтовый индекс.
Вы должны принять перед отправкой.
<form class="row g-3">
  <div class="col-md-4">
    <label for="validationServer01" class="form-label">Имя</label>
    <input type="text" class="form-control is-valid" id="validationServer01" value="Иван" required>
    <div class="valid-feedback">
      Все хорошо!
    </div>
  </div>
  <div class="col-md-4">
    <label for="validationServer02" class="form-label">Фамилия</label>
    <input type="text" class="form-control is-valid" id="validationServer02" value="Петров" required>
    <div class="valid-feedback">
      Все хорошо!
    </div>
  </div>
  <div class="col-md-4">
    <label for="validationServerUsername" class="form-label">Имя пользователя</label>
    <div class="input-group has-validation">
      <span class="input-group-text" id="inputGroupPrepend3">@</span>
      <input type="text" class="form-control is-invalid" id="validationServerUsername" aria-describedby="inputGroupPrepend3 validationServerUsernameFeedback" required>
      <div id="validationServerUsernameFeedback" class="invalid-feedback">
        Пожалуйста, выберите имя пользователя.
      </div>
    </div>
  </div>
  <div class="col-md-6">
    <label for="validationServer03" class="form-label">Город</label>
    <input type="text" class="form-control is-invalid" id="validationServer03" aria-describedby="validationServer03Feedback" required>
    <div id="validationServer03Feedback" class="invalid-feedback">
      Укажите действующий город.
    </div>
  </div>
  <div class="col-md-3">
    <label for="validationServer04" class="form-label">Область</label>
    <select class="form-select is-invalid" id="validationServer04" aria-describedby="validationServer04Feedback" required>
      <option selected disabled value="">Выберите...</option>
      <option>...</option>
    </select>
    <div id="validationServer04Feedback" class="invalid-feedback">
      Пожалуйста, выберите корректный город.
    </div>
  </div>
  <div class="col-md-3">
    <label for="validationServer05" class="form-label">Индекс</label>
    <input type="text" class="form-control is-invalid" id="validationServer05" aria-describedby="validationServer05Feedback" required>
    <div id="validationServer05Feedback" class="invalid-feedback">
      Пожалуйста, предоставьте действующий почтовый индекс.
    </div>
  </div>
  <div class="col-12">
    <div class="form-check">
      <input class="form-check-input is-invalid" type="checkbox" value="" id="invalidCheck3" aria-describedby="invalidCheck3Feedback" required>
      <label class="form-check-label" for="invalidCheck3">
        Примите условия и соглашения
      </label>
      <div id="invalidCheck3Feedback" class="invalid-feedback">
        Вы должны принять перед отправкой.
      </div>
    </div>
  </div>
  <div class="col-12">
    <button class="btn btn-primary" type="submit">Отправить форму</button>
  </div>
</form>

Поддерживаемые элементы

Стили проверки доступны для следующих элементов управления формы и компонентов:

  • <input> и <textarea> с .form-control (включая до одного .form-control в группах ввода)
  • <select> с .form-select
  • .form-check
Пожалуйста, введите сообщение в текстовое поле.
Пример неверного текста обратной связи
Еще пример неверного текста обратной связи
Пример обратной связи неверного выбора
Пример обратной связи неверной формы выбора файла
<form class="was-validated">
  <div class="mb-3">
    <label for="validationTextarea" class="form-label">Текстовое поле</label>
    <textarea class="form-control is-invalid" id="validationTextarea" placeholder="Обязательный пример текстового поля" required></textarea>
    <div class="invalid-feedback">
      Пожалуйста, введите сообщение в текстовое поле.
    </div>
  </div>

  <div class="form-check mb-3">
    <input type="checkbox" class="form-check-input" id="validationFormCheck1" required>
    <label class="form-check-label" for="validationFormCheck1">Отметьте этот флажок</label>
    <div class="invalid-feedback">Пример неверного текста обратной связи</div>
  </div>

  <div class="form-check">
    <input type="radio" class="form-check-input" id="validationFormCheck2" name="radio-stacked" required>
    <label class="form-check-label" for="validationFormCheck2">Переключить это радио</label>
  </div>
  <div class="form-check mb-3">
    <input type="radio" class="form-check-input" id="validationFormCheck3" name="radio-stacked" required>
    <label class="form-check-label" for="validationFormCheck3">Или переключить это другое радио</label>
    <div class="invalid-feedback">Еще пример неверного текста обратной связи</div>
  </div>

  <div class="mb-3">
    <select class="form-select" required aria-label="select example">
      <option value="">Откройте это меню выбора</option>
      <option value="1">Один</option>
      <option value="2">Два</option>
      <option value="3">Три</option>
    </select>
    <div class="invalid-feedback">Пример обратной связи неверного выбора </div>
  </div>

  <div class="mb-3">
    <input type="file" class="form-control" aria-label="file example" required>
    <div class="invalid-feedback">Пример обратной связи неверной формы выбора файла</div>
  </div>

  <div class="mb-3">
    <button class="btn btn-primary" type="submit" disabled>Отправить форму</button>
  </div>
</form>

Всплывающие подсказки

Если разметка ваших форм позволит, вы можете заменить классы .{valid|invalid}-feedback классами .{valid|invalid}-tooltip - для отображения обратной связи валидации, стилизованной под всплывающую подсказку. Для правильного позиционирования всплывающей подсказки удостоверьтесь, что родительский элемент содержит position: relative. В примере ниже наши классы колонок уже имеют этот атрибут, но ваш проект может потребовать иные настройки.

Все хорошо!
Все хорошо!
@
Пожалуйста, выберите уникальное и действительное имя пользователя.
Укажите действующий город.
Пожалуйста, выберите корректный город.
Пожалуйста, предоставьте действующий почтовый индекс.
<form class="row g-3 needs-validation" novalidate>
  <div class="col-md-4 position-relative">
    <label for="validationTooltip01" class="form-label">Имя</label>
    <input type="text" class="form-control" id="validationTooltip01" value="Иван" required>
    <div class="valid-tooltip">
      Все хорошо!
    </div>
  </div>
  <div class="col-md-4 position-relative">
    <label for="validationTooltip02" class="form-label">Фамилия</label>
    <input type="text" class="form-control" id="validationTooltip02" value="Петров" required>
    <div class="valid-tooltip">
      Все хорошо!
    </div>
  </div>
  <div class="col-md-4 position-relative">
    <label for="validationTooltipUsername" class="form-label">Имя пользователя</label>
    <div class="input-group has-validation">
      <span class="input-group-text" id="validationTooltipUsernamePrepend">@</span>
      <input type="text" class="form-control" id="validationTooltipUsername" aria-describedby="validationTooltipUsernamePrepend" required>
      <div class="invalid-tooltip">
        Пожалуйста, выберите уникальное и действительное имя пользователя.
      </div>
    </div>
  </div>
  <div class="col-md-6 position-relative">
    <label for="validationTooltip03" class="form-label">Город</label>
    <input type="text" class="form-control" id="validationTooltip03" required>
    <div class="invalid-tooltip">
      Укажите действующий город.
    </div>
  </div>
  <div class="col-md-3 position-relative">
    <label for="validationTooltip04" class="form-label">Область</label>
    <select class="form-select" id="validationTooltip04" required>
      <option selected disabled value="">Выберите...</option>
      <option>...</option>
    </select>
    <div class="invalid-tooltip">
      Пожалуйста, выберите корректный город.
    </div>
  </div>
  <div class="col-md-3 position-relative">
    <label for="validationTooltip05" class="form-label">Индекс</label>
    <input type="text" class="form-control" id="validationTooltip05" required>
    <div class="invalid-tooltip">
      Пожалуйста, предоставьте действующий почтовый индекс.
    </div>
  </div>
  <div class="col-12">
    <button class="btn btn-primary" type="submit">Отправить форму</button>
  </div>
</form>

Sass

Переменные

$form-feedback-margin-top:          $form-text-margin-top;
$form-feedback-font-size:           $form-text-font-size;
$form-feedback-font-style:          $form-text-font-style;
$form-feedback-valid-color:         $success;
$form-feedback-invalid-color:       $danger;

$form-feedback-icon-valid-color:    $form-feedback-valid-color;
$form-feedback-icon-valid:          url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>");
$form-feedback-icon-invalid-color:  $form-feedback-invalid-color;
$form-feedback-icon-invalid:        url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>");

Миксины

Два миксина объединяются вместе с помощью нашего цикла, чтобы сгенерировать наши стили обратной связи для проверки формы.

@mixin form-validation-state-selector($state) {
  @if ($state == "valid" or $state == "invalid") {
    .was-validated #{if(&, "&", "")}:#{$state},
    #{if(&, "&", "")}.is-#{$state} {
      @content;
    }
  } @else {
    #{if(&, "&", "")}.is-#{$state} {
      @content;
    }
  }
}

@mixin form-validation-state(
  $state,
  $color,
  $icon,
  $tooltip-color: color-contrast($color),
  $tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),
  $focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity)
) {
  .#{$state}-feedback {
    display: none;
    width: 100%;
    margin-top: $form-feedback-margin-top;
    @include font-size($form-feedback-font-size);
    font-style: $form-feedback-font-style;
    color: $color;
  }

  .#{$state}-tooltip {
    position: absolute;
    top: 100%;
    z-index: 5;
    display: none;
    max-width: 100%; // Contain to parent when possible
    padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
    margin-top: .1rem;
    @include font-size($form-feedback-tooltip-font-size);
    line-height: $form-feedback-tooltip-line-height;
    color: $tooltip-color;
    background-color: $tooltip-bg-color;
    @include border-radius($form-feedback-tooltip-border-radius);
  }

  @include form-validation-state-selector($state) {
    ~ .#{$state}-feedback,
    ~ .#{$state}-tooltip {
      display: block;
    }
  }

  .form-control {
    @include form-validation-state-selector($state) {
      border-color: $color;

      @if $enable-validation-icons {
        padding-right: $input-height-inner;
        background-image: escape-svg($icon);
        background-repeat: no-repeat;
        background-position: right $input-height-inner-quarter center;
        background-size: $input-height-inner-half $input-height-inner-half;
      }

      &:focus {
        border-color: $color;
        box-shadow: $focus-box-shadow;
      }
    }
  }

  // stylelint-disable-next-line selector-no-qualifying-type
  textarea.form-control {
    @include form-validation-state-selector($state) {
      @if $enable-validation-icons {
        padding-right: $input-height-inner;
        background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
      }
    }
  }

  .form-select {
    @include form-validation-state-selector($state) {
      border-color: $color;

      @if $enable-validation-icons {
        padding-right: $form-select-feedback-icon-padding-end;
        background-image: escape-svg($form-select-indicator), escape-svg($icon);
        background-position: $form-select-bg-position, $form-select-feedback-icon-position;
        background-size: $form-select-bg-size, $form-select-feedback-icon-size;
      }

      &:focus {
        border-color: $color;
        box-shadow: $focus-box-shadow;
      }
    }
  }

  .form-check-input {
    @include form-validation-state-selector($state) {
      border-color: $color;

      &:checked {
        background-color: $color;
      }

      &:focus {
        box-shadow: $focus-box-shadow;
      }

      ~ .form-check-label {
        color: $color;
      }
    }
  }
  .form-check-inline .form-check-input {
    ~ .#{$state}-feedback {
      margin-left: .5em;
    }
  }

  .input-group .form-control,
  .input-group .form-select {
    @include form-validation-state-selector($state) {
      z-index: 3;
    }
  }
}

Карта

Это карта валидации Sass из _variables.scss. Переопределите или расширьте это, чтобы создать другие или дополнительные состояния.

$form-validation-states: (
  "valid": (
    "color": $form-feedback-valid-color,
    "icon": $form-feedback-icon-valid
  ),
  "invalid": (
    "color": $form-feedback-invalid-color,
    "icon": $form-feedback-icon-invalid
  )
);

Карты $form-validation-states могут содержать три необязательных параметра для переопределения всплывающих подсказок и стилей фокуса.

Цикл

Используется для перебора значений карты $form-validation-states для генерации наших стилей проверки. Любые изменения в приведенной выше карте Sass будут отражены в Вашем скомпилированном CSS через этот цикл.

@each $state, $data in $form-validation-states {
  @include form-validation-state($state, $data...);
}

Пользовательские настройки

Состояния проверки можно настроить через Sass с помощью карты $form-validation-states. Эта карта Sass, расположенная в нашем файле _variables.scss, используется для генерации состояний валидации по умолчанию valid/invalid. ключена вложенная карта для настройки цвета каждого состояния, значка, цвета всплывающей подсказки и тени фокуса. Хотя браузеры не поддерживают никакие другие состояния, те, кто использует собственные стили, могут легко добавить более сложную обратную связь с формой.

Обратите внимание, что мы не рекомендуем настраивать значения $form-validation-states без изменения миксина form-validation-state.