:default伪类不适用于select的option元素,仅对button、radio、checkbox的初始默认状态有效;应改用option[selected]属性选择器来可靠高亮预设选项。

为什么 :default 伪类几乎不生效
因为浏览器对 :default 的支持非常有限——它只在原生表单控件中对「用户未手动切换过」的初始选中项起作用,且仅限于 、、,**完全不适用于 的 **。很多开发者误以为给 加 :default 就能高亮默认项,结果样式根本没应用。
常见错误现象:select option:default { background: #ffeb3b; } 在 Chrome/Firefox/Safari 中全部无效;控制台也看不到匹配的样式规则。
-
:default不是“有selected属性就匹配”,而是“由 UA(浏览器)决定哪个控件当前处于初始默认状态” - 对于
,浏览器不把selected的视为“默认控件”,所以不触发:default - 即使你用 JS 动态设置
select.value = 'xxx',也不会让对应匹配:default
想突出预选的 ?用 selected 属性 + CSS
真正可靠的方式是直接利用 HTML 属性选择器,而不是依赖语义模糊的伪类。只要选项带有 selected 属性(无论是否被 JS 修改过),就能稳定命中。
使用场景:表单加载后需要视觉强调用户还没动过的初始选项,比如「请选择城市」作为占位符不加 selected,而真实默认项如「北京」带 selected,就该高亮它。
- 写法:
select option[selected] { background: #e3f2fd; color: #1976d2; } - 注意:必须用
[selected],不是:selected(后者是当前被选中的状态,会随用户操作实时变化) - 兼容性:所有现代浏览器都支持,包括 IE9+
- 性能无影响:属性选择器和伪类一样是 CSS 引擎原生处理的
:selected 和 [selected] 的关键区别在哪
这是最容易混淆的点。:selected 是运行时状态,[selected] 是静态属性存在性——哪怕你用 JS 清掉 selected 属性,只要 DOM 上曾经写过,[selected] 就不会回退;而 :selected 永远只反映当前 UI 选中项。
示例对比:
<select><option value="a">A</option> <option value="b" selected>B</option> <option value="c">C</option></select>
- 页面加载完:
option[selected]匹配 B;option:selected也匹配 B - 用户选了 C:
option[selected]仍只匹配 B(属性没变);option:selected现在匹配 C - JS 执行
el.options[0].selected = true:option:selected切到 A,但[selected]还是 B ——除非你同时调用el.options[1].removeAttribute('selected')并给 A 加上
复杂点在于「占位符选项」要不要参与样式逻辑
很多表单第一个 是「请选择…」这类禁用占位符,它通常有 disabled 且无 value,但它也可能被写成 。这时候你要决定:这个占位符算不算“预选默认项”?
如果不算,就得排除它:
- 写法:
select option[selected]:not([disabled]) { ... } - 更稳妥(兼容老浏览器):
select option[selected][value]:not([disabled]) { ... },靠[value]过滤空值占位符 - 别依赖
:default去自动绕过它——它本来就不匹配
真正麻烦的是动态表单:初始无 selected,JS 根据 URL 参数或 localStorage 设置默认值。这时你得同步操作 DOM 属性(option.setAttribute('selected', '')),否则 [selected] 选择器失效。这点很容易被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











