Always position button at the bottom of a form using flexbox - html

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>

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>

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>

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>

Related

centering items even with or without labels

I have this on my codepen in which I was using flex to align items. What I want is to align items even with or without labels.
here is my html code:
<div class="parent-main">
<div class="child1">
<!--<label>checkbox</label> -->
<input type="text"/>
</div>
<div class="child2">
<label>checkbox</label>
<input type="checkbox"/>
</div>
<div class="child3">
<label>checkbox</label>
<input type="radio"/>
</div>
</div>
my css:
.parent-main {
display: flex;
justify-items: center;
border: solid 1px #ccc;
width: 55vh;
height: 25vh;
margin: 5px;
padding: 15px;
gap: 2px;
}
.child1 {
display: flex;
flex-direction: column;
/* position: relative;
top: 2px; */
}
.child2 {
display: flex;
flex-direction: column;
align-items: baseline;
}
.child3 {
display: flex;
flex-direction: column;
align-items: baseline;
}
Here is my codepen link: enter link description here
This is quite tricky on my side but I hope I can have your insights on this, been working this for 2 days now.
As you want to align the input of type "text" with the other div siblings but without it having any label element, we use a line break in order to mimic an empty blank space without any text element in it by using either <br> or
Tip:
Avoid duplication of codes in CSS properties, see the below snippet
.parent-main {
display: flex;
justify-items: center;
border: solid 1px #ccc;
width: 55vh;
height: 25vh;
margin: 5px;
padding: 15px;
gap: 2px;
}
.parent-main>div {
display: flex;
flex-direction: column;
}
.child2,
.child3 {
align-items: baseline;
}
<div class="parent-main">
<div class="child1">
<!--empty space -->
<br>
<!-- can also be used -->
<input type="text" />
</div>
<div class="child2">
<label>checkbox</label>
<input type="checkbox" />
</div>
<div class="child3">
<label>checkbox</label>
<input type="radio" />
</div>
</div>

How can I align three box in same line using flexbox in css?

In my project, I want to design a shipping address design with HTML and css(flexbox). And i want to design "city","zip code","state", box in one line like this
but in my code, I am unable to do like that design so help me to what changes should I have done to get that result?
And my code results shows is like this
So I want "city","zip code","state" box takes same size fit to the "ad
Here is my code
.shipping-containers {
height: 100vh;
width: 100%;
border: 2px solid black;
display: flex;
flex-direction: column;
flex-wrap: wrap;
background: red;
justify-content: center;
align-items: center;
}
.shipping-wrapper {
display: flex;
flex-direction: column;
width: 70%;
background: lightskyblue;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.shipping-wrapper>form {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 1px solid black;
}
.shipping-div {
display: flex;
flex-direction: row;
margin-right: 15rem;
justify-content: center;
align-items: center;
}
.shipping-div input {
text-align: center;
justify-content: center;
align-items: center;
}
.shipping-wrapper input {
width: 50%;
font-size: 10px;
padding: 15px;
background: #f1f1f1;
margin-bottom: 10px;
}
<div class="shipping-containers">
<div class="shipping-wrapper">
<form>
<input type="text" placeholder=" name" />
<input type="text" placeholder=" address" />
<div class="shipping-div">
<div>
<input type="text" placeholder=" city" class="shipping-input" />
</div>
<div>
<input type="text" placeholder=" zip code " class="shipping-input" />
</div>
<div>
<input type="text" placeholder=" state" class="shipping-input" />
</div>
</div>
<input type="text" placeholder=" Country" class="shipping-input" />
<button>Continue</button>
</form>
</div>
</div>
You have many borders included which are a mess to take into account. The easiest and cleanest solution is to use * { box-sizing: border-box; }. With that property, we don't have to take all the different borders into account.
You nested way too many Flexbox and used unnecessary div's. As such I removed all div's out of your form.
I used flex-wrap: wrap on your form. Then I raised the width from all the inputs to 100% and created the space left and right with padding on the form.
I changed justify-content: center to justify-content: space-between for your form.
I changed the flex-direction: column on the form to default row as otherwise, the flex-wrap will not work.
The width for the 3 small inputs must be calculated (that's why CSS-Grid would have been a better and easier solution). YOu have to take the 2x gaps a 10px each into account. So the width for the 3 elements in total is 100% - 20px. That again must then be divided by 3:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.shipping-containers {
height: 100vh;
border: 2px solid black;
display: flex;
flex-direction: column;
flex-wrap: wrap;
background: red;
justify-content: center;
align-items: center;
}
.shipping-wrapper {
display: flex;
flex-direction: column;
width: 70%;
background: lightskyblue;
justify-content: center;
align-items: center;
}
.shipping-wrapper > form {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
border: 1px solid black;
padding: 0 15%;
}
.shipping-wrapper input {
width: 100%;
font-size: 10px;
padding: 15px;
background: #f1f1f1;
margin-bottom: 10px;
}
.shipping-wrapper input:nth-child(3),
.shipping-wrapper input:nth-child(4),
.shipping-wrapper input:nth-child(5) {
width: calc((100% - 20px) / 3);
}
.shipping-wrapper button {
margin: 0 auto;
}
<div class="shipping-containers">
<div class="shipping-wrapper">
<form>
<input type="text" placeholder="name">
<input type="text" placeholder="address">
<input type="text" placeholder="city">
<input type="text" placeholder="zip code">
<input type="text" placeholder="state">
<input type="text" placeholder="Country">
<button>Continue</button>
</form>
</div>
</div>
Here's my take. Points to note: box-sizing: border-box is a must for the inputs.
.shipping-div has negative margin so children with margin would align to width (this is bootstrap trick). And the rest is trivial.
.shipping-containers {
height: 100vh;
border: 2px solid black;
display: flex;
background: #ff00007f;
justify-content: center;
align-items: center;
}
.shipping-wrapper {
width: 70%;
background: lightskyblue;
}
.shipping-wrapper>form {
border: 1px solid black;
}
.shipping-div {
display: flex;
justify-content: space-between;
margin-left: -5px;
margin-right: -5px;
}
.shipping-div>div {
margin-left: 5px;
margin-right: 5px;
width: 100%;
}
.shipping-wrapper input {
width: 100%;
min-width: 100%;
font-size: 10px;
padding: 15px;
background: #f1f1f1;
margin-bottom: 10px;
position: relative;
display: block;
box-sizing: border-box;
}
<div class="shipping-containers">
<div class="shipping-wrapper">
<form>
<input type="text" placeholder=" name" />
<input type="text" placeholder=" address" />
<div class="shipping-div">
<div>
<input type="text" placeholder=" city" class="shipping-input" />
</div>
<div>
<input type="text" placeholder=" zip code " class="shipping-input" />
</div>
<div>
<input type="text" placeholder=" state" class="shipping-input" />
</div>
</div>
<input type="text" placeholder=" Country" class="shipping-input" />
<button>Continue</button>
</form>
</div>
</div>

How to align button right in a flex container?

I don't know how to float my button right and I hope someone can help me out here.
The yellow color shows the background of the div. The width of the div is set to 50%.
.faq {
width: 100%;
padding: 12px 20px;
display: block;
box-sizing: border-box;
width: 50%;
margin: auto;
margin-top: 30px;
}
.outerDiv {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
margin-top: 20px;
background-color: yellow;
}
.save {
float: right;
background-color: red;
}
<div class="outerDiv">
<h2>New FAQ</h2>
<input type="text" class="faq">
<br>
<button class="save" mat-raised-button color="primary">Primary</button>
</div>
What am I doing wrong?
Floats do not work in a flex container
Use align-self:flex-end instead
.faq {
padding: 12px 20px;
display: block;
box-sizing: border-box;
width: 50%;
margin: auto;
margin-top: 30px;
}
.outerDiv {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
margin-top: 20px;
background-color: yellow;
}
.save {
align-self:flex-end;
background-color: red;
}
<div class="outerDiv">
<h2>New FAQ</h2>
<input type="text" class="faq">
<br>
<button class="save" mat-raised-button color="primary">Primary</button>
</div>
.faq {
width: 100%;
padding: 12px 20px;
display: block;
box-sizing: border-box;
width: 50%;
margin: auto;
margin-top: 30px;
}
.outerDiv {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
margin-top: 20px;
background-color: yellow;
}
.save {
margin-left:auto;
background-color: red;
}
<div class="outerDiv">
<h2>New FAQ</h2>
<input type="text" class="faq">
<br>
<button class="save" mat-raised-button color="primary">Primary</button>
</div>
Floats do not work with flex.
There are two approaches that you can take here.
Approach #1:
Use align-self: flex-end on the button. This would make the button appear in the rightmost corner of your parent.
Approach #2:
In case you want more control over the position of the button in terms of alignment with the text area, you can wrap the button in a div and keep the float right on the button.
HTML
<div class="button-wrapper">
<button class="save" mat-raised-button color="primary">Primary</button>
</div>
CSS
.button-wrapper {
width: 50%; /* same as the width of your input*/
}

input boxes shape restricted by parent div

I'd like to achieve the look for my login area similar to this photo.
My current HTML and CSS are as follows:
HTML
<div className="loginArea">
<p>Account Login</p>
<div className="inputBoxes">
<div>
<input type="text" placeholder="Username" />
<input type="password" placeholder="Password" />
</div>
<div>
<p>Sign In</p>
</div>
</div>
</div>
CSS
.loginArea {
margin: auto;
padding-top: 8%;
display: flex;
flex-direction: column;
height: 100%;
max-width: 400px;
justify-content: center;
}
.inputBoxes {
display: flex;
flex-direction: column;
justify-content: center;
border-radius: 15px;
background-color: blue;
}
.inputBoxes div {
display: flex;
justify-content: center;
}
input {
flex-grow: 1;
border: none;
}
My goal is to achieve the styling of this input area with respect to the shape of the inputs/sign in button as what look like one rectangle with rounded corners.
The problems I'm running into are two fold:
I can't seem to restrict the size of the input areas to the parent container. They run outside the parent div.
I can't seem to get the input areas to accept the restricted border-radius of the parent container.
Do I have to style each element individually for the rounded borders and how do I restrict the username and password areas to the width of the parent div?
If there are "better" approaches, I'm open to suggestions.
Since you're already using flexbox, the input element sizes seem to correctly fit inside the confines of the parents without any issue.
With regards to your second issue, adding overflow: hidden to the element .inputBoxes will work.
See proof-of-concept below:
body {
background-color: #ccc;
}
.loginArea {
margin: auto;
padding-top: 8%;
display: flex;
flex-direction: column;
height: 100%;
max-width: 400px;
justify-content: center;
}
.inputBoxes {
display: flex;
flex-direction: column;
justify-content: center;
border-radius: 15px;
background-color: blue;
overflow: hidden;
}
.inputBoxes div {
display: flex;
justify-content: center;
}
input {
flex-grow: 1;
border: none;
height: 35px; /* Just for demo */
}
<div class="loginArea">
<p>Account Login</p>
<div class="inputBoxes">
<div>
<input type="text" placeholder="Username" />
<input type="password" placeholder="Password" />
</div>
<div>
<p>Sign In</p>
</div>
</div>
</div>

Pin a button to the bottom corner of a container

I am using flexbox to center a form vertically and horizontally. Inside this form I'd like to pin a button to the bottom right of the flexbox container. I am not sure how to get the button pinned to the bottom right though.
html,
body {
height: 100%;
}
.container {
height: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
form {
border: 1px solid gray;
padding: 1em;
}
.form-button {
margin-top: 1em;
align-self: flex-end;
}
<div class="container">
<form>
<div class="form-input">
<label> Name <input type="text" /></label>
</div>
<div class="form-button">
<button type="submit">Submit</button>
</div>
</form>
</div>
You just need to make the form element a flex container, because flex properties only work between parent and child elements.
In other words, your align-self: flex-end on the .form-button is not working because the parent – form – does not have display: flex or display: inline-flex applied.
Here's a more complete explanation:
Proper use of flex properties when nesting flex containers
html, body {
height: 100%;
}
.container {
height: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
form {
border: 1px solid gray;
padding: 1em;
/* NEW */
display: flex;
flex-direction: column;
}
.form-button {
margin-top: 1em;
align-self: flex-end;
}
<div class="container">
<form>
<div class="form-input">
<label> Name <input type="text" /></label>
</div>
<div class="form-button">
<button type="submit">Submit</button>
</div>
</form>
</div>
.form-button {
margin-top: 1em;
align-self: flex-end;
display: flex;
justify-content: flex-end;
}
Just insert float: right;
like this:
.form-button {
float: right;<-----------added
//more code...
}
html,
body {
height: 100%;
}
.container {
height: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
form {
border: 1px solid gray;
padding: 1em;
}
.form-button {
margin-top: 1em;
float: right;
}
<div class="container">
<form>
<div class="form-input">
<label> Name <input type="text" /></label>
</div>
<div class="form-button">
<button type="submit">Submit</button>
</div>
</form>
</div>