1

I have the following snippet where the display of the paragraphs are determined by whether the container has the class .dark-mode or not.

function toggleDarkMode() {
  const container = document.getElementById("container");
  container.classList.toggle("dark-mode");
}
:not(.dark-mode) .dark-mode-only {
  display: none;
}
.dark-mode .light-mode-only {
  display: none;
}
<div id="container">
  <p class="light-mode-only">
    Only for light mode.
  </p>
  <p class="dark-mode-only">
    Only for dark mode.
  </p>
  <button onclick="toggleDarkMode()">Toggle dark mode</button>
</div>

As you can see, clicking the button adds the .dark-mode class to the container, but the :not(.dark-mode) .dark-mode-only {...} selector does not actually work. However, if I simply add div in-front of this statement, it works again:

function toggleDarkMode() {
  const container = document.getElementById("container");
  container.classList.toggle("dark-mode");
}
div:not(.dark-mode) .dark-mode-only {
  display: none;
}
.dark-mode .light-mode-only {
  display: none;
}
<div id="container">
  <p class="light-mode-only">
    Only for light mode.
  </p>
  <p class="dark-mode-only">
    Only for dark mode.
  </p>
  <button onclick="toggleDarkMode()">Toggle dark mode</button>
</div>

So what exactly is the issue here? Does the :not selector work only when the element is specified before it? Thanks for any help.

EDIT Even using something like *:not(.dark-mode) does not work.

darkhorse
  • 8,192
  • 21
  • 72
  • 148

1 Answers1

4

:not(.dark-mode) will match anything that isn't .dark-mode, including <html> and <body>.

So this

:not(.dark-mode) .dark-mode-only {
  display: none;
}

resolves to body .dark-mode-only and hides your text.

Description

There are several unusual effects and outcomes when using :not() that you should keep in mind when using it:

  • :not(.foo) will match anything that isn't .foo, including and .

https://developer.mozilla.org/en-US/docs/Web/CSS/:not

lastr2d2
  • 3,604
  • 2
  • 22
  • 37
  • So essentially there is no way to wildcard this type of negation? – darkhorse Mar 02 '21 at 18:53
  • I will do it the other way around, hide the text for darkmode until it's within a `darkmode` object. Actually, for the case of dark-mode, the media query `prefers-color-scheme` may be a better choice – lastr2d2 Mar 02 '21 at 18:58