Lesson 7 - Bootstrap - Forms
In the previous lesson, Bootstrap - Buttons, we started a showcase of Bootstrap CSS framework components and learned to use buttons. In today's tutorial, we're going to start the most extensive part of Bootstrap, the forms.
Forms
The form styles are together with the grid probably the most attractive thing
about the Bootstrap CSS framework. They are responsive, pretty, and the controls
have the same size in every browser. They can even look the same if we use
custom styling. We assign the .form-control
class to individual
form controls. Then we wrap them together with the <label>
element into the <div>
element. We assign the
.form-group
class to the <div>
.
We can create a basic form, for example, like this:
<form> <div class="form-group"> <label for="login-email">Email</label> <input type="email" class="form-control" id="login-email" aria-describedby="emailDescription" placeholder="[email protected]"> <small class="form-text text-muted">You can type in your phone number instead of an email address.</small> </div> <div class="form-group"> <label for="login-password">Password</label> <input type="password" class="form-control" id="login-password"> </div> <button type="submit" class="btn btn-primary">Sign in</button> </form>
We assign a unique ID to each form control to pair the
<label>
and the <input>
elements. To
prevent naming collisions in case of multiple forms on a single page, we usually
prefix these IDs with the form name. In the example above, it's the
signin-
prefix. If we click on the <label>
, the
related input will be selected.
The result:
You can try reduce the size of your browser window and see that the form will
really wrap. Notice the usage of the .form-text
class for a little
hint text. In older versions of Bootstrap, you can find this class as
.help-block
.
Checkboxes and radio buttons
If we need to add a checkbox to the form, we insert it inside a
<label>
so that both the input and the
<label
> are clickable. For checkboxes, we use the
.form-check
, .form-check-label
, and
.form-check-input
classes instead of .form-group
. It
may be a bit confusing that we also use these classes for radio buttons.
Let's showcase another controls:
<form> <div class="form-check"> <label class="form-check-label"> <input class="form-check-input" type="checkbox" value=""> I agree to the Terms & Conditions </label> </div> <div class="form-check"> <label class="form-check-label"> <input class="form-check-input" type="radio" name="pay-method" id="pay-method1" value="card" checked> Pay by credit card </label> </div> <div class="form-check"> <label class="form-check-label"> <input class="form-check-input" type="radio" name="pay-method" id="pay-method2" value="transfer" checked> Wiretransfer payment </label> </div> </form>
The result:
Other classes for checkboxes and radio buttons
If we ad several checkboxes, one after another, they will render one under
another. This behavior can be changed by assigning the
.form-check-inline
class together with the .form-check
class. Even if we decided not to fill in the label text, we won't remove the
<label>
element and assign the .position-static
class to the <input>
in this case.
Selects, textareas and file inputs
We insert the <select>
and <textarea>
elements as we are used to. But to the inputs of the file
type, we don't assign the .form-control
class, we use the
.form-control-file
class instead.
<form> <div class="form-group"> <label for="example-size">Size</label> <select class="form-control" id="example-size"> <option>S</option> <option>M</option> <option>L</option> <option>XL</option> </select> </div> <div class="form-group"> <label for="example-note">Note</label> <textarea class="form-control" id="example-note" rows="3"></textarea> </div> <div class="form-group"> <label for="example-file">Resume (CV)</label> <input type="file" class="form-control-file" id="example-file"> </div> </form>
The result:
Sizes
We can change the size of form controls similarly as we did it with buttons, using one of the following classes:
.form-control-lg
- Large size- For the standard size, we just assign the
.form-control
class .form-control-sm
- Small size
The .form-control
class must always be assigned.
Inactive inputs
If we add the readonly="readonly"
attribute to the
<input>
element, Bootstrap styles it as gray and of course
its value can't be changed. If you are not an orthodox XML lover, it's okay to
assign the attribute just as readonly
and omit the value. This
works for any HTML attributes in this course. It's also possible to render
inactive <input>
s as plain text without the control element.
We can achieve that by assigning the .form-control-plaintext
class,
the readonly
attribute must be provided as well, of course. We can
similarly disable an element by adding the disabled="disabled"
attribute.
The difference between readonly
and disabled
is
that the disabled
elements will not be sent to the server and
cannot be selected by the tab key. Using the disabled
attribute we can also disable all the controls in the
<fieldset>
element if we assign it to this element. If the
buttons are defined by the <a>
element in a disabled
<fieldset>
, we should also ensure they won't be activated by
keyboard using the tabindex="-1"
attribute as we discussed in the
lesson about buttons.
Grid
Form controls are styled as blocks, meaning that they stretch to fill the
whole width of the page. If we have some more complex form, it may be useful to
place multiple controls in a single row, e.g. inputs for the first and last
name. If the inputs of a long form were all one under another, the form would
look even longer than necessary and would scare the user from filling the form.
For these purposes, we're going to use a grid which we'll discuss in detail
further in the course. Let's just mention that it allows us to define a grid
similarly to as the <table>
element. However, by reducing the
size of the browser window, the form controls will wrap underneath each other.
I.e. the grid is responsive.
<form> <div class="form-row"> <div class="form-group col-2"> <label for="signup-first-name">First name</label> <input type="text" class="form-control" placeholder="First name" id="signup-first-name"> </div> <div class="form-group col"> <label for="signup-last-name">Last name</label> <input type="text" class="form-control" placeholder="Last name" id="signup-last-name"> </div> </div> </form>
In the code above, the first name occupies 2 times more space than the last
name. We've achieved this using the .col-2
class. Of course, we can
also use other numbers or set the same size just by using the .col
class. We can also force the component to occupy only as less space as necessary
using the .col-auto
class. The example code above looks like this
in the browser:
Instead of .form-row
we could also use the standard
.row
class, but the gap between controls would be larger which
don't look good in forms. If your form is even more complex, you can make use of
other classes of the Bootstrap grid system and specify how much space should
columns take etc. We can use this for smart placement of labels next to the
controls if we don't want them above. We'd assigning the
.col-form-label
class to the <label>
elements in
this case. Similarly, by assigning the .col-form-legend
class, we
can style the <legend>
elements. We can specify different
label sizes for controls of different sizes as well by assigning the
.col-form-label-sm
and .col-form-label-lg
classes. The
labels in the example below wrap when the form is reduced in size.
We'll discuss all this in depth in the lesson about the grid system
Inline forms
It's sometimes useful to place smaller forms in a single row. For example,
this is a common solution for filtering products in e-shops. We can render a
form in a single row by assigning the .form-inline
class to the
<form>
element. On smaller viewports, the elements will wrap
one under another again. If we needed to add some own elements into such a form,
we should know that the inline rendering is implemented by
display: flex
. We use the margin and flex utility classes to
position something in such a form, see further in the course. In inline forms,
we often hide the <label>
elements using the
.sr-only
class, however, we still place them inside.
If we needed a small hint text in the inline form, a similar one we used in
the block form, we could use the .text-muted
class. We usually
assign this class to the <small>
element. The
.form-text
class is only for block forms.
In the next lesson, Bootstrap - Advanced forms, we'll continue with the client-side validations, custom styles for checkboxes, and other form controls and input groups.