'Bootstrap 4 invalid feedback with input group not displaying

I have been looking into Bootstrap 4 - beta, however when using .is-invalid with .input-group it doesn't seem to show up.

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" />
<div class="form-group">
  <label for="label">Label</label>
  <div class="input-group">

    <div class="input-group-addon">
      label
    </div>
    <input type="text" value="" name="label" class="form-control is-invalid">
  </div>

  <div class="invalid-feedback is-invalid">
    <strong>Invalid Label</strong>
  </div>
</div>

How are you meant to display an invalid message while using .input-group?

Adding the following CSS works as a workaround, but it seems odd.

.form-group.is-invalid {
    .invalid-feedback {
        display: block;
    }
}


Solution 1:[1]

They haven't taken into account their own examples using input group addons and buttons, even with a column model. The markup does only facilitate "neighboring" elements, not parent > neighboring element (there is no CSS rule for that).

It seems, for now, you should fall back to Alpha 6 or program your own CSS classes accordingly. I've done the same, unfortunately.

Please note when reading my answer that this was posted just as the beta was released. :)

Solution 2:[2]

Boostrap 4 is very buggy. My suggestion is to replace:

 <div class="invalid-feedback">
 Text here
 </div>

With:

<div class="text-danger">
Text here
</div>

And the second one looks virtually the same and will not fail.

For a better look, try:

<div class="text-danger">
<small>Text here</small>
</div>

Solution 3:[3]

The way Bootstrap does override the display from none to block is by checking first for a previous is-invalid class, for example! Check this CSS out:

enter image description here

That means, in case of an error, first is-invalid must be applied on an element and then invalid-feedback on another afterward! Like the following in Laravel, for instance:

{{-- Either following an input --}}

<input type="password" id="registerPassword"
       class="form-control @error('register_password') is-invalid @enderror"
       name="register_password" required autocomplete="new-password"
>

@error('register_password')
    <span class="invalid-feedback" role="alert">
        <strong>{{ $message }}</strong>
    </span>
@enderror

{{-- Or separately in DOM --}}

@error('register_password')
    <div class="is-invalid">...</div>

    <span class="invalid-feedback" role="alert">
        <strong>{{ $message }}</strong>
    </span>
@enderror

Solution 4:[4]

I solved it by adding d-block class:

@error('terms')
    <div class="invalid-feedback d-block" role="alert">
         <strong>{{ $message }}</strong>
    </div>
@enderror

Happy coding!

Bootstrap docs here about d-block:Display property

Solution 5:[5]

Working example with a trick using flex-wrap and w-100:

<div class="form-group">
    <label class="form-control-label">Name</label>
    <div class="input-group flex-wrap">
        <span class="input-group-addon"><span class="fa fa-lock"></span></span>
        <input name="name" class="form-control is-invalid" type="text">
        <div class="invalid-feedback w-100">Custom error</div>
    </div>
</div>

Solution 6:[6]

Add .is-invalid to the .input-group.

If the invalid-feedback element is preceded by an element with .is-invalid it will be displayed -- that is how server-side validation is supported.

Solution 7:[7]

I found this solution

<div class="input-group ">
    <div class="input-group-prepend">
        <div class="input-group-text">Start Date</div>
    </div>
    <input type="text" class="form-control is-invalid" placeholder="Date Input">
    <div class="invalid-feedback order-last ">
        Error Message
    </div>
    <div class="input-group-append">
        <div class="input-group-text"><i class="fa fa-calendar"></i></div>
    </div>
</div>

Solution 8:[8]

Inspecting the .invalid-feedback class I've found this definition (bootstrap 4.3)

.invalid-feedback {
    /*display: none;*/
    width: 100%;
    margin-top: .25rem;
    font-size: 80%;
    color: #dc3545;
}

You could copy and rename this class and use it without the built-in limitations

Solution 9:[9]

here is my "diy" answer

html

<div class="container">
<div class="row p-3">
    <div class="col-md-6 mb-3">
        <label class="sr-only">End Date/Time</label>
        <div class="input-group">
            <div class="input-group-prepend ">
                <div class="input-group-text error-feedback">Start Date</div>
            </div>
            <input type="text" class="form-control error-feedback" placeholder="Date Input">
            <div class="invalid-feedback order-last ">
                Error Message
            </div>
            <div class="input-group-append error-feedback">
                <div class="input-group-text"><i class="fa fa-calendar"></i></div>
            </div>
        </div>
    </div>
</div>

css

.error-feedback{
    border:1px red solid;
}

enter image description here

I know there is a bit off but, IMO pretty good compared this example

Solution 10:[10]

<div class="form-group">
<label class="form-control-label">Name</label>
<div class="input-group flex-wrap">
    <span class="input-group-addon"><span class="fa fa-lock"></span></span>
    <input name="name" class="form-control is-invalid" type="text">
    <div class="invalid-feedback d-block">Custom error</div>
</div>

Solution 11:[11]

Alternatively you can add the .is-valid/.is-invalid class to the parent element .input-group. Then you can change the css to add the red border to the child elements like this:

.input-group.is-invalid .form-control,
        .input-group.is-invalid .custom-select {
            border-color: #FA5252;
        }

        .input-group.is-invalid .input-group-prepend .input-group-text {
            border: 1px solid #FA5252;
        }

        .input-group.is-valid .form-control,
        .input-group.is-valid .custom-select {
            border-color: #05A677;
        }

        .input-group.is-valid .input-group-prepend .input-group-text {
            border: 1px solid #05A677;
        }

Solution 12:[12]

I'm using Bootstrap 4.3 and following code worked for me. Try adding "validated" class with "form-group" and group error message inside the input-group.

<div class="form-group validated">
    <label class="form-control-label">Name</label>
    <div class="input-group">
        <span class="input-group-addon"><span class="fa fa-lock"></span></span>
        <input name="name" class="form-control is-invalid" type="text">
        <div class="invalid-feedback">Custom error</div>
    </div>
</div>

Solution 13:[13]

In my app, I'm namespacing Bootstrap's styles so that they don't pollute the styles outside my app:

.my-app {
  @import '~bootstrap/scss/bootstrap.scss';
}

What I found by looking through the generated styles is that the validation css ultimately gets clobbered due to the mixin that generates it into:

.was-validated .my-app:invalid ~ .invalid-feedback,
.was-validated .my-app:invalid ~ .invalid-tooltip, 
.my-app.is-invalid ~ .invalid-feedback, 
.my-app.is-invalid ~ .invalid-tooltip {
  display: block;
}

Note that it's .my-app.is-invalid and not .my-app .is-invalid. It looks like this is a consequence of the form-validation-state-selector mixin that generates it, which has a comment suggesting it's the result of a dart-sass compatibility fix. One hack I could do is add the my-app class to every input that needed validation but that's not ideal.

I was able to resolve it by extending my namespace selector with a wildcard as follows:

.my-app * {
  @import '~bootstrap/scss/bootstrap.scss';
}