::first-letter 不适用于 <input> 元素,因其属替换元素且无真实文本渲染层;应改用 text-transform: capitalize、JavaScript 动态修改 value 及 autocapitalize 属性协同实现。

::first-letter 不能用于 <input> 元素,这是最常踩的坑——它只对块级、可生成首字母的**文本容器**(如 <p>、<div>)生效,而 <input> 是替换元素(replaced element),不支持该伪元素。
为什么 ::first-letter 对输入框完全无效
浏览器规范明确将 ::first-letter 的适用范围限制在「具有真实文本内容且能分词渲染的非替换元素」上。<input type="text"> 内部文本由用户实时输入,其渲染由 UA(用户代理)直接控制,CSS 无法穿透到其首字符层级。尝试写 input::first-letter { text-transform: uppercase; } 不会报错,但也不会有任何视觉变化。
真正可用的替代方案:用 text-transform: capitalize
这是最轻量、纯 CSS 的解法,适用于单行文本输入场景:
-
text-transform: capitalize会让每个单词首字母大写(不是仅第一个字母),对中文、数字、符号后跟的字母也生效 - 它作用于输入框的**显示层**,不修改实际值(
input.value仍为小写) - 兼容所有现代浏览器,包括 Safari 15.4+(旧版 Safari 对
input的capitalize支持不稳定,建议加-webkit-appearance: none保底)
示例:
立即学习“前端免费学习笔记(深入)”;
input[type="text"] {
text-transform: capitalize;
/* 可选:避免 Safari 渲染异常 */
-webkit-appearance: none;
}需要真正修改值?必须用 JavaScript 监听 input 事件
如果业务要求提交时首字母必须是大写(比如用户名、姓名字段),仅靠 CSS 不够,得操作 value:
- 监听
input事件(不是change),确保每次按键都响应 - 只处理第一个字符:用
value.charAt(0).toUpperCase() + value.slice(1),避免影响后续单词 - 注意光标位置:直接赋值会重置光标到末尾,需用
setSelectionRange恢复 - 防止重复触发:检查首字符是否已是大写字母,避免无谓更新
简明实现:
const input = document.querySelector('input#name');
input.addEventListener('input', () => {
const { value } = input;
if (!value || value[0] === value[0].toUpperCase()) return;
const capitalized = value[0].toUpperCase() + value.slice(1);
const pos = input.selectionStart;
input.value = capitalized;
input.setSelectionRange(pos, pos);
});移动端键盘首字母自动大写:别漏掉 autocapitalize
这是 HTML 原生属性,专为移动设备优化,和 CSS 无关但常被忽略:
-
autocapitalize="sentences":每句首字母大写(iOS 默认行为) -
autocapitalize="words":每个单词首字母大写 -
autocapitalize="characters":全部大写 -
autocapitalize="off":彻底关闭(适合密码、代码等场景)
它不影响桌面端,但对 iOS/Android 键盘行为有决定性影响。和 text-transform 或 JS 方案搭配使用效果更稳。
真正要落地的输入框首字母大写,得同时考虑三件事:CSS 显示层(text-transform)、JS 数据层(修改 value)、HTML 行为层(autocapitalize)。只盯 ::first-letter 会卡死在第一步。


















