460

我正在呈现以下 CSS 和 HTML 片段。

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为父级的宽度?

4

16 回答 16

721

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

我经常使用的一个:

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

在此处查看浏览器支持。

于 2010-11-11T15:58:34.300 回答
89

许多 CSS 格式问题的答案似乎是“添加另一个 <div>!”

那么,本着这种精神,您是否尝试过添加一个应用了边框/填充的包装 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>

于 2008-11-07T16:33:42.993 回答
24

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

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

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

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

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

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

简单的例子:

.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 元素提供了大而可见的填充和边框,让您在单击时看到它们的行为。

于 2010-03-23T10:48:46.317 回答
15

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

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

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

于 2008-11-07T17:00:28.993 回答
13

我在这里遇到了另一个非常简单的解决方案:将 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>
于 2011-07-29T16:18:24.960 回答
11

此代码适用于 IE8 和 Firefox

<td>
    <textarea style="width:100%" rows=3 name="abc">Modify width:% accordingly</textarea>
</td>
于 2013-11-13T00:31:03.993 回答
5

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

于 2010-03-25T12:35:50.907 回答
5

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

<div style="width: 100%; max-width: 500px;">
  <textarea style="width: 100%;"></textarea>
</div>
于 2018-10-22T08:52:09.637 回答
2

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

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

于 2008-11-07T05:26:12.433 回答
1

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

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

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

于 2013-04-03T21:56:53.463 回答
1

使用盒子尺寸属性

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

这会有所帮助

于 2014-08-03T08:48:04.260 回答
1

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

textarea.form-conrtol{
    height:auto;
}
于 2014-08-07T15:05:11.863 回答
1

我经常用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; 
}
于 2016-11-15T09:47:18.020 回答
1

问题出在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

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

于 2021-04-25T11:48:14.647 回答
0

负利润怎么办?

textarea {
    border:1px solid #999999;
    width:100%;
    margin:5px -4px; /* 4px = border+padding on one side */
    padding:3px;
}
于 2012-06-14T21:01:10.287 回答
0

* {
    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>

于 2018-02-01T05:47:15.833 回答