我如何才能使TextArea 100%宽度没有溢出时,填充是在CSS?

我有下面的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"></textarea>
</div>

问题是文本区域最终比父区域宽8px(边界为2px +填充为6px)。是否有一种方法可以继续使用边框和填充,但将textarea的总大小限制为父类的宽度?

495317 次浏览

不,CSS不能这样做。这就是微软最初引入另一个可能更实用的盒模型的原因。最终获胜的盒子模型使得混合百分比和单位不切实际。

我不认为这是可以与你表达填充和边界宽度的百分比的父。

许多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>

如果你不太介意填充的宽度,这个解决方案实际上会保持填充的百分比。

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

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

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

在我看来,最好的方法是尽可能使用底层解决方案,以达到最大的浏览器支持。 在这种情况下,只有HTML可以很好地工作,避免使用Javascript(无论如何我们都喜欢) LABEL标签在我们的帮助中,因为有这样的行为,并且允许包含它必须指向的输入元素。 它的默认样式是内联元素之一,因此,给标签一个块显示样式,我们可以利用自己的自动100%宽度,包括填充和边框,而内部文本区域没有边框,没有填充和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元素的padding和border是我们要赋予textarea的。试着编辑它们,按照你想要的样式。 我给了. textareacontainer元素大而可见的填充和边框,让你看到他们的行为时点击

你可以使用box-sizing属性,所有主流兼容标准的浏览器和IE8+都支持它。不过,对于IE7,你仍然需要一个变通方案。阅读更多在这里

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

我经常使用的一个:

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

参见浏览器支持在这里

我遇到了另一个解决方案在这里,它非常简单:在textarea的容器中添加padding-right。这保留了文本区域的边距、边框和填充,从而避免了Beck指出的chrome和safari在文本区域周围放置焦点高亮的问题。

容器的padding-right应该是文本区域两侧的有效边距、边框和填充之和,再加上容器可能需要的任何填充。对于原题中的情况

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>

那么负边际呢?

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

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

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

textarea的右侧与容器的右侧完美对齐,而且文本区域内的文本与容器中的正文文本完美对齐…和左侧的textarea“突出”一点。它有时更漂亮。

这段代码适用于我的IE8和Firefox

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

使用包装盒上浆属性:

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

这会有帮助

对于使用Bootstrap的人,textarea。表单控制也会导致文本区域大小问题。Chrome和Firefox似乎使用不同的高度与以下引导CSS:

textarea.form-conrtol{
height:auto;
}

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

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

或者如果你想给文本区域一个边框:

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

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

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

<div style="width: 100%; max-width: 500px;">
<textarea style="width: 100%;"></textarea>
</div>
问题在于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(在这个例子中是padding-right和padding-left ->因为我们谈论的是宽度)和边界(在这种情况下,border-right和border-left—>因为我们谈论的是宽度),这些值被添加到最终的宽度。所以你的元素会比你想要的宽

将其设置为box-sizing: border-box;。宽度的计算方法如下:

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

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

下面是一个更完整的CSS设计。如前所述,新的box-sizing:border-box;设置将边界和填充推到宽度计算中,因此当你使用min-width:100%时,所有内容都适合父容器并展开。

<style type="text/css">
body textarea,
body textarea:visited,
body textarea:hover,
body textarea:focus,
body textarea:active {
display: block;
width: auto;
height: auto;
min-width: 100%;
min-height: 10em;
padding: 1em;
margin: 0;
-webkit-appearance: textarea;
-moz-appearance: textfield-multiline;
cursor: text;
overflow: auto;
resize: both;
background-color: #eee;
word-wrap: normal;
border: 2px solid #bbb;
border-radius: .2em;
font-family:inherit;
line-height: normal;
}


div {
border:2px solid blue;
}


textarea,div {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
</style>


<div>
<textarea>Some test text...</textarea>
</div>

div父元素的边框是蓝色的,子文本区域是灰色的。

enter image description here