Mittlerweile bin ich etwas klüger geworden: nichts zu finden gab es bei Operationen innerhalb eines DocumentFragment. Dieses dann aber, eingefügt in document.body, lieferte dem Stylesheet Futter für :empty.
Bei den Operationen im Fragment habe ich lediglich ungeliebte Dinge entfernt, nichts hinzugefügt. Also kein createElement, kein append, lediglich remove sowie removeAttribute. Sogar replaceChildrengibt’s nur fürs Einhängen des Fragments.
Auch ein normalize()lief über das Fragment. Nur(?) zwischen diesem und der Stelle, an der querySelectorAll(':empty') blind war, liefen noch `NodeIterator˚-Schleifen (mittendrin versuchsweise auch mal mit TreeWalker) mit entsprechenden Aufräum-Aktionen.
„Unten“ angelangt hatten die sich verweigernden Nodes dann aber trotzdem textContent: lauter \n. Und die verschwanden dann, offensichtlich („sagt ja schon das CSS danach“), alleine durch das einhängen des Fragments.
Jetzt habe ich lediglich noch ein normalize() direkt vor dem relevanten Abschnitt eingefügt. Und schon klappt es wie gedacht. Nur: das Wieso, den Unterschied, den verstehe ich „nicht wirklich“. Wobei das Unverständnis auf dem Effekt des „Whitespace raus beim Einhängen“ beruht. (Die „empty-ignorierten“ Nodes befinden sich nicht mal am Anfang oder Ende des Fragments!)
(Anmerkung: außer den erwähnten Querries war/ist, vermutlich „natürlich“, auch matchesbetroffen.)