跨浏览器统一 placeholder 透明度需四套独立规则并显式声明 opacity:webkit 用 opacity: 0.6,firefox 用 opacity: 1 抵消默认 0.54 衰减,ie/edge 用 opacity: 0.6,标准语法放最后。

因为 Firefox 默认给 ::-moz-placeholder 加了 opacity: 0.54,Safari 对 rgba() 的 alpha 通道支持不完整,而 Chrome/Edge 虽默认 opacity: 1,但一旦被全局样式或框架重置就会失守——三者逻辑互不兼容,只靠 color 无法统一视觉。
Firefox 的 ::-moz-placeholder 必须显式写 opacity: 1
Firefox 默认给占位符加了半透明层,哪怕你只设 color: #999,最终渲染也是发灰的浅色。这个 opacity: 0.54 是硬编码在渲染引擎里的,color 压不住它。必须在每条 ::-moz-placeholder 规则里都带上 opacity: 1,否则上线后 placeholder 突然变淡、看不清,八成是它在作怪。老版本(如 Firefox 50)甚至不认 opacity 属性,所以不能省略——写了不一定全生效,但不写一定失效。
Safari 不吃 rgba() 的 alpha,得拆开写 color + opacity
如果你写 color: rgba(153, 153, 153, 0.6),Safari(尤其是 iOS 16.3 及更早)可能直接忽略 alpha 值,导致文字“突然变黑”或“完全隐形”。正确做法是分开声明:color: #999 + opacity: 0.6,并且这条 opacity 必须同步出现在所有前缀规则中,包括 ::-webkit-input-placeholder。别用 inherit 或 currentcolor 做 color 值——Safari 有时会继承 input 的 border 色,让 placeholder 文字和边框同色,等于消失。
Chrome/Edge 看似“正常”,实则最易被意外覆盖
Chrome 和新版 Edge 默认 opacity: 1,但它们对选择器权重和样式继承非常敏感。常见破防场景包括:
- UI 框架(如 Ant Design)全局重置了
input::placeholder { opacity: 0.5; },你的规则权重不够就被划掉 -
all: unset或appearance: none作用于input时,会切断伪元素渲染通道,::-webkit-input-placeholder直接失效 - Vue 的
<style scoped></style>或 React CSS Modules 会给选择器自动加哈希,变成input[data-v-xxx]::-webkit-input-placeholder,但 Safari/Chrome 不支持带属性的选择器匹配伪元素,必须用:deep()或提为全局样式
真正能跨浏览器统一透明度的写法
四套规则必须分开写,不能用逗号合并;opacity 必须每条都显式声明;标准写法 input::placeholder 放最后。示例:
input::-webkit-input-placeholder { color: #999; opacity: 0.6; }
input::-moz-placeholder { color: #999; opacity: 1; }
input:-moz-placeholder { color: #999; opacity: 1; }
input::-ms-input-placeholder { color: #999; opacity: 0.6; }
input::placeholder { color: #999; opacity: 0.6; }
注意:不要指望 opacity 在所有浏览器里表现完全一致——Firefox 的 opacity: 1 是为了抵消它的默认衰减,而 Safari 的 opacity: 0.6 是真·半透明,这是底层渲染差异,只能靠显式控制收口,没法一劳永逸。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











