如何拉伸一个元素的宽度,使其为100%减去其兄弟元素的宽度?

27

假设我有以下无序列表。按钮具有width: auto。如何为元素设置样式,以便#textField尽可能地拉伸,使#textField的宽度和按钮的宽度加起来等于100%?也就是说,#textField的宽度==(宽度的100%)-(按钮的计算宽度)。

<ul>
  <li>
    <input id="textField" type="text" /><input type="button" />
  </li>
</ul>
所以,例如,假设 li 的宽度为 100 像素:如果按钮的计算宽度为 30px,则#textField的宽度为 70px;如果按钮的计算宽度为 25px,则#textField的宽度将变为 75px。

您还需要考虑边距和填充属性。如果这些不是零,即使它是100%,也可能看起来不像。 - extraneon
你是否对我的回答进行了投票,如果是,为什么? - PointedEars
@PointedEars 我没有对任何答案进行投票。 - William Niu
谢谢回复。如果您发现它有用,我将感激反馈,因为它可以实现所需的效果“不使用table或JavaScript”,这一点乍一看可能并不明显。 - PointedEars
11个回答

53

你可以通过混用 floatoverflow: hidden 来快速实现这个效果:

<ul>
    <li>
        <input class="btn" type="button" value="Submit"/>
        <div class="inputbox"><input id="textField" type="text" /></div>
    </li>
</ul>

CSS:

ul { 
  list-style: none; 
  padding: 0; }
.btn { float: right; }
.inputbox { 
  padding: 0 5px 0 0;
  overflow: hidden; }
.inputbox input { 
  width: 100%;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box; }

预览(使用盒模型):http://jsfiddle.net/Wexcode/E8uHf/546/

以下是没有盒模型的样子:http://jsfiddle.net/Wexcode/E8uHf/


6
这个功能很好,但会改变HTML的顺序,导致键盘tab键的顺序也发生改变,这将使得许多使用键盘的用户困惑,因为按钮在文本输入框之前被聚焦。 - Doug
2
你不能只是用 tabindex 来解决任何标签顺序问题吗? - Jonah Bishop
3
这可能有所帮助,但请记住 tabindex 会覆盖整个文档的 Tab 键顺序,而不仅仅是表单。也就是说,任何具有正值 tabindex 的元素都将被移到 Tab 键顺序的前面,并在页面上任何其他元素之前进行导航。http://www.w3.org/TR/html401/interact/forms.html#adef-tabindex - Doug
3
对于一般的表格来说,设置选项卡顺序并不太困难。这个解决方案相当可靠。 - Ryley
1
只是一点提示:这被称为块级格式化上下文,请再看一下类似问题的解决方法。https://dev59.com/b3M_5IYBdhLWcg3wt1k0 - Roger
显示剩余4条评论

6

请试一下:

HTML

<ul>
  <li>
    <input id="textField" type="text" /><input value="Button!" class="btn"type="button" />
  </li>
</ul>

CSS

ul li {
    width:100%;
}

#textField, .btn {
    float:left;
}

#textField {
    width:70%;
}

.btn {
    width:auto;
}

这里有一个演示:

http://jsfiddle.net/andresilich/RkCvf/


以下是我为您准备的更多演示。

这个 演示使用CSS3的flex-box模型来拉伸 input 字段,而不需要指定宽度。但是IE8及以下版本不支持。


这个演示只使用CSS模拟表格。它支持IE8及以上版本。


我不想给 #textField 设置一个固定的宽度;我希望它可以自适应伸缩。例如,如果 li 的宽度是100像素,按钮的计算宽度是30像素,那么 #textField 将会是70像素;当按钮的计算宽度变成40像素时,#textField 会变成60像素。 - William Niu
3
你能否使用CSS3的flex-box?这里有一个演示:http://jsfiddle.net/andresilich/NFEab/ - Andres Ilich
这似乎是一个不错的替代方案,但IE似乎不支持它... :-/ - William Niu
1
您支持IE的多久版本?还有一种方法是使用display: table-cell属性来获得最终结果,尽管只支持IE8 +。 - Andres Ilich
又一个不错的建议!为什么不把这两个建议都放在你的答案里呢?我很愿意至少点赞这个答案。 - William Niu

5

使用支持CSS-2.x布局引擎的用户代理可以实现此功能:

  …
  <style type="text/css">
    .full-width {
      width: 100%;
    }

    .table {
      display: table;
    }

    .row {
      display: table-row;
    }

    .cell {
      display: table-cell;
    }
  </style>
</head>

<body>
  <ul class="table">
    <li class="row">
      <span class="cell full-width">
        <input type="text" id="textField" class="full-width" />
      </span>
      <span class="cell">
        <input type="button" value="foobar" />
      </span>
    </li>
  </ul>
</body>

以下浏览器测试结果为正面:

  • Chromium 16.0.912.75(开发版本116452 Linux),Apple WebCore 535.7
  • Chromium 16.0.912.63(开发版本113337 Linux),Apple WebCore 535.1

请注意,由于固定宽度,input元素上的填充和边距会产生干扰。

但是:我看不出任何理由为什么你不应该在这里使用table元素(表格和CSS可以混合使用)。从语义上讲,它是有意义的(表格将是可序列化的),兼容性很可能比上面的CSS display属性值更好:

<body>
  <ul>
    <li>
      <table class="full-width"
             summary="Input text field with &#8220;foobar&#8221; button">
        <tr>
          <td class="full-width">
            <input type="text" id="textField" class="full-width" />
          </td>
          <td>
            <input type="button" value="foobar" />
          </td>
        </tr>
      </table>
    </li>
  </ul>
</body>

有可能你一开始就应该只使用一个table元素。


不是我给你点踩,但我猜是因为你仍在使用表格进行布局,尽管已对其进行了样式处理。CSS纯粹主义者真的不喜欢这样做。 - Bryan Boettcher
1
那么也许那个人并没有真正阅读答案,因为我的解决方案中没有使用table元素。第二种变体只是一种替代方案。 - PointedEars
对已经支持你观点的人说教,为两个可行的替代方案点赞。 - Bryan Boettcher
2
你不应该使用表格的原因是表单数据不是表格形式的。 - Samuel Edwin Ward
@SamuelEdwinWard 取决于情况。试着这样看:我们有一个数据 - input 元素 - 它与其他数据 - 处理它的按钮 - 之间存在行关系。许多其他表单更明显是表格形式:标签与描述和引用它的表单控件(通过 for 属性)之间存在行关系。我宁愿使用可序列化的表格,如此处所示,并使用 summary 属性来描述其内容(以提高可访问性),而不是在浏览器中看到“仅 CSS”解决方案崩溃。但是,我将创建一个测试用例来查看“仅 CSS”解决方案的兼容性如何。 - PointedEars

3

我最终使用了一个表格,然后拉伸包含文本字段的单元格:

<ul>
  <li>
    <table>
      <tr>
        <td width="100%"><input width="100%" id="textField" type="text" /></td>
        <td><input type="button" width="auto" /></td>
      </tr>
    </table>
  </li>
</ul>

2
你有更好的建议吗,Litso? - William Niu
1
首先,CSS具有几个与表格元素相同的“显示”属性值。http://w3.org/tr/css21/visuren.html#propdef-display - reisio
3
我不认为仅仅因为解决方案使用了表格就立刻拒绝它是正确的。有时候它们是有用的。在所有提出的解决方案中,没有一个像这个那样简单。 - Ryley
我这样做是不对的。使用表格这种方式会破坏HTML的整个目的。 - reisio

-1

使用JavaScript来完成。 获取li的宽度减去button的长度,并将文本框的宽度设置为这个值。但要记住盒模型。如果没有JavaScript,我真的没有什么主意。


-1
/* ROBOTICCSS*/
/*  test in ff - works*/

ul{
width: auto;
padding: 0 80px 0 0;/* right padding >= button width */
list-style:none;
}

input.text_area{
width: 100%;
}

input.submit_button{
float: right;
margin: 0 -80px 0 0;/* match above value */
}

<!--HTML -->
<ul>
  <li>
      <input class="text_area" type="text" />
      <input class="submit_button" type="button" value="Submit"/>
  </li>
</ul>

欢迎来到Stackoverflow。感谢您提供的解决方案,如果您能在发布代码时添加一些描述,我们将更加感激。谢谢。 - Vivek

-1

这个怎么样?

<ul>
  <li>
    <input id='textField' style='width: 80%'/><input type='button' style='width: 20%'/>
  </li>
</ul>

我不想为它们中的任何一个显式设置宽度。 - William Niu

-1
<ul>
  <li style="position:relative; width:100%;">
    <input id="textField" type="text" style="position:absolute; left:0px; right:80px" />
    <input type="button" value="Submit" style="position:absolute; right:0; width:auto" />
  </li>
</ul>

调整 right:80px 以设置文本框和按钮之间的边距;


有趣的想法,但那并不起作用。当您将元素位置设置为绝对定位时,您需要明确设置位置和大小,这不是我想要的。我希望文本字段可以调整大小。 - William Niu
我定义了 leftright,使其锚定到其容器(必须具有 position:relative),而不是定义其大小,它是可调整大小的。 - Jeaf Gilbert
首先,由于某种原因,在Safari中right属性对我不起作用。其次,我不想定义right属性,因为我希望它能够自动调整到按钮的右侧。 - William Niu

-1

这几乎是期望的结果:

<!DOCTYPE html>
<html lang="en">
<head>
<style>
li { width: 100%; border: 1px solid black; display: block; text-align: justify; }
span { display: inline-block; }
span { width: 100%; }
#foo { display: inline-block; width: 90%; border: 1px solid red; }
#foo input { display: block; width: 100%; }
</style>
</head>

<ul>
  <li>
    <object id="foo"><input type="text"></object> <object><input type="button" value="1234567890"></object>
      <span></span>
  </li>
</ul>

</html>

-1

表格和定位完全不是必需的。答案是将一个元素向左浮动,另一个元素向右浮动。

http://jsfiddle.net/johnallan/HeUSN/

HTML:

<ul>
<li class="media attribution">
<button class="button" >Press Me</button>
<div class="copy">b blah blah blah blah blah blah blah blah blahblah blah blahblah blah blah  blah blah blahblah blah blahblah blah blahblah blah blah blah blah blahlah blah blah</div>
</li>
</ul>

CSS:

.media{ border:1px solid black }
.media, .copy{overflow:hidden; _overflow:visible; zoom:1;}
.media .button{float:left; margin-right: 10px;}

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