【问题标题】:How can I make a TextArea 100% width without overflowing when padding is present in CSS?当 CSS 中存在填充时,如何使 TextArea 的宽度为 100% 而不会溢出?
【发布时间】:2010-09-21 05:27:30
【问题描述】:

我正在渲染以下 CSS 和 HTML sn-p。

textarea
{
  border:1px solid #999999;
  width:100%;
  margin:5px 0;
  padding:3px;
}
<div style="display: block;" id="rulesformitem" class="formitem">
  <label for="rules" id="ruleslabel">Rules:</label>
  <textarea cols="2" rows="10" id="rules"/>
</div>

问题是文本区域最终比父区域宽 8 像素(边框 2 像素 + 内边距 6 像素)。有没有办法继续使用边框和填充但将textarea 的总大小限制为父级的宽度?

【问题讨论】:

标签: html css stylesheet


【解决方案1】:

不,你不能用 CSS 做到这一点。这就是微软最初推出另一个可能更实用的box model 的原因。最终获胜的盒子模型使得混合百分比和单位变得不切实际。

我不认为你也可以用父级的百分比来表示填充和边框宽度。

【讨论】:

    【解决方案2】:

    许多 CSS 格式问题的答案似乎是“添加另一个

    !”

    那么,本着这种精神,您是否尝试过添加一个应用了边框/填充的包装 div,然后将 100% 宽度的文本区域放入其中?类似(未经测试):

    textarea
    {
      width:100%;
    }
    .textwrapper
    {
      border:1px solid #999999;
      margin:5px 0;
      padding:3px;
    }
    <div style="display: block;" id="rulesformitem" class="formitem">
      <label for="rules" id="ruleslabel">Rules:</label>
      <div class="textwrapper"><textarea cols="2" rows="10" id="rules"/></div>
    </div>

    【讨论】:

    • 我最终放弃了使用 % 宽度。我相信你的方法会同样有效。谢谢!
    • 别忘了加“.”到 textwrapper 类。
    • @Chris:谢谢并修复。我有点惊讶,有人花了将近一年半的时间才明白这一点......
    • 在这种情况下 textarea 的滚动条看起来如何?
    • 在 chrome 中,当您聚焦 textarea 元素时,它会自动突出显示,如果您为 div 包装器创建填充,则此填充将可见,因此两个边框将可见。一个来自hightlighting,另一个来自 .textwrapper border:1px solid #999999;
    【解决方案3】:

    如果您不太在意内边距的宽度,此解决方案实际上也会将内边距保持为百分比。

    textarea
    {
        border:1px solid #999999;
        width:98%;
        margin:5px 0;
        padding:1%;
    }
    

    不完美,但你会得到一些填充,宽度加起来是 100%,所以一切都很好

    【讨论】:

      【解决方案4】:

      让我们考虑一下我们想要实现的呈现给用户的最终输出:带有边框和填充的填充文本区域,其特征是被单击时会将焦点传递给我们的文本区域,以及块元素典型的自动 100% 宽度的优势。

      我认为最好的方法是尽可能使用低级解决方案,以达到浏览器的最大支持。 在这种情况下,唯一的 HTML 可以正常工作,避免使用 Javascript(无论如何我们都喜欢)。

      LABEL 标签之所以出现在我们的帮助中,是因为它具有这样的行为,并且允许包含它必须寻址的输入元素。 它的默认样式是内联元素之一,因此,给标签一个块显示样式,我们可以利用自动 100% 宽度,包括填充和边框,而内部 textarea 没有边框,没有填充和 100% 宽度.

      看看 W3C 的细节,我们可能会注意到其他优势:

      • 不需要“for”属性:当LABEL标签包含目标输入时,点击时会自动聚焦子输入;
      • 如果已经为文本区域设计了外部标签,则不会发生冲突,因为给定的输入可能有一个或多个标签。

      有关更多详细信息,请参阅W3C specifics

      简单示例:

      .container { 
        width: 400px; 
        border: 3px 
        solid #f7c; 
        }
      .textareaContainer {
      	display: block;
      	border: 3px solid #38c;
      	padding: 10px;
        }
      textarea { 
        width: 100%; 
        margin: 0; 
        padding: 0; 
        border-width: 0; 
        }
      <body>
      <div class="container">
      	I am the container
      	<label class="textareaContainer">
      		<textarea name="text">I am the padded textarea with a styled border...</textarea>
      	</label>
      </div>
      </body>

      .textareaContainer 元素的内边距和边框是我们想要赋予文本区域的。尝试编辑它们以根据需要设置样式。 我为 .textareaContainer 元素提供了大而可见的填充和边框,让您在单击时看到它们的行为。

      【讨论】:

      • 不确定这里有什么跨浏览器陷阱,但我喜欢这种方法。 +1
      【解决方案5】:

      您可以使用 box-sizing 属性,所有主要的符合标准的浏览器和 IE8+ 都支持它。不过,您仍然需要 IE7 的解决方法。阅读更多here

      【讨论】:

      • @DavidJohnstone:由于您不再为 IE7 或更早版本开发网站,这就是解决方案 :)
      【解决方案6】:

      为什么不忘记这些技巧,只用 CSS 来做呢?

      我经常使用的一个:

      .boxsizingBorder {
          -webkit-box-sizing: border-box;
             -moz-box-sizing: border-box;
                  box-sizing: border-box;
      }
      

      查看浏览器支持here

      【讨论】:

      • 这一定是我最近发现的最酷的东西之一。谢谢,有没有办法在 IE7 中也可以做到这一点?
      • 请注意,您仍然希望将 width:100% 与边框框结合使用。
      • 旧版本的 Internet Explorer 不只使用边框行为吗?
      • 谁能解释一下,这门课在哪里?一个围绕文本区域的 div?
      • 这太棒了......即使经过这么多年,仍然每天都能学到新东西。 @koolaang 这基本上是说对象的大小不应考虑填充,因此理论上您可以将此样式直接应用于 textarea 本身。
      【解决方案7】:

      我遇到了另一个非常简单的解决方案here:将 padding-right 添加到 textarea 的容器中。这样可以保留 textarea 上的边距、边框和内边距,从而避免了 Beck 指出的关于 chrome 和 safari 围绕 textarea 放置的焦点突出显示的问题。

      容器的 padding-right 应该是 textarea 两侧的有效边距、边框和内边距的总和,再加上您可能需要的容器内边距。因此,对于原始问题中的情况:

      textarea{
          border:1px solid #999999;
          width:100%;
          margin:5px 0;
          padding:3px;
      }
      .textareacontainer{
          padding-right: 8px; /* 1 + 3 + 3 + 1 */
      }
      

      <div class="textareacontainer">
          <textarea></textarea>
      </div>
      

      【讨论】:

      • +1 这将在比 CSS3 语句更多的浏览器中工作。不幸的事实是,世界仍然需要包装 div。
      • 我真的很喜欢这个答案。它使 textarea 快速适应,没有任何小于 100% 的神奇百分比数字。您可以在包装器的所有侧面使用填充来强制文本区域移入并保留在父项内。包装器上的最小高度和高度也需要为 100%。然后可以使用相同的填充将 textarea 设置为 100%,以使所有内容完美契合。
      【解决方案8】:

      负边距怎么样?

      textarea {
          border:1px solid #999999;
          width:100%;
          margin:5px -4px; /* 4px = border+padding on one side */
          padding:3px;
      }
      

      【讨论】:

        【解决方案9】:

        如果你像这样填充和偏移它:

        textarea
        {
            border:1px solid #999999;
            width:100%;
            padding: 7px 0 7px 7px; 
            position:relative; left:-8px; /* 1px border, too */
        }
        

        textarea 的右侧与容器的右侧完美对齐,并且 textarea 内的文本与容器中的正文文本完美对齐... textarea 有点“突出”。它有时更漂亮。

        【讨论】:

          【解决方案10】:

          此代码适用于 IE8 和 Firefox

          <td>
              <textarea style="width:100%" rows=3 name="abc">Modify width:% accordingly</textarea>
          </td>
          

          【讨论】:

          • 也在 Chrome 中工作过。
          【解决方案11】:

          使用box sizing property:

          -moz-box-sizing:border-box; 
          -webkit-box-sizing:border-box; 
          box-sizing:border-box;
          

          这会有所帮助

          【讨论】:

            【解决方案12】:

            对于使用 Bootstrap 的人来说,textarea.form-control 也会导致 textarea 大小问题。 Chrome 和 Firefox 似乎使用以下 Bootstrap CSS 的不同高度:

            textarea.form-conrtol{
                height:auto;
            }
            

            【讨论】:

              【解决方案13】:

              我经常用calc() 解决这个问题。您只需为 textarea 提供 100% 的宽度和一定数量的填充,但您必须减去您为 textarea 提供的 100% 宽度的左右填充的总和:

              textarea {
                  border: 0px;
                  width: calc(100% -10px);
                  padding: 5px; 
              }
              

              或者如果你想给 textarea 一个边框:

              textarea {
                  border: 1px;
                  width: calc(100% -12px); /* plus the total left and right border */
                  padding: 5px; 
              }
              

              【讨论】:

                【解决方案14】:

                * {
                    box-sizing: border-box;
                }
                
                .container {
                    border-radius: 5px;
                    background-color: #f2f2f2;
                    padding: 20px;
                }
                
                /* Clear floats after the columns */
                .row:after {
                    content: "";
                    display: table;
                    clear: both;
                }
                
                input[type=text], select, textarea{
                    width: 100%;
                    padding: 12px;
                    border: 1px solid #ccc;
                    border-radius: 4px;
                    box-sizing: border-box;
                    resize: vertical;
                }
                <div class="container">
                  <div class="row">
                    <label for="name">Name</label>
                    <input type="text" id="name" name="name" placeholder="Your name..">
                  </div>
                  <div class="row">
                    <label for="country">Country</label>
                    <select id="country" name="country">
                      <option value="australia">UK</option>
                      <option value="canada">USA</option>
                      <option value="usa">RU</option>
                    </select>
                  </div>    
                  <div class="row">
                    <label for="subject">Subject</label>
                    <textarea id="subject" name="subject" placeholder="Write something.." style="height:200px"></textarea>
                  </div>
                </div>

                【讨论】:

                  【解决方案15】:

                  我一直在寻找内联样式解决方案而不是 CSS 解决方案,这是响应式文本区域的最佳选择:

                  <div style="width: 100%; max-width: 500px;">
                    <textarea style="width: 100%;"></textarea>
                  </div>
                  

                  【讨论】:

                  • 是的,这是我认为的最佳解决方案。谢谢。
                  • 在最新的 chrome 版本中对我不起作用。我必须使用 min-width:100% 才能让它工作。
                  • @MohanGundlapalli 这是一个简单的 CSS 规则,也应该适用于最新的 Chrome,是否有任何其他样式影响 width: 100% 规则?也许您可以尝试使用 Chrome 开发工具检查它
                  【解决方案16】:

                  问题在于box-sizing 属性。 默认情况下,box-sizing 属性的初始值为content-box。 所以你在引擎盖下有这样的东西:

                  textarea {
                    border:1px solid #999999;
                    width:100%;
                    margin:5px 0;
                    padding:3px;
                    box-sizing: content-box;
                  }
                  

                  box-sizing: content-box; 表示实际元素的宽度等于元素内容框的宽度。 因此,当您添加填充(在本例中为 padding-right 和 padding-left --> 因为我们正在谈论宽度)和边框(在本例中是border-right 和border-left --> 因为我们正在谈论宽度),这些值被添加到最终宽度。所以你的元素会比你想要的更宽。

                  将其设置为box-sizing: border-box;。所以宽度将像这样计算:

                  horizontal border + horizontal padding + width of content box = width
                  

                  在这种情况下,当你添加水平边框和水平填充时,元素的最终宽度不会改变,实际上内容框会缩小以满足方程。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-08-06
                    • 2013-03-30
                    • 1970-01-01
                    • 2023-01-19
                    • 2013-07-06
                    • 2012-01-05
                    相关资源
                    最近更新 更多