css2原生支持id选择器(#header)、类选择器(.btn)、元素选择器(div)、后代/子代选择器(nav a、ul > li)、相邻兄弟选择器(h2 + p)、基本伪类(a:hover、:first-child)及四种属性选择器[title]、[title="home"]、[title~=word]、[lang|=en]。

CSS3 的选择器不是“替代”CSS2,而是叠加增强;所有 CSS2 选择器在 CSS3 中完全可用,新增的只是更细粒度的匹配能力。
哪些选择器是 CSS2 原生支持的
CSS2 已支持以下核心选择器类型,至今仍是日常开发主力:
- ID 选择器:
#header - 类选择器:
.btn - 元素选择器:
div、p - 后代/子代选择器:
nav a、ul > li - 相邻/兄弟选择器:
h2 + p、li ~ li(注意:~是 CSS3 新增,+在 CSS2.1 中已存在) - 基本伪类:
a:hover、a:focus、:first-child(:first-child实际属于 CSS2.1,常被误归为 CSS3) -
属性选择器仅限三种:
[title]、[title="home"]、[title~=word](空格分隔单词匹配)、[lang|=en](语言前缀匹配)
CSS3 新增的关键属性选择器怎么用
这些是真正从 CSS3 开始才有的,解决了“开头/结尾/包含字符串”的硬需求,且不依赖 JavaScript:
-
[data-id^="user"]:匹配data-id="user-123"或data-id="user",但不匹配data-id="admin-user" -
[href$=".pdf"]:匹配所有以.pdf结尾的链接,比如href="report.pdf",适合统一加 PDF 图标 -
[class*="grid"]:匹配class="col-grid-3"、class="grid-system",但注意也会误中class="agreement"(含grid子串) - ⚠️ 不要混淆:
[attr~=val](CSS2)要求空格分隔的完整单词;而[attr*=val](CSS3)是任意位置子串匹配,语义完全不同
结构伪类和伪元素是区分重点
这类选择器最容易暴露“是否真懂 CSS3”,因为它们改变了定位逻辑:
-
:nth-child(2n)按 DOM 顺序数孩子,不管标签名;:nth-of-type(2n)只数同类型(如li)元素——这是 CSS3 才有的精确控制 -
:not(.disabled)支持复杂参数,比如:not([type="hidden"]):not([disabled]),CSS2 的:not()仅支持简单选择器(IE8 完全不支持) - 伪元素双冒号语法:
::before和::after是 CSS3 标准写法;:before是 CSS2 兼容写法(仍有效,但语义上表示“伪类”,易混淆) -
:is()和:where()是更新的 CSS4 特性(非 CSS3),别误当作 CSS3 新增
兼容性与实际落地要注意什么
别只看 Can I Use 数据,真实项目里几个关键点常被忽略:
- IE9+ 支持大部分 CSS3 属性选择器,但 IE8 及以下只认 CSS2 的四种属性选择器,
^=、$=、*=全挂 - 移动端几乎无压力,但微信内置浏览器(X5 内核旧版本)对
:nth-child()复杂表达式(如3n+2)偶有解析异常 - 使用
[data-*]自定义属性时,[data-role^="nav"]比[data-role="nav-main"]更易维护,但需确保 HTML 中值确实按约定书写,否则匹配失败不报错 - autoprefixer 插件不处理选择器——它只加 CSS 属性前缀,
:-webkit-any()这类废弃私有伪类不会自动补全,也不该用
真正卡住人的往往不是“会不会写 :nth-child”,而是没意识到 :nth-of-type 和 :nth-child 在混合标签结构下结果可能天差地别,或者把 [attr*=val] 当成“单词匹配”来用导致样式意外生效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











