So let's suppose I have this code. It's probably easiest to just see what is going on in the js fiddle itself, when it's formatted.
Here is some example HTML:
<div>
<h1>Anything outside of #keep-original should be set color: var(--colour-1) !important</h1>
</div>
<div id='keep-original'>
<h1>Stuff inside #keep-original should keep original colour</h1>
</div>
<div>
<h1>Anything outside of #keep-original should be set color: var(--colour-1) !important</h1>
</div>
:root {
--colour-1: red;
}
/* invalid CSS
*:not(#keep-original *){
color: var(--colour-1);
}
*/
/* formatting stuff */
* {
margin: 0px;
padding: 0px;
color: white;
}
html {
height: 100%;
}
body {
display: grid;
grid-template-columns: repeat(3, 1fr);
background: #222;
height: 100%;
}
body>div {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
div * {
display: inline;
}
.c1,
.c1 * {
color: #ff6500ff;
}
.c2,
.c2 * {
color: #f0ff00ff;
}
.c3,
.c3 * {
color: #1fc102ff;
}
.c4,
.c4 * {
color: #02c1acff;
}
.c5,
.c5 * {
color: #0f2bfdff;
}
.c6,
.c6 * {
color: #fc0bbfff;
}
<div>
<h4>Anything</h4>
<h3>outside</h3>
<h2>the</h2>
<h1>middle</h1>
<h1>div</h1>
<h2>should</h2>
<h3>be</h3>
<h4>--colour-1</h4>
</div>
<div id='keep-original'>
<h3 class='c1'>This</h3>
<h2 class='c2'>text</h2>
<h1 class='c3'>should</h1>
<h2 class='c4'>be</h2>
<h3 class='c5'>unaffected</h3>
<h1 class='c6'>including
<p>nested<span> elements<a> like<p> these</p></a></span></p>
</h1>
</div>
<div>
<h4>Anything</h4>
<h3>outside</h3>
<h2>the</h2>
<h1>middle</h1>
<h1>div</h1>
<h2>should</h2>
<h3>be</h3>
<h4>--colour-1</h4>
</div>
Let's assume I want all elements on the page to be a certain colour, EXCEPT for those that are children of a particular element. For example, this obviously sets the colour of all elements:
:root{
--colour-1: red;
}
*{
color: var(--colour-1) !important
}
Logically, I would want to do something like this (i.e. "select all, except children of #keep-original"), but it's not supported by CSS:
*:not(#keep-original *){
color: var(--colour-1);
}
I realise I could achieve what I want easily in JS by e.g. adding a .keep-original
class to all children of #keep-original
, then applying the colour style the css selector *:not(.keep-original)
, but I'm wondering, is it possible to do what I want purely in css? I feel as though this should be something that is quite easy to do, so maybe I've missed something really obvious...
You’re close. :not()
doesn't work as well as you'd expect with ID selectors, despite the relevant standards.
This doesn't work:
*:not(#keep-original) * {
color: var(--colour-1);
}
But this does:
div:not(#keep-original) * {
color: var(--colour-1);
}
For some reason, you have to prefix :not()
with something more specific than *
.
I suggest you use a class instead (which is always a good idea anyway):
<div class='keep-original'>
and then this will work:
*:not(.keep-original) * {
color: var(--colour-1);
}