CSS:填充父容器的文本框

时间:2008-09-09 18:40:46

标签: css

我试图让<input type="text">(以下称为“文本框”)通过将width设置为100%来填充父容器。这有效,直到我给文本框填充。然后将其添加到内容宽度并且输入字段溢出。请注意,在Firefox中,这仅在将内容呈现为符合标准时才会发生。在怪癖模式下,另一个盒子模型似乎适用。

这是在所有现代浏览器中重现行为的最小代码。

#x {
  background: salmon;
  padding: 1em;
}

#y, input {
  background: red;
  padding: 0 20px;
  width: 100%;
}
<div id="x">
  <div id="y">x</div>
  <input type="text"/>
</div>

我的问题:如何让文本框适合容器?

注意:对于<div id="y">,这很简单:只需设置width: auto即可。但是,如果我尝试对文本框执行此操作,则效果会有所不同,文本框将其默认行数视为宽度(即使我为文本框设置了display: block)。

/编辑:大卫的“解决方案”当然会奏效。但是,我不想修改HTML - 我特别不想添加没有语义功能的虚拟元素。这是divitis的典型案例,我想不惜一切代价避免这种情况。这只能是最后的黑客攻击。

11 个答案:

答案 0 :(得分:22)

您可以使用<div>包围文本框,并提供<div> padding: 0 20px。您的问题是100%宽度不包括任何填充或边距值;这些值被添加到100%宽度之上,因此溢出。

答案 1 :(得分:21)

使用CSS3,您可以在输入上使用box-sizing属性来标准化他们的盒子模型。 这样的东西可以让你添加填充并具有100%的宽度:

input[type="text"] {
    -webkit-box-sizing: border-box; // Safari/Chrome, other WebKit
    -moz-box-sizing: border-box;    // Firefox, other Gecko
    box-sizing: border-box;         // Opera/IE 8+
}

不幸的是,这对IE6 / 7不起作用,但其余的都很好(Compatibility List),所以如果你需要支持这些浏览器,最好的选择就是戴维斯解决方案。

如果您想了解更多信息,请查看this brilliant article by Chris Coyier

希望这有帮助!

答案 2 :(得分:3)

由于Box-Modell的定义和实现方式,我不认为这个问题只有css解决方案。 (除了Matthew描述的内容:使用填充百分比,例如宽度:94%;填充:0 3%;)

然而,您可以构建一些Javascript代码来计算页面加载... hm上的动态宽度,并且每次调整浏览器窗口大小时,该值当然也必须更新。

我做过的一些测试的有趣副产品:Firefox 确实将输入字段的宽度设置为100%,如果另外加width: 100%;您还将max-width设置为100 %。这在Opera 9.5或IE 7中不起作用(尚未测试旧版本)。

答案 3 :(得分:2)

遗憾的是,纯CSS无法实现这一点;任何非平凡的灵活但受约束的UI行为都需要HTML或Javascript修改。 CSS3专栏在某种程度上会有所帮助,但在像你这样的场景中却没有。

大卫的解决方案是最干净的。这不是真正的divitis案例 - 你不是不必要地添加一堆div,或者给它们类似“p”和“h1”的类名。它服务于一个特定的目的,在这种情况下的好处是它也是一个可扩展的解决方案 - 例如然后,您可以随时添加圆角,而无需进一步添加任何内容。可访问性也不受影响,因为它们是空的div。

Fwiw,这是我实现所有文本框的方式:

<div class="textbox" id="username">
    <div class="before"></div>
    <div class="during">
        <input type="text" value="" />
    </div>
    <div class="after"></div>
</div>

然后你就可以自由地使用CSS来添加圆角,像你的情况一样添加填充等,但你也没必要 - 你可以完全隐藏那些边div并且只有一个常规输入文本框。

其他解决方案是使用表格,例如亚马逊使用表格来获得灵活但受限制的布局,或使用Javascript调整大小并在窗口大小调整上更新它们,例如Google文档,地图等都是这样做的。

无论如何,我的两分钱:在这种情况下,不要让理想主义妨碍实用性。 :) David的解决方案很有效,并且几乎不会混淆HTML(事实上,使用像“before”和“after”这样的语义类名仍然非常干净)。

答案 4 :(得分:1)

此行为是由盒子模型的不同解释引起的。正确的框模型表明宽度仅适用于内容,并且填充和边距添加到其上。因此,你的100%加上20px左右填充等于100%+ 40px作为总宽度。原始IE盒模型,也称为怪癖模式,包括宽度中的填充和边距。因此,在这种情况下,您的内容宽度将为100% - 40px。这就是为什么你会看到两种不同的行为。据我所知,没有解决办法,但是通过将宽度设置为98%并将每边的填充设置为1%,可以解决这个问题。

答案 5 :(得分:1)

@Domenic这不起作用。 width auto只执行该元素的默认行为,因为width的初始值为auto(参见第164页,层叠样式表Level 2 Revision 1 Specification)。分配类型块的显示也不起作用,这只是告诉浏览器在显示元素时使用块框,并且没有像div那样分配占用尽可能多空间的默认行为(参见第121页,层叠样式)表2级修订版1规范)。该行为由可视用户代理处理,而不是CSS或HTML定义。

答案 6 :(得分:1)

如何使文本框适合2019年的容器?

只需使用display:flex;

./assets/icons/manifest-icon-512.png"
#x {
  background: salmon;
  padding: 1em;
  display: flex;
  flex-wrap: wrap;
}

#y, input {
  background: red;
  padding: 0 20px;
  width: 100%;
}

答案 7 :(得分:0)

我相信你可以用负余量来抵消溢出。即

margin: -1em;

答案 8 :(得分:0)

默认的填充和边框会阻止您的文本框真正为100%,因此首先您必须将它们设置为0:

input {
    background: red;
    padding: 0;
    width: 100%;
    border: 0; //use 0 instead of "none" for ie7 
}

然后,将您想要的边框和任何填充或边距放在文本框周围的div中:

.text-box {
    padding: 0 20px;
    border: solid 1px #000000;
}

<body>
    <div id="x">
        <div id="y">x</div>
        <div class="text-box"><input type="text"/></div>
    </div>
</body>

这应该允许您的文本框可以扩展,并且无需javascript就可以获得所需的大小。

答案 9 :(得分:0)

要使输入内容填满父级,需要设置3个属性:width:100%,margin-left:0,margin-right:0。

我只是猜想零边距设置会有所帮助,并且我已经尝试过了,但是我不知道为什么要使零边距(左右边距;当然顶部和底部边距在这里不受影响)应该为零作品。 :-)

input {
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}

注意:您可能需要将box-sizing设置为border-box,以确保填充不会影响结果。

答案 10 :(得分:0)

我过去使用仅限CSS的表格来解决此问题。有点长的例子,但是 对于所有想为大量字段创建输入屏幕的人来说都很重要 用于数据库...

// GH

// NO JAVA !!! ;-)
html {
  height: 100%;
}

body {
  position: fixed;
  margin: 0px;
  padding: 0px;
  border: 2px solid #FF0000;
  width: calc(100% - 4px);
  /* Demonstrate how form can fill body */
  min-height: calc(100% - 120px);
  margin-top: 60px;
  margin-bottom: 60px;
}


/* Example how to make a data entry form */

.rx-form {
  display: table;
  table-layout: fixed;
  border: 1px solid #0000FF;
  width: 100%;
  border-collapse: separate;
  border-spacing: 5px;
}

.rx-caption {
  display: table-caption;
  border: 1px solid #000000;
  text-align: center;
  padding: 10px;
  margin: 10px;
  width: calc(100% - 40px);
  font-size: 2.5em;
}

.rx-row {
  display: table-row;
  /* To make frame on rows. Rows have no border... ? */
  box-shadow: 0px 0px 0px 1px rgb(0, 0, 0);
}

.rx-cell {
  display: table-cell;
  margin: 0px;
  padding: 4px;
  border: 1px solid #FF0000;
}

.rx-cell label {
  float: left;
  border: 1px solid #00FF00;
  width: 110px;
  padding: 4px;
  font-size: 1em;
  text-align: right;
  font-family: Arial, Helvetica, sans-serif;
  overflow: hidden;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rx-cell label:after {
  content: " :";
}

.rx-cell input[type='text'] {
  float: right;
  border: 1px solid #FF00FF;
  padding: 4px;
  background-color: #eee;
  border-radius: 0px;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 1em;
  /* Fill the cell - but subtract the label width - and litte more... */
  width: calc(100% - 130px);
  overflow: hidden;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

input[type='submit'] {
  font-size: 1.3em;
}
<html>
<meta charset="UTF-8">

<body>

  <!--                                                                                                                                                                                                                                                                             
        G Hasse, gorhas at raditex dot nu                                                                                                                                                                                                                                            
        This example have a lot of frames so we                                                                                                                                                                                                                                      
        can experiment with padding and margins.                                                                                                                                                                                                                                     
    -->

  <form>

    <div class='rx-form'>


      <div class='rx-caption'>
        Caption
      </div>


      <!-- First row of entry -->

      <div class='rx-row'>

        <div class='rx-cell'>
          <label for="input11">Label 1-1</label>
          <input type="text" name="input11" id="input11" value="Some latin text here. And if it is very long it will get ellipsis" />
        </div>

        <div class='rx-cell'>
          <label for="input12">Label 1-2</label>
          <input type="text" name="input12" id="input12" value="The content of input 2" />
        </div>

        <div class='rx-cell'>
          <label for="input13">Label 1-3</label>
          <input type="text" name="input13" id="input13" value="Content 3" />
        </div>

        <div class='rx-cell'>
          <label for="input14">Label 1-4</label>
          <input type="text" name="input14" id="input14" value="Content 4" />
        </div>

      </div>

      <!-- Next row of entry -->

      <div class='rx-row'>

        <div class='rx-cell'>
          <label for="input21">Label 2-1</label>
          <input type="text" name="input21" id="input21" value="Content 2-1">
        </div>

        <div class='rx-cell'>
          <label for="input22">Label 2-2</label>
          <input type="text" name="input22" id="input22" value="Content 2-2">
        </div>

        <div class='rx-cell'>
          <label for="input23">Label 2-3</label>
          <input type="text" name="input23" id="input23" value="Content 2-3">
        </div>

      </div>


      <!-- Next row of entry -->

      <div class='rx-row'>

        <div class='rx-cell'>
          <label for="input21">Label 2-1</label>
          <input type="text" name="input21" id="input21" value="Content 2-1">
        </div>

        <div class='rx-cell'>
          <label for="input22">Label 2-2</label>
          <input type="text" name="input22" id="input22" value="Content 2-2">
        </div>

        <div class='rx-cell'>
          <label for="input23">Label 2-3</label>
          <input type="text" name="input23" id="input23" value="Content 2-3">
        </div>

      </div>

      <!-- And some text in cells -->

      <div class='rx-row'>

        <div class='rx-cell'>
          <div>Cell content</div>
        </div>

        <div class='rx-cell'>
          <span>Cell content</span>
        </div>

      </div>



      <!-- And we place the submit buttons in a cell -->

      <div class='rx-row'>

        <div class='rx-cell'>
          <input type="submit" name="submit1" value="submit1" />
          <input type="submit" name="submit2" value="submit2" />
        </div>

      </div>

      <!-- End of form -->
    </div>
  </form>

</body>

</html>