Using flex to achieve two rows and one column layout [duplicate] - html

This question already has answers here:
Make a div span two rows in a grid
(2 answers)
Closed 3 years ago.
I'm trying to use flexbox to achieve a column layout with an element "floated" to the right.
Something like this:
Thing is, I cannot alter the HTML since it's an embedded form so trying to achieve this via pure CSS.
So far, I have this:
.form {
display: flex;
flex-direction: column;
text-align: center;
}
.form-container {
display: flex;
flex-direction: column;
text-align: center;
justify-content: space-between;
}
.form-form {
width: 100%;
}
form {
display: flex;
justify-content: center;
}
fieldset {
border: 0;
}
textarea {
resize: none;
}
.form-columns-2 {
display: flex;
}
.form-columns-2 input:first-child {
margin-bottom: .5em
}
.form-columns-1 textarea {
height: 100%
}
.submit-wrapper{
flex-direction:column;
}
<div class="form">
<div class="form-container">
<div class="form-form">
<form>
<fieldset class="form-columns-2">
<input type="text" placeholder="test">
<input type="text" placeholder="test">
</fieldset>
<fieldset class="form-columns-2">
<input type="text" placeholder="test">
<input type="text" placeholder="test">
</fieldset>
<fieldset class="form-columns-1">
<textarea placeholder="test">Text</textarea>
</fieldset>
<div class="submit-wrapper">
<div class="actions">
<input type="submit" value="Submit">
</div>
</div>
</form>
</div>
</div>
</div>
Edit:
I also need the submit button to sit under the textarea, but since the .submit-wrapper is a direct child of form, the only way I can see addressing this is by adding flex-direction: column; to form. However, this turns the whole layout into a column, which I do not want.

You are apllying display: flex to the wrong elements and to more elements than you need to.
Check this: https://codepen.io/anon/pen/dwPoEP
* {
box-sizing: border-box;
}
fieldset{
border:0;
}
textarea{
resize:none;
}
form { // you want the form to be a flex box, not everything!
display: flex;
justify-content: center;
}
.form-columns-2 {
display: flex; //you can use other options here, this works but you can use display: block on the inputs for example
}
// this 2 are just to make it look like the image
.form-columns-2 input:first-child {
margin-bottom: .5em
}
.form-columns-1 textarea {
height: 100%
}

Related

How to make div elements appear inline with a flex direction of column?

I am trying to get the text input on the same line as the h1 tag inline then display it as a flex-direction of column. But it only seems to want to set all the inputs in a line and with the h1 on top which is not what I want.
Here is what I mean.
here is the desired output:
.contactuscontent{
border: 1px solid pink;
display: flex;
}
.contactusinput {
display: inline-flex;
flex-direction: column;
border: 1px solid purple;
}
<div class="contactuscontent">
<div class="contactusinput">
<div class="name"><h1>Name</h1> <input type="text"> </div>
<div class="email"><h1>Email</h1> <input type="text"> </div>
<div class="refer"><h1>How did you find us</h1> <input type="text"> </div>
</div>
</div>
You should look into semantics of HTML, <h1> is used for headlines.
If you want to add labels for input fields you should use <label for="...">. You can style the any tag in any way you want so default styling should not be a reason to use a tag at all.
.contactuscontent {
border: 1px solid pink;
display: flex;
justify-content: center;
}
.contactusinput {
width: 400px;
border: 1px solid purple;
}
.contactusinput>div {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.contactusinput label {
width: 200px;
}
.contactusinput input,
.contactusinput textarea {
width: 200px;
padding: 3px;
}
<div class="contactuscontent">
<div class="contactusinput">
<div class="name"><label for="name">Name</label> <input type="text" id="name" name="name"> </div>
<div class="email"><label for="email">Email</label> <input type="text" id="email"> </div>
<div class="refer"><label for="howtofind">How did you find us</label> <textarea id="howtofind"> </textarea> </div>
</div>
</div>
That's because h1 is a block element, and since it's inside an un-styled div, it will push the input in a new line.
If you make the div that wraps the h1 and the input as flexbox, it will look similar to the image:
.contactusinput div {
display: flex;
}
You don't need flexbox on any of the parents for this to work.
To push inputs in the same line you can add min-width to the h1:
h1 {
min-width: 200px;
}
You will need to apply different styling to smaller screens, likely removing the min-width and showing the h1 in a column instead of row.
Here is a jsFiddle
By the way, heading elements h1-h6 aren't meant for this. You generally want to have only one h1 in the entire site. The better option to use here would be label.
To make the design you want, it is needed to set flexbox on the div which contains input and h1.
So in this case, there will be 3 divs to have the flexbox design and all of them are the direct childs of .contactusinput selector.
So on style, you can set the .contactusinput > div (direct div child of .contactusselector) style to flexbox as follows.
.contactuscontent {
border: 1px solid pink;
display: flex;
}
.contactusinput {
display: inline-flex;
flex-direction: column;
border: 1px solid purple;
}
.contactusinput > div {
display: flex;
justify-content: space-between;
align-items: center;
}
<div class="contactuscontent">
<div class="contactusinput">
<div class="name"><h1>Name</h1> <input type="text"> </div>
<div class="email"><h1>Email</h1> <input type="text"> </div>
<div class="refer"><h1>How did you find us</h1> <input type="text"> </div>
</div>
</div>

Aligning elements horizontally adjacent that are in different grid cells with CSS Grid and Flexbox

Currently I'm using a mixture between grid and flexbox to try and achieve a layout for a form.
I would like both input elements to horizontally lineup without setting a height on them. If I were to apply for padding on the text input, the range should continue to vertically center with the input adjacent to it.
Additionally I would like the label elements to also remain horizontally aligned too.
Please suggest solutions that DO NOT require changing the markup or using Javascript.
Currently what I have:
What I'm trying to achieve:
I know I could apply a fixed height or padding on the range to align it but I'm trying to make this as fluid as possible.
HTML:
<form class="grid">
<div class="group">
<label for="input-1">Label 1</label>
<input type="text" id="input-1" placeholder="placeholder" />
</div>
<div class="group">
<label for="input-2">Label 2</label>
<div class=range-wrapper>
<input type="range" id="input-2" placeholder="placeholder" />
<output>0</output>
</div>
</div>
</form>
SCSS:
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2rem;
}
.grid {
width: 80%;
max-width: 960px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 40px 10px;
padding: 50px;
background: #ccc;
}
.group {
display: flex;
flex-direction: column;
margin-top: auto;
label {
margin-bottom: 10px;
}
}
input {
font-size: inherit;
&[type="text"] {
padding: 14px;
}
&[type="range"] {
width: 100%;
}
}
.range-wrapper {
display: flex;
align-items: center;
output {
padding: 10px;
}
You can also check out the codepen here.
Many thanks!
** EDIT **
Should support multiline labels, if the label wraps multiple lines, elements should still horizontally align.
Multiline label example: Codepen
try this for your "group" class.
(or use a new class for that element with this styling)
.group {
display: flex;
flex-direction: column;
justify-content: center;
label {
margin-bottom: 10px;
}
}

Positioning input tag cursor after resizing

I have a simple input tag in a form element
<form>
<input type="text" name="" value="">
</form>
I wanted the input tag to look really big. So I add this:
input {
height: 300px;
}
However, the problem which bugs me is that the cursor of the input tag is located exactly at the centre of the height.
I want the cursor to be at the very top. How do I position the cursor?
Input is a one-line thing - so there is no sence to have it larger then caret.
That's why you have a choice between two options.
To use a large font with the input element:
<div class="input-wrapper">
<form>
<input type="text" name="" value="">
</form>
</div>
<style>
input {
font-size: 100px;
width: 50vw;
}
.input-wrapper {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
body {
margin: 0;
}
</style>
Or use textarea:
<div class="textarea-wrapper">
<textarea rows="25" cols="100"></textarea>
</div>
<style>
.textarea-wrapper {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
body {
margin: 0;
}
</style>

Vertical centering with flex box not working even with most basic code

I'm sure this is a duplicate question but I've eliminated almost everything from my code and still can't get it to work. I am new to Flexbox and tried to follow the code at https://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/ (as an aside, even that code doesn't work!). I am using Safari 11.1.1 and Chrome 67.0.3396.87 so it's not that they're old browsers.
I'm trying to center a <div> horizontally and vertically on the screen. The div contains a form which contains a couple of inputs and a button. I'm trying to center each of this horizontally and the group should be entered vertically within the <div>.
In Safari,nothing is centred. In Chrome, the div is centred horizontally but not vertically, but the inputs/button are not centred either horizontally and vertically.
body {
background: grey;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#holder {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 300px;
height: 300px;
background: white;
}
<div id="holder">
<form action="">
<input type="text" placeholder="something">
<input type="text" placeholder="something else">
<button>An Action</button>
</form>
</div>
What am I missing? As said, even the sample code from the site mentioned above didn't work correctly, so I'm quite stumped.
You need to set height:100vh in body, or set height:100% on html,body
And center items in forms, use flexbox properties in form instead of #holder
body {
margin: 0;
height: 100vh;
background: grey;
display: flex;
justify-content: center;
align-items: center;
}
#holder {
width: 300px;
height: 300px;
background: white;
}
form {
display: flex;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
}
form>* {
margin-bottom: 20px
}
<div id="holder">
<form action="">
<input type="text" placeholder="something">
<input type="text" placeholder="something else">
<button>An Action</button>
</form>
</div>

Flex items overflowing in Firefox [duplicate]

This question already has answers here:
input / button elements not shrinking in a flex container
(7 answers)
Why don't flex items shrink past content size?
(5 answers)
Closed 5 years ago.
I'm trying to create a form with first row a single text field 100% width and 2nd row 3 fields equidistant. It works fine on Chrome. However it's overflowing on FireFox.
.form {
display: flex;
flex-direction: column;
width: 300px;
justify-content: center;
align-items: center;
margin: 0 auto;
}
.form input {
width: 100%;
padding: 20px;
}
.form .number {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.form .expiry {
display: flex;
width: 100%;
justify-content: space-between;
}
<div class="form">
<div class="number">
<input data-stripe="number" placeholder="Credit Card Number" class="" type="text">
</div>
<div class="expiry">
<input data-stripe="exp-month" placeholder="MM" class="" type="text">
<input data-stripe="exp-year" placeholder="YY" class="" type="text">
<input data-stripe="cvc" placeholder="CVC" class="" type="text">
</div>
</div>
https://jsfiddle.net/xhr031yr/2/
You will need to set:
.form .expiry input {
min-width: 0;
}
jsFiddle
The reason is flex items have min-width:auto set by default, and for a replaced element such as <input>, it has intrinsic dimensions. The flex item won't shrink when the total width of the input boxes exceeded.
You can also give the size attribute a smaller value (default is 20 for text input) to make it smaller:
<input type="text" size="3">
References
Automatic Minimum Size of Flex Items
Replaced elements
HTML <input> attribute size
I can't tell you why that's happening, my guess is the way the browser handles the input element.
You can achieve the layout by...
Add the box-sizing rule.
Wrapping the inputs in a container
fiddle
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.form {
display: flex;
flex-direction: column;
width: 300px;
justify-content: center;
align-items: center;
margin: 0 auto;
}
.form input {
width: 100%;
padding: 20px;
}
.form .number {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.form .expiry {
display: flex;
width: 100%;
justify-content: space-between;
}
<div class="form">
<div class="number">
<input data-stripe="number" placeholder="Credit Card Number" class="" type="text">
</div>
<div class="expiry">
<div class="input">
<input data-stripe="exp-month" placeholder="MM" class="" type="text">
</div>
<div class="input">
<input data-stripe="exp-year" placeholder="YY" class="" type="text">
</div>
<div class="input">
<input data-stripe="cvc" placeholder="CVC" class="" type="text">
</div>
</div>
</div>
<!---->