Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Flexbox in a Form [duplicate]

Tags:

html

css

flexbox

I want to use the flex display property on my web form in order to have two text fields side-by side and automatically growing to fill the space. I chose to use flex over a table layout because I want them to move to their own line when the window shrinks.

I believe I am misunderstanding how to use flexbox.

Below is my work so far (simplified for posting here). I am using a fieldset as a flex parent, and each form element which should "grow" side-by-side is encased in a div (set to display: inline so they can be on the same line). I also have a legend for the fieldset, set to display:block and width:100% so that it will be on its own line.

jsFiddle link

fieldset {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    border: none;
}

label {
    display: none;
}

legend {
    display: block;
    width: 100%;
}

fieldset > div {
    display: inline;
    flex: 1 1 auto;
}

input {
    width: 100%;
}
<form>
    <fieldset>
        <legend>These are Text Fields</legend>
        <div>
            <input type="text" id="text1">
            <label for="text1">Text Field</label>
        </div>
        <div>
            <input type="text" id="text2">
            <label for="text2">More Text</label>
        </div>
    </fieldset>
</form>

As you can see, the divs are each on their own line (despite the display: inline and flexbox stuff). If you add a border to the div elements, you'll see that they are 100% width right now; but even if you manually define a width (like 30%), they remain on their own lines.

How can I use flex to display the divs side-by-side and allow them to scale to fill the parent's width?

like image 284
Woodrow Barlow Avatar asked Dec 09 '14 00:12

Woodrow Barlow


1 Answers

EDIT: This bug has been fixed in Firefox and Chrome. The example as originally posted in the question now works as intended.

https://bugzilla.mozilla.org/show_bug.cgi?id=1230207
https://bugs.chromium.org/p/chromium/issues/detail?id=375693


Two things here:

  1. When you do display: flex on an element, every single direct child is affected. So in your example (if it were working) the legend will also be displayed on the same line.

  2. For whatever reason, fieldset doesn't like to play nicely with flexbox. since you don't want the legend to be on the same line anyway, I would suggest specifically wrapping the elements you want to be on the same line.

<form>
    <fieldset>
        <legend>These are Text Fields</legend>
        <div class="flex-wrapper">
            <div>
                <input type="text" id="text1">
                <label for="text1">Text Field</label>
            </div>
            <div>
                <input type="text" id="text2">
                <label for="text2">More Text</label>
            </div>
        </div>
    </fieldset>
</form>
fieldset {
    border: none;
}

.flex-wrapper {
 
    display: flex;
    flex-direction: row;
    justify-content: space-between;   
    align-items: stretch;
}

.flex-wrapper > div {
    flex: 1 1 auto;
}

label {
    display: none;
}

legend {
    display: block;
    width: 100%;
}

input {
    width: 100%;
}

like image 117
ratherblue Avatar answered Nov 01 '22 17:11

ratherblue