'Always position button at the bottom of a form using flexbox

I've created a Fiddle here: http://jsfiddle.net/gonw4udf/1/

I have a form that we want to be of a minimum height. Sometimes, the form only has very few fields which means that the "Submit" button immediately follows the last field. However, we want the "Submit" button to always be positioned at the bottom of its container.

I'm wondering if there is a way to do so without having to rely on position: absolute.

To clarify: If the form is taller than the minimum height, it's okay to put the "Submit" button immediately after its last field. However, for forms that are shorter than the minimum height, we always want the "Submit" button at the bottom of the form. There may be multiple valid heights for these form so a solution that doesn't rely on hard coding a pixel value would be best.

.form-wrapper {
  max-width: 300px;
  width: 300px;
  background-color: #D2B4DE;
  padding: 20px 30px;
  min-height: 300px;
}

.form {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  margin: 0 auto;
}

.form-title {
  font-weight: bold;
  font-size: 28px;
  margin-bottom: 8px;
}

.button {
  margin-top: 10px;
  justify-content: flex-end;
  align-items: baseline;
}
<div class="form-wrapper">
  <form class="form">
    <div class="form-title">
      This is a form title.
    </div>
    <label for="field">Field</label>
    <input type="text" id="field" placeholder="Enter a field" />

    <button class="button">Submit</button>
  </form>
</div>


Solution 1:[1]

Your form does not fill its container, you can use either min-height: 100% or set the container as a flex box too (easier way, no need to mind about margins then).

Once this done, the button should go down to the bottom of the form with an auto margin.

Possible example:

.form-wrapper {
  max-width: 300px;
  width: 300px;
  background-color: #D2B4DE;
  padding: 20px 30px;
  min-height: 300px;
  display:flex;/* NEW*/
}

.form {
  display: flex;
  flex-direction: column;
  gap:10px;/*NEW*/
  flex-wrap: wrap;
  margin: 0 auto;
}

.form-title {
  font-weight: bold;
  font-size: 28px;
  margin-bottom: 8px;
}

.button {
  margin-top:auto;/* MODIFIED*/
  align-items: baseline;
}
<div class="form-wrapper">
  <form class="form">
      <div class="form-title">
         This is a form title.
      </div>
      <label for="field">Field</label>
      <input type="text" id="field" placeholder="Enter a field" />

      <button class="button">Submit</button>
  </form>
</div>

Solution 2:[2]

Here is the solution with justify-content: space-between. To make this work I've added 1 div wrapping the form content and another div wrapping the button.

.form-wrapper {
  max-width: 300px;
  width: 300px;
  background-color: #D2B4DE;
  padding: 20px 30px;
  min-height: 300px;
  display: flex;
}

.form {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  margin: 0 auto;
  flex: 1;
  justify-content: space-between;
}

.form-content {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}

.form-action {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}

.form-title {
  font-weight: bold;
  font-size: 28px;
  margin-bottom: 8px;
}

.button {
  margin-top: 10px;
  justify-content: flex-end;
  align-items: baseline;
}
<div class="form-wrapper">
  <form class="form">
    <div class="form-content">
      <div class="form-title">
        This is a form title.
      </div>
      <label for="field">Field</label>
      <input type="text" id="field" placeholder="Enter a field" />
    </div>
    <div class="form-action">
      <button class="button">Submit</button>
    </div>
  </form>
</div>

Solution 3:[3]

I have solved your issue and that is, you need to specify some height to the .form-wrapper and then give height: 100%; to form and then give margin-top: auto to the .button. AND YOU ARE DONE... This is happening because your form is not filling the content-space of the .form-wrapper. Moreover, margin-top: auto; takes the available space of the wrapper. There is another way using position: absolute; but that is very error prone, I don't suggest you doing that. However, If you want I can tell you that too. The solution by Nik is also a good way to deal with this situation

.form-wrapper {
  max-width: 300px;
  width: 300px;
  background-color: #D2B4DE;
  padding: 20px 30px;
  min-height: 300px;
  height: 10vh;
  margin:0 auto;
}

.form {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  margin: 0 auto;
  height: 100%;
}

.form-title {
  font-weight: bold;
  font-size: 28px;
  margin-bottom: 8px;
}

.button {
  margin-top: auto;
  justify-content: flex-end;
  align-items: baseline;
}
<div class="form-wrapper">
  <form class="form">
    <div class="form-title">
      This is a form title.
    </div>
    <label for="field">Field</label>
    <input type="text" id="field" placeholder="Enter a field" />

    <button class="button">Submit</button>
  </form>
</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 G-Cyrillus
Solution 2 Nik
Solution 3