Adblock Plus 专属伪选择器 `:-abp-` 系列:超出标准 CSS 的隐藏能力
为什么需要 ABP 专属伪选择器
标准 CSS 选择器只能根据元素自身的标签、class、id、属性来匹配。但广告元素经常:
- class 名随机生成(
abcz1234ad),不稳定; - 本身没有任何明显的广告标识,只有它的子元素或父元素有;
- 需要根据元素的内部文本内容来判断(比如"想继续免费浏览请关闭 AdBlock"这类弹窗)。
ABP 扩展了一组伪选择器来解决这些问题。这些选择器在浏览器原生 CSS 里不支持,只有 ABP 的元素隐藏引擎能识别。
:-abp-has()
根据子元素匹配父元素:
example.com##div.sidebar:-abp-has(div.sponsor-badge)
意思是:找到 example.com 上所有 div.sidebar,如果它包含一个 div.sponsor-badge 子元素,就把整个 sidebar 隐藏。
这比单纯写 example.com##div.sponsor-badge 更好——因为 sponsor-badge 可能只是 sidebar 里的一个小标记,你想隐藏的是整个广告容器。
:-abp-contains()
根据元素内部文本匹配:
example.com##div.popup:-abp-contains(关闭 Adblock)
意思是:找到 example.com 上所有 div.popup,如果里面有"关闭 Adblock"这几个字,就隐藏整个 popup。
对对抗"反拦截"弹窗特别有用——这类弹窗的 class 经常变,但里面的文字相对稳定。
:-abp-properties()
根据 CSS 属性值匹配:
example.com##div:-abp-properties(width: 300px; height: 250px;)
意思是:找到宽 300px 高 250px 的所有 div——这是经典的矩形广告位尺寸。这种规则能跨域名通用(很多广告位用相同尺寸),但误伤概率也高。
还支持正则:
example.com##div:-abp-properties(/width: 30[0-9]px;height: 250px;/)
:has() vs :-abp-has()
CSS Selectors Level 4 里也有一个原生 :has() 伪选择器,Chrome 105+ 和 Firefox 121+ 已经支持。但:
- 原生
:has()只在浏览器渲染时生效,某些动态加载场景可能失效; :-abp-has()是 ABP 内部实现的,不依赖浏览器原生支持,兼容性更好;- 如果你写的是 ABP 规则,用
:-abp-has()更稳妥。
组合使用
伪选择器可以组合:
example.com##div.ad-slot:-abp-has(img):-abp-contains(Sponsored)
这条表示:找到带图片且内容里有"Sponsored"字样的 ad-slot div,隐藏它。三重条件同时满足才生效,误伤概率最低。
局限
伪选择器会增加页面加载时的 CPU 消耗——因为 ABP 需要额外遍历 DOM 来做匹配。规则写得越多、越宽泛,性能影响越大。