如何使文本输入框占据父块中剩余的所有宽度?

42

如何实现以下功能:

┌────────────────────parent────────────────────┐
│ label [text-box                   ] [button] │
│ paragraph                                    │
└──────────────────────────────────────────────┘
  • label 左对齐
  • button 右对齐
  • text-box 占据其父元素剩余的宽度
  • paragraph 左对齐,必须与 label 左对齐

无论如何,labelbutton 都应该尽可能遵循在其他地方定义的字体属性。 parent 在窗口中心对齐,并且可以具有任意宽度。

请给予建议。

6个回答

53

更新 [2016年10月]: 弹性框架版本...

form {
  display: flex;
}
form input[type="text"] {
  flex: 1;
}
<form>
  <label>Name</label>
  <input type="text" />
  <button>Submit</button>
</form>
<p>Lorem ipsum...</p>

原始回答[2011年4月]: 不使用表格的CSS版本(表格行为)...

<div id="parent">
    <div id="inner">
        <label>Name</label>
        <span><input id="text" type="text" /></span>
        <input id="submit" type="button" value="Submit" />
    </div>
    <p>some paragraph text</p>
</div>

CSS...

#inner {
    display: table;
    width: 100%;
}
label {
    display: table-cell;
}
span {
    display: table-cell;
    width: 100%;
    padding: 0px 10px;
}
#text {
    width: 100%;
}
#submit {
    display: table-cell;
}

演示:http://jsfiddle.net/wdm954/626B2/4/


当父级块给出极端宽度时,它看起来很好。将其拉伸,标签文本和文本输入框之间将会有一个大洞。将其压缩,标签和按钮节点内的文本将会折叠。这就是我正在努力解决的问题的本质。 - user422039
很酷,谢谢,现在它完全独立于父元素的宽度。 - user422039
是的,它很棒,但在IE7中不起作用,因为它不支持display: table-cell;。 - jasin_89
这是在IE7中解决问题的方法:https://dev59.com/kG435IYBdhLWcg3wxDL_ - jasin_89

13

我不喜欢第一个答案的“无表格”版本,实际上它使用了table-cell。也不喜欢使用实际表格的第二个答案。第三个答案使用了硬编码宽度。这里有一个使用flex的解决方案。迄今为止,这是最简单的:

#parent {
  display: flex;
}
input {
  flex: 1;
}
<div id="parent">
  <label>Name</label>
  <input type="text" />
  <button>Button</button>
</div>
<div>paragraph</div>


请注意,flex在Android 4.2浏览器中无法使用,因此无法构建跨平台的Cordova应用程序。Flex可以简化很多事情,我非常喜欢它,但为了兼容性,在未来一两年内我们必须使用浮点数代替。 - Brian Cannard

10

使用表格。 :D 我知道人们倾向于讨厌表格,但在这种情况下它们会起作用...

<div id="parent">
    <table style="width:100%">
        <tr>
            <td>label</td>
            <td style="width:100%">
                <input type="text" style="width:100%">
            </td>
            <td>
                <button>clickme</button>
            </td>
        </tr>
    </table>
</div>

现在我很好奇它是如何工作的,因为它可以(没有预定义的宽度,甚至百分比)。 - user422039
因为表格单元格的定义是一直延伸到下一个单元格或行或表格的末尾,所以您不必指定它。 - Thomas Shields
2
爱因斯坦说:“要使一切尽可能简单,但不可过于简单。”这是你表格方案的论据。奥卡姆也会同意,并去除啰嗦的div解决方案。有些人相信童贞诞生,有些人则不使用表格。必须有信仰。就是这样。 - mathheadinclouds
当您将按钮放在输入框之前并为其分配float:right,并将输入框包装在具有display:blockoverflow:hidden的span中时,它可以在没有表格的情况下工作。没有任何魔法涉及到: <div style="width:100%"><button style="float:right">clickme 2</button><button style="float:right">clickme 1</button><label style="float:left">label</label><span style="display:block;overflow:hidden"><input type="text" style="width:100%"/></span></div>。基本思想是所有右侧按钮按相反顺序指定。 - Brian Cannard

2

不要忘记,你可以使用calc()函数。假设labelbutton的总宽度为100像素(包括外边距),那么宽度为:

.text-box {    
  width: calc(100% - 100px);
}

如果你认为它不支持很多浏览器,那么你确实是错的。现在它支持很多浏览器了。时代已经改变。


1
哇!看起来这个支持得相当久远,甚至到IE9。我很惊讶为什么没有更多人使用它。 - SouthShoreAK

2
我知道实现此类效果的唯一方法是将“文本框”作为一个块级元素,并自动填充其父容器的整个宽度,然后在左右分别应用与左右容器总宽度相等的内边距。然后将“标签”和“按钮”元素设置其位置属性为相对定位,并将它们浮动到所需位置(float: left,float: right)。
类似以下代码:
HTML:
<div id="parent">
    <div id="label">label</div>
    <div id="button">button</div>
    <div id="text-box">
        text<br />
        text<br />
        text<br />
        text<br />
        text
    </div>
</div>

CSS(层叠样式表):
div#label
{
    position: relative;
    float: left;
    width: 200px;
    background: #F00;
}

div#button
{
    position: relative;
    float: right;
    width: 120px;
    background: #0F0;
}

div#text-box
{
    padding-left: 200px;
    padding-right: 120px;
    background: #00F;
}

如果按钮和标签元素不需要设置宽度,所有元素的宽度都可以设置为百分比值(总和为100%)。

不幸的是,按钮块浮动文本框块上方,覆盖了其内容(尝试:opacity:0.75)。另外,请查看我对wdm关于百分比宽度脆弱性答案的评论。 - user422039
你可以通过给body设置最小宽度来避免左右元素的折叠 - 我不确定你所说的标签文本和文本输入之间的空隙是什么意思 - 我的解决方案确保文本框的内容始终紧贴在输入元素的右侧。 - Marty
标签和按钮元素都重叠在文本框区域上。但由于填充的应用,该区域内的内容永远不会在后面或下面。 - Marty
当您将按钮放在输入框之前并为其分配 float: right,并将输入框包装在具有 display: blockoverflow: hidden 的 span 中时,它可以在没有表格的情况下工作。没有什么神奇的: <div style="width:100%"><button style="float:right">clickme 2</button><button style="float:right">clickme 1</button><label style="float:left">label</label><span style="display:block;overflow:hidden"><input type="text" style="width:100%"/></span></div>。基本思想是所有右侧按钮按相反顺序指定。 - Brian Cannard

0

如果分配 float: right 并将按钮(或多个按钮按相反顺序放在输入框之前,则无需使用 flex 和表格即可正常工作。

然后使用 float: left 放置标签,给输入框100%宽度并将其包装在一个带有display: blockoverflow: hidden中。

没有任何魔法涉及:

<div style="width:100%">
  <button style="float:right">clickme 2</button>
  <button style="float:right">clickme 1</button>
  <label style="float:left">label</label>
  <span style="display:block;overflow:hidden">
    <input type="text" style="width:100%"/>
  </span>
</div>

所有右侧按钮的基本思想是在输入框之前以相反的顺序指定。


对于那些需要标签将点击和轻拍传递到输入框并将其包装的人,padding-right: 100%margin-right: -100%是唯一的解决方案。但是会发现它使按钮无法点击。我喜欢这个建议https://dev59.com/J2855IYBdhLWcg3wViot#4408709。完整的解决方案在这里:http://codepen.io/avesus/pen/VpaPWK。 - Brian Cannard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接