3

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>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Retros
  • 3,511
  • 10
  • 40
  • 60
  • You want the elements to never wrap? – Kushtrim Nov 24 '17 at 13:32
  • https://stackoverflow.com/q/37840646/3597276 – Michael Benjamin Nov 24 '17 at 13:32
  • @Michael_B So, if I apply flex to form, its children are .form-body and .form-footer. and those get flex properties, right? I'd need to apply flex to them too, separately? And control how they react to wrapping. Did I get any of that right? Haha – Retros Nov 24 '17 at 13:45
  • 1
    What exactly are you trying to achieve? Why did you resort to using flexbox? – Rob Monhemius Nov 24 '17 at 13:49
  • @RMo I'm trying to inline this form and make it so that when it wraps, it wraps as you'd expect it: all input fields first and then button at the end. Sorry if my explanation is a mess. And about flexbox, I'm not sure. I thought that would work best? – Retros Nov 24 '17 at 13:52
  • Did you figure out a solution? – Rob Monhemius Dec 22 '17 at 09:44

3 Answers3

4

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

form, .form-fields {
  display: flex;
  flex-wrap: wrap;
}
dom_ahdigital
  • 1,651
  • 18
  • 37
1

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;
}

Reuben B
  • 184
  • 1
  • 6
0

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>
Rob Monhemius
  • 4,822
  • 2
  • 17
  • 49