Apply display:flex to a form

Viewed 10317

I'm trying to apply display:flex on this form and failing. The structure of the HTML cannot be changed and I can't for the life of me figure out how to go about it. The only way they all inline (including the button) is to apply flex on both the form and .form-fields. But when the form wraps, the button stays in the first row, while the input field for the last name goes into second.

What am I doing wrong? And what can I do with CSS only, without touching the HTML? Thank you!

form, .form-fields {
  display: flex;
}
<div class="form">
  <form>
    <div class="form-body">
      <ul class="form-fields">
        <li class="form-field">
          <div class="input-container">
            <span class="name_first">
              <input type="text" name="first_name" id="first_name" value="" placeholder="First Name *" required="">
            </span>
            <span class="name_last">
              <input type="text" name="last_name" id="last_name" value="" placeholder="Last Name *" required="">
            </span>
          </div>
        </li>
        <!--  name and last name -->

        <li class="form-field">
          <div class="input-container">
            <input name="email_address" id="email_address" type="email" value="" placeholder="Email *" required="">
          </div>
        </li>
        <!-- email adress -->
        <li class="form-field">
          <div class="input-container">
            <input name="phone_number" id="phone_number" type="tel" value="" placeholder="Phone *" required="">
          </div>
        </li>
        <!--  phone -->
      </ul>
      <input name="action" type="hidden" value="Request an Info Sheet">
    </div>
    <div class="form-footer">
      <button type="submit" class="form_button">
        <span>Contact Us</span>
      </button>
    </div>
    <!-- button -->
  </form>
</div>

3 Answers

Adding flex-wrap sends the button to the end of the next row:

form, .form-fields {
  display: flex;
  flex-wrap: wrap;
}

Flexbox has effect only on direct children. So if you do display:flex on a parent, all the direct children will be affected. The nested divs inside the child won't be affected. So display:flex on the form will make the .form-body and .form-footer behave as flex children so these two divs will be in a row.

Applying display:flex to .form-fields will make all direct children of .form-fields i.e lis with the class of .form-field into a flex item. So they will align horizontally.

The problem of the wrapping was because the first .input-container has two non flex children. So adding flex over there as well will make them stay inline.

So adding this css will horizontally align all items:

 form {
  display: flex;
  justify-content:center;
  align-items:center;
}
.form-fields, .input-container{
  display:flex;
}

I think this might be what you want to do. All I did was add: flex-direction: column;.

The default value for a flexbox is row. That will make the flex item a row and spread the children out over that row.

Setting value for a flexbox to column, will make the flex item a column and spread the children out over that column.

Hope it helps ;)

form, .form-fields {
  display: flex;
  flex-direction: column;
}
<div class="form">
  <form>
    <div class="form-body">
      <ul class="form-fields">
        <li class="form-field">
          <div class="input-container">
            <span class="name_first">
              <input type="text" name="first_name" id="first_name" value="" placeholder="First Name *" required="">
            </span>
            <span class="name_last">
              <input type="text" name="last_name" id="last_name" value="" placeholder="Last Name *" required="">
            </span>
          </div>
        </li>
        <!--  name and last name -->

        <li class="form-field">
          <div class="input-container">
            <input name="email_address" id="email_address" type="email" value="" placeholder="Email *" required="">
          </div>
        </li>
        <!-- email adress -->
        <li class="form-field">
          <div class="input-container">
            <input name="phone_number" id="phone_number" type="tel" value="" placeholder="Phone *" required="">
          </div>
        </li>
        <!--  phone -->
      </ul>
      <input name="action" type="hidden" value="Request an Info Sheet">
    </div>
    <div class="form-footer">
      <button type="submit" class="form_button">
        <span>Contact Us</span>
      </button>
    </div>
    <!-- button -->
  </form>
</div>

Related