textarea 的 placeholder 不支持换行是 HTML 规范所致,white-space 等 CSS 属性对 ::placeholder 无效;唯一可靠方案是用绝对定位 div 模拟,并严格同步样式与事件;优先将多行说明移至外部标签。

textarea 的 placeholder 属性天生不支持换行 —— 这不是 bug,是 HTML 规范明确规定的:所有空白符(包括 \n、\r\n、直接回车)都会被压缩为单个空格或忽略。硬塞换行符只会让提示文字变乱或截断。
为什么 textarea::placeholder 加 white-space: pre-wrap 不管用
很多人试过在 CSS 里写:
textarea::placeholder { white-space: pre-wrap; }
结果发现 Chrome 仍不换行,Firefox / Safari 更干脆无视。原因很直接:规范没授权浏览器对 placeholder 内容做白空间解析。伪元素的样式控制权极其有限,white-space 在这里基本无效(除个别 Chrome 旧版本偶然生效,不可依赖)。
- 所有主流浏览器(Chrome 120+、Firefox 125+、Safari 17+)均不响应
white-space对::placeholder的设置 -
content伪元素(如::after)在::placeholder上无法添加内容,CSS 生成内容不被允许 - 用
或实体也无效 —— placeholder 是纯文本上下文,不解析 HTML 实体
真正能落地的 JS 模拟方案(推荐)
用一个绝对定位的 <div> 叠在 textarea 上,手动同步显隐和位置。这是目前唯一跨浏览器、无障碍友好、移动端可用的解法。
立即学习“前端免费学习笔记(深入)”;
-
textarea必须设position: relative,作为遮罩层的定位上下文 - 遮罩层用
white-space: pre-line保留换行,字体、颜色、行高需严格匹配textarea的font计算值(不能只写font-size) - 监听
input事件(不只是focus),否则粘贴内容后遮罩不消失 - 必须处理
resize和滚动时的重定位 —— 尤其当textarea在 modal 或 fixed 容器里
示例关键片段:
<div class="textarea-wrapper"> <textarea id="desc"></textarea> <div class="placeholder" aria-hidden="true">请填写:<br>• 第一行说明<br>• 第二行要求</div> </div>
别踩的坑:用 contenteditable 替代 textarea
看似自由,实则埋雷:
- 表单提交时
contenteditable元素的值不会自动进入FormData,必须手动同步到隐藏<input type="hidden"> - iOS 中文输入法下光标跳动、选词框错位频繁,Android 部分厂商键盘会失焦
- 失去原生
rows/cols自适应、软换行逻辑、滚动锚点行为 - 即使加了
role="textbox",屏幕阅读器对编辑状态、字数统计的支持仍弱于textarea
真正需要多行提示时,优先考虑把说明文字挪到 textarea 外部:用 <label> 或独立段落 + 小号灰色字体。placeholder 的职责就是“临时占位”,不是说明书。强行撑开它,往往暴露的是交互设计本身的问题。



















