Andy_Jake
Andy_Jake

Reputation: 144

Apply an effect on each element in html tag except one element (ID/class)

I want to apply an effect on every element of the html page except one ID (or class) when the user clicks/elicits an event. How can I do it? I tried with :not() selector, but I think it is not intended for it.

MWE:

index.html

<html>
  <head>
    <link disabled id="toggle_element" rel="stylesheet" href="./new_theme.css">
    <link rel="stylesheet" href="./style.css">
    <script src="./script.js" type="text/javascript"></script>
  </head>
  <body>
    <h1> Some text </h1>
    <button id="fixedbutton" onclick="change()">CLICKME</button>
    <button  id="anotherfixedbutton">please let me sleep me here firefox</button>
  </body>
</html>

style.css

html {
}

#fixedbutton {
  position: fixed;
  bottom: 20px;
  right: 20px;
}
h1{
  color:blue;
}

#anotherfixedbutton {
  position:fixed; 
  bottom:20px; 
  left: 20px
}

new_theme.css

html {
  filter: invert(100%) hue-rotate(180deg);
  -webkit-filter: invert(100%) hue-rotate(180deg);
  -moz-filter: invert(100%) hue-rotate(180deg); 
  -o-filter: invert(100%) hue-rotate(180deg);
  -ms-filter: invert(100%) hue-rotate(180deg);
}

script.js

function change()
{
  document.getElementById("toggle_element").disabled = false;
}

I want to exclude the fixed buttons from the effect of the filter. This example works fine and has no problem in Chrome and Safari, but in Firefox the buttons simply lose their positions.

Upvotes: 0

Views: 623

Answers (2)

Alexander Nied
Alexander Nied

Reputation: 13623

OK, so following up on the edits and looking into the related post there is a lot to unpack here. Between your original closed question and this new one with the edits, I see one (maybe two?) problems you are trying to solve:

  1. When you apply the filters, in Firefox the buttons lose their position.
  2. You would (maybe?) like the buttons to not be affected by the filter.

I've created a slightly modified snippets that works with your code and address both issues:

For the issue of button placement:

function change()
{
  document.getElementsByTagName('html')[0].classList.toggle('new-theme');
}
html {
  height: 100%; /* Fixes the buttons losing position in firefox */
}

.new-theme {
  filter: invert(100%) hue-rotate(180deg);
  -webkit-filter: invert(100%) hue-rotate(180deg);
  -moz-filter: invert(100%) hue-rotate(180deg); 
  -o-filter: invert(100%) hue-rotate(180deg);
  -ms-filter: invert(100%) hue-rotate(180deg);
}

#fixedbutton {
  position: fixed;
  bottom: 20px;
  right: 20px;
}
h1{
  color:blue;
}

#anotherfixedbutton {
  position:fixed; 
  bottom:20px; 
  left: 20px
}
<html>
  <head>
  </head>
  <body>
    <h1> Some text </h1>
    <button id="fixedbutton" onclick="change()">CLICKME</button>
    <button  id="anotherfixedbutton">please let me sleep me here firefox</button>
  </body>
</html>

The solution here for the buttons losing their position on Firefox was to add height: 100% to the html element. A bit strange, but similar to Temani Afif's answer on the purported duplicated of your original question; basically, because the filter creates a new containing block context we need to make some adjustments.

For excluding the buttons from the filter effect:

function change()
{
  document.getElementsByTagName('html')[0].classList.toggle('new-theme');
}
html {
  height: 100%; /* Fixes the buttons losing position in firefox */
}

.new-theme {
  filter: invert(100%) hue-rotate(180deg);
  -webkit-filter: invert(100%) hue-rotate(180deg);
  -moz-filter: invert(100%) hue-rotate(180deg); 
  -o-filter: invert(100%) hue-rotate(180deg);
  -ms-filter: invert(100%) hue-rotate(180deg);
}

.new-theme #fixedbutton,
.new-theme #anotherfixedbutton {
  filter: invert(100%) hue-rotate(180deg);
  -webkit-filter: invert(100%) hue-rotate(180deg);
  -moz-filter: invert(100%) hue-rotate(180deg); 
  -o-filter: invert(100%) hue-rotate(180deg);
  -ms-filter: invert(100%) hue-rotate(180deg);
}

#fixedbutton {
  position: fixed;
  bottom: 20px;
  right: 20px;
}
h1{
  color:blue;
}

h2 {
  color: orange;
}

#anotherfixedbutton {
  position:fixed; 
  bottom:20px; 
  left: 20px
}
<html>
  <head>
  </head>
  <body>
    <h1> Some text </h1>
    <h2> Some other text </h2>
    <button id="fixedbutton" onclick="change()">CLICKME</button>
    <button  id="anotherfixedbutton">please let me sleep me here firefox</button>
  </body>
</html>

Again, I'm not totally sure if this was an effect you were seeking. But regardless, the issue here is that the buttons have their color inverted not because they are selected by the .new-theme selector, but because they are contained within the .new-theme-classed element which is having the filter applied to it. However, because you are simply inverting the filters you are using, you can invert them again for those specific buttons when they are within a .new-theme-classed element, returning them their original hues.

Upvotes: 1

Tamino W.
Tamino W.

Reputation: 169

You can use JavaScript and add this to your code: (you don't need css with this code)

function highlight() {
    element = document.getElementById('not');
    document.documentElement.style.backgroundColor = '#f00';
    element.style.backgroundColor = '#fff';
}

Add the id "not" to the one element that you want to exclude and call the function with onClick="highlight()"

Upvotes: 1

Related Questions