I don't think this is possible with CSS alone, barring a less-than-ideal workaround.
The Selectors 3 specification states that :not()
requires a simple selector, which is why your initial attempt doesn't work.
The first thought for a workaround would be a simple override, but this has a major caveat: all children of the "excluded" parent would have to be overriden with the same display
type:
body * { display: none; }
.list-app, .list-app * {
display: block !important; /* Every child is now display: block */
}
<span>Hello world</span>
<div class="list-app">
<span>Hi world</span>
</div>
For some more insight as to why this workaround's caveat exists, we can refer to an excellent answer by BoltClock, to an older related question:
A browser's default styles are defined in its user agent stylesheet, the sources of which you can find here. Unfortunately, the Cascading and Inheritance level 3 spec does not appear to propose a way to reset a style property to its browser default. However there are plans to reintroduce a keyword for this in Cascading and Inheritance level 4 — the working group simply hasn't settled on a name for this keyword yet (the link currently says revert
, but it is not final). Information about browser support for revert
can be found on caniuse.com.
While the level 3 spec does introduce an initial
keyword, setting a property to its initial value resets it to its default value as defined by CSS, not as defined by the browser. The initial value of display
is inline
; this is specified here. The initial
keyword refers to that value, not the browser default.