New #?# syntax for advanced element hiding rules · 2017-06-19 17:21 by Hubert Figuière
Starting with Adblock Plus 1.13.3 for Chrome and Opera (and development builds as of 188.8.131.522) there is a new and improved syntax which can be used for advanced element hiding filters. It allows for elements to be hidden based upon their contents using
:-abp-has. CSS property filters have also being adjusted to be consistent with the new syntax, so both those and
:-abp-has filters now use the
#?# option separator.
So for example here’s a standard element hiding filter:
Which with the new advanced syntax could be written as:
The overall syntax is the same, but
#?# filters have access to a few extensions implemented as CSS pseudo classes. This extra power comes with a cost however, the new
#?# filters are much slower and should only be used where necessary. The above example is bad therefore, since none of those extensions are being used. Filters using the new syntax must also be restricted to as few domains as possible, without any domain restrictions they are rejected outright.
So which CSS pseudo classes are supported?
:-abp-properties() (CSS property filters)
:-abp-properties() is a reworked syntax for the CSS property filter. The value of the
-abp-properties attribute becomes the argument passed to the pseudo-class selector. Your old filters will be converted automatically when loading the filter lists, and will work the same way. For example:
domain.com##[-abp-properties='background-color: rgb(0, 0, 0)']
domain.com#?#:-abp-properties(background-color: rgb(0, 0, 0))
Note the lack of quotes. As before, you can combine this into a more complex CSS selector.
With this change we introduced a new pseudo-class:
:-abp-has(selector). Inspired by the CSS Level 4 draft :has(), this pseudo-class selects an element if it contains something that matches the selector passed an argument.
domain.com#?#div.sidebar > div:-abp-has(> video.ad)
On the site “domain.com”, hide the element that has as direct descendant a
<video> element with the class “ad” and is a direct descendent of a
<div> that has the class “sidebar”. We want the enclosing element because it contain other things with want to hide.
domain.com#?#div.sidebar > div:-abp-has(> div.sidebartitle) > .adtext
On the site domain.com, hide the elements with the class “adtext”, that are direct descendent of a
<div> element that also has a direct descendent a
<div> with the class “sidebartitle”, and that is a direct descendent of a
<div> that has the class “sidebar”.
Note: It is recommended to not nest
:-abp-has() where possible, as that will further slow down element hiding. Also it is recommended that the selector inside a
:-abp-has() starts with a combinator like
~. Otherwise a lot of elements will be needlessly selected as more that one ancestor will match.