你刚调完一个自适应输入框的JavaScript,第47次测试时它又在移动端崩了——这种崩溃感,每个前端都懂。
CSS工作组终于扔过来一根救命稻草:field-sizing。不是新框架,不是构建工具,就一行属性,能让表单元素像普通div那样随内容自然伸缩。本文把它的来龙去脉、踩坑点、实战代码一次性说清。
我们是怎么被折磨过来的
让输入框跟着内容长高,这件事曾经只有两个选项,都很糟。
选项一:JavaScript监听。给textarea绑input事件,读scrollHeight,手动算高度。结果?视觉抖动、延迟一帧、padding和box-sizing打架时直接失效。原作者吐槽得很精准:"jittery, often felt a frame behind"。
选项二:"隐形双胞胎" hack。造一个隐藏的div,样式和输入框完全一致,塞同样的文字,让div撑开容器,输入框再用position: absolute盖上去。原作者的比喻很生动:"building a house out of duct tape and prayers"——用胶带和祈祷盖房子。
这两种方案都要写几十行代码,还要处理边界情况。原作者估算,这玩意儿"would have saved us literally thousands of lines of fragile JavaScript back in the day"。
2026年的解法:把活扔给浏览器
field-sizing的核心逻辑很简单:表单元素默认是field-sizing: fixed,所以不会动;改成content,浏览器自动接管尺寸计算。
适用元素包括textarea、input、甚至select。配合:has()伪类(原文提到的"Advanced Use of the :has() Pseudo-Class"),能做出零JavaScript的响应式表单。
直接上代码,原作者认证的"cleanest way":
/* 核心就这一行 */.auto-expanding-textarea {field-sizing: content;min-height: 3lh; /* 别缩成一条缝 */max-height: 400px; /* 别无限长高 */width: 100%;padding: 0.8rem;border: 1px solid #ccc;border-radius: 8px;resize: none; /* 手动拖拽柄可以退休了 *//* input同理 */.expanding-input {field-sizing: content;min-width: 150px;max-width: 100%;}注意resize: none——既然元素自己会长,右下角那个拖拽柄反而碍事。
新手坟场:忘了设边界
原文只点到一半的坑,我必须补完。只写field-sizing: content不设min/max限制,等于给页面埋雷:
• 没min-height:空输入框缩成一条线,用户找不到光标
• 没max-height:用户粘贴一万字,页面被撑爆
• 没min/max-width:input可能缩到0或撑破布局
原作者只提了"Forgetting the Limits"这个标题就断掉,但意思很清楚——边界条件是必选项,不是可选项。
为什么这事值得兴奋
表面看是省了几行JS,实际是设计范式的转移。
以前做自适应输入,是"开发者算尺寸→浏览器渲染→开发者再算→再渲染"的循环。现在浏览器内部直接根据内容算布局,跳过了JavaScript这层中介。性能更好,代码更少,行为更可预测。
原作者把它和clamp()函数、:has()伪类并列,指向同一个趋势:CSS正在接管以前必须用JS的交互逻辑。不是渐进增强,是能力替代。
浏览器支持方面,Chrome/Edge 123+、Firefox 136+、Safari 17.4+已实装(原文未明确版本号,但这是2026年5月的现状)。新项目可以无脑用,老项目渐进升级。
最后留一个问题
当浏览器原生解决了"输入框自适应"这种具体问题,你团队里那套用了五年的表单组件库,还有多少代码是在解决已经不存在的问题?
热门跟贴