textarea必须用结束标签,不能自闭合;rows和cols仅控制可见尺寸,不限制输入长度;换行符提交行为依赖后端处理;移动端聚焦时需延时scrollIntoView避免被键盘遮挡。

textarea 元素必须用结束标签,不能自闭合
很多人写 <textarea name="content"></textarea>,浏览器会把它当成没有内容的空标签,实际提交时值永远为空。HTML 规范里 textarea 是明确要求有开始和结束标签的,中间的内容才是默认值。
正确写法是:
<textarea name="content">这里可以写默认提示文字</textarea>
如果想初始为空,就留空:<textarea name="content"></textarea>,而不是用斜杠闭合。
rows 和 cols 属性控制的是“可见尺寸”,不是限制长度
rows 决定显示几行(行高由字体、行距等影响),cols 决定每行显示多少个平均字符宽度(通常按等宽字体估算)。它们不影响用户能输入多少字——用户照样可以粘贴几千字进去,也能用方向键上下滚动。
常见误用场景:
- 以为设了
rows="3"就只能输 3 行 → 实际可无限换行 - 用
cols="50"想防超长输入 → 完全无效,得靠maxlength或后端校验
真正限制输入长度要用:maxlength(HTML5 属性,按 Unicode 码点计数)或 JavaScript 监听 + 截断,但注意中文、emoji 都算一个字符。
换行符在提交时的行为取决于服务器端处理
用户在 textarea 里敲回车,生成的是 \n(Unix 风格)还是 \r\n(Windows),取决于浏览器和系统,但现代浏览器统一发 \n 给服务端。关键问题是:你的后端是否保留它?是否转成 <br> 渲染?是否做了 trim?
典型坑点:
- PHP 接收后直接 echo,页面不显示换行(HTML 忽略空白符)→ 得用
nl2br()或 CSSwhite-space: pre-wrap - 数据库字段是
VARCHAR(255),但用户粘贴带换行的长文本 → 插入失败或被截断 - 前端用
.value.trim().length === 0判空,但用户只打了几个空格+回车 → 误判为非空
移动端软键盘弹出时 textarea 可能被遮挡
尤其在 iOS Safari 上,textarea 聚焦后软键盘顶起页面,若它在视口底部,很容易被盖住。CSS 的 scrollIntoView() 不总可靠,更稳妥的做法是监听 focus 事件并手动滚动:
document.querySelector('textarea').addEventListener('focus', () => {
setTimeout(() => {
document.querySelector('textarea').scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}, 100);
});
注意加 setTimeout:iOS 在键盘动画开始前触发 focus,立刻 scroll 可能时机太早;100ms 是经验值,太短仍可能失效。
另外,避免给 textarea 外层容器设 overflow: hidden 或固定高度,否则滚动会被截断。


















