使用 flexbox 设计表单样式——标签溢出嵌套的 flexbox div

Styling a form with flexbox -- labels overflowing nested flexbox divs

这可能是重复的,但我已经在 Whosebug 上解决了大约 20 "flexbox overflowing children" 个问题,但没有找到我的特定问题的答案......所以如果这个 重复并且有人已经回答了这个特定问题我真的非常感谢 link :) 在此先感谢您的任何建议 :)


我正在设计一个预生成的表单,更改 html 在这种情况下不切实际。 has 是一个简单的,我不敢相信我忽略了那个! css 解决这个...

我对这种样式的意图是,如果可能的话,我希望每个单独的标签都保持在一行上,而不是挤压得更窄和环绕。如果这意味着一个单选按钮 + 标签延伸整个表单的宽度,那很好,但我只希望标签(加上单选输入)比表单宽时换行。同时,如果表单项 div 不能全部放在一行中,我希望它们在必要时换行。我正在使用嵌套的 flexboxes,因为我希望能够垂直居中我的单选按钮和标签。不幸的是,根据包含元素的宽度,"form-item" div 正在挤压自己以适应一行并且其中的标签溢出!

我已将表单简化为一个非常基本的测试用例。你可以see it on codepen。这是 html 和 scss:

html:

<form>
    <div class="container">
        <div class="form-item form-item--1">
            <input type='radio' id='item1' name='group'>
            <label for='item1'>The quick brown fox</label>
        </div>
        <div class="form-item form-item--2">
            <input type='radio' id='item1' name='group'>
            <label for='item1'>The quick brown fox</label>
        </div>
        <div class="form-item form-item--3">
            <input type='radio' id='item1' name='group'>
            <label for='item1'>The quick brown fox</label>
        </div>
        <div class="form-item form-item--4">
            <input type='radio' id='item1' name='group'>
            <label for='item1'>The quick brown fox</label>
        </div>
    </div>
</form>

scss:

.container {
    // setting the container div to a width that provokes this issue... 
    max-width: 45em; 

    // the form-item child divs should be wrapping at this width, but instead their contents are overflowing!!!
    display: flex;
    flex-wrap: wrap;
}

.form-item {    
    // put 20px between this element and the next element to the right
    margin-right: 20px; 
    // make each div at least as wide as its content, and have them expand to fill all available space.
    flex: 1 0 auto; 

    display: flex; // <-- If the form-item divs are not flexboxes, the contents do *not* overflow. Instead the last div wraps as desired. Of course, then the contents are not vertically centered, and the flex-bases of the input and labels are ignored. For those reasons, I *really* want to use display: flex here!!! 

    input {
        // make the radio button take up exactly 25px of horizontal space
    flex: 0 0 25px;
    }

    label {     
        // make the label at least as wide as its content, and have it expand to fill all available space.
        flex: 1 0 auto; 
    }
}



// styling to better display the situation, but shouldn't affect the issue. (You can comment all the following out, and the labels are still overflowing their form-item parent div)
html {
    font-size: 62.5%;
}

body {
    font-size: 16px;
}

.container {
    align-items: center;
    border: 1px dashed black;
    height: 100px;
}

.form-item {
    align-items: center;
    border: 1px dashed green;
    height: 50px;

    label {
        border: 1px dashed orange;
    }
}

您应该试试下面的代码。如您所料,这种变化非常微妙。我只是将输入的样式从使用 25px 的 flex-basis 更改为 auto 并将宽度设置为 25px。

SCSS

.container {
    max-width: 45em;
    display: flex;
    flex-wrap: wrap;
}

.form-item {    
    margin-right: 20px;
    flex: 1 0 auto;
    display: flex; 

    input {
        width: 25px;
        flex: 0 0 auto;
    }

    label {
        flex: 1 0 auto; 
    }
}

html {
    font-size: 62.5%;
}

body {
    font-size: 16px;
}

.container {
    align-items: center;
    border: 1px dashed black;
    height: 100px;
}

.form-item {
    align-items: center;
    border: 1px dashed green;
    height: 50px;

    label {
        border: 1px dashed orange;
    }
}