~选择器用于匹配某元素之后所有同级兄弟元素,适用场景包括表单校验、文档流样式统一及折叠面板控制;失效主因是跨父级、节点被移除或display:contents破坏兄弟关系。

它不能跨父级、不能反向选、不响应交互,但只要 DOM 结构满足“同级+靠后”,就能一次性控制多个后续元素——比写 JS 或重复 class 更轻量。
什么时候必须用 ~ 而不是 +
当你需要影响「某个触发元素之后所有同类兄弟」,而非仅第一个时。+ 只能命中紧邻的下一个,~ 才能覆盖全部。
- 表单校验:一个
input.error后面跟着span.error、small.help-text、div.validation-tip,用input.error ~ .error一次全中;写成input.error + .error只改第一个 - 文档流样式:
h2 ~ p让所有二级标题之后的段落统一斜体,中间夹着img或blockquote也不打断 - 折叠面板:在
input[type="checkbox"]后加图标、分隔线、多层内容区,#toggle:checked ~ .panel仍能生效,而+会被中间元素卡断
~ 失效最常见的三个原因
90% 的“写了没反应”问题,和语法无关,是结构或渲染导致的匹配失败。
-
input.error和.hint不在同一个父容器下——比如 UI 库把提示挂到body底下,~完全失效 -
input.error是v-if或*ngIf控制的,条件为false时节点被移除,不是隐藏,~没东西可匹配 - 父容器用了
display: contents,子元素失去“兄弟关系”语义,浏览器视其为无父容器直连文档流,~判定失效
如何用 :not() 配合 ~ 选“前面的元素”
~ 本身只能向后选,但组合 :not() 可实现反向逻辑:先选全部,再排除“在某元素之后”的部分。
- 场景:取
.divider之前所有.item—— 写.content > .item:not(.divider ~ .item) - 原理:
.divider ~ .item匹配所有在分隔符后的.item,:not()把它们剔除,剩下就是“前面的” - 注意:
.divider必须真实存在于 DOM 中且有稳定类名;node-html-parserv6 及更早版本不支持该组合,需升级或手动遍历
性能和可维护性容易被忽略的点
~ 单独用没有性能问题,但嵌套过深或搭配复杂伪类时,重排开销会上升,尤其在低端 Android 设备上。
- 避免深层链式写法:
.container > .list > li ~ li比li ~ li多出两层计算,能扁平就扁平 - 别依赖 DOM 顺序做关键逻辑:加个
<span></span>包裹文字、插个空div,就可能让整块样式突然消失,接手的人很难定位 - 内容高度不可预测时,别只靠
max-height过渡——Safari 对该属性动画支持不稳定,建议加opacity或visibility双保险
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











