0

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.

Andy_Jake
  • 134
  • 1
  • 11

2 Answers2

1

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.

Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
  • for sure, this a working example, but my question is to apply on html{} and then to exclude one element. E.g., filters in Firefox simply disturb all the fixed position elements. Hence, I want to exclude those elements while applying the effect side-wide. ``` html .button(#skipme){ filter: invert(50%) hue-rotate(90deg); -webkit-filter: invert(50%) hue-rotate(90deg); -moz-filter: invert(50%) hue-rotate(90deg); -o-filter: invert(50%) hue-rotate(90deg); -ms-filter: invert(50%) hue-rotate(90deg); } ``` will not work (may be I'm doing it the wrong way). – Andy_Jake Sep 27 '19 at 04:45
  • @Andy_Jake - OK, so it sounds like there is more to this question than I understood. It might be a good idea to add the salient details to your question, so that it fully captures the nature of the issue that you are seeing. Otherwise, as you can see, the ambiguity in the question is leading to answers that don't fulfill your actual requirements. – Alexander Nied Sep 27 '19 at 13:48
  • Sure, I asked this question before with full details, but was marked duplicate. https://stackoverflow.com/questions/58089668/how-to-apply-filters-on-entire-html-without-affecting-fixed-positioned-elements So, I asked it in this way. – Andy_Jake Sep 27 '19 at 13:56
  • I see-- that's fair. It appears that there are a few people petitioning to reopen your question. Would it be possible for you to create a snippet in the question that illustrates the issue you are having? That would be, imo, the easiest way for the community to understand the problem and generate solutions for you. – Alexander Nied Sep 27 '19 at 14:05
  • Thanks for properly understanding BOTH my questions. I would like to accept this as the proper answer as it answers both my questions with the MWE. But, there is one thing to consider: 1. The solution `height:100%` works with pages that fit the height of the page, but if we try it on longer page (that are scrollable), the buttons' position break again. I tried by pasting `lorem ipsum` text to make the page longer, and it broke again. ANY pointers here? 2. However, color inversion works perfectly - what I wanted to achieve - Tx. – Andy_Jake Sep 28 '19 at 05:00
  • @Andy_Jake If you only want the element to size to the screen then scroll vertically you can use viewport units: `height: 100vh;` make sure to include handling that allows for the overflow to scroll. – Alexander Nied Sep 28 '19 at 05:03
  • tx for the solution, I have accepted the answer. The button in my real-case is a `returnt to top` button that I'd like to stay/float on the screen (on a fixed position) while the scroll up/down the page. – Andy_Jake Sep 28 '19 at 05:52
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/200085/discussion-between-andy-jake-and-alexander-nied). – Andy_Jake Sep 28 '19 at 06:24
1

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()"

Tamino W.
  • 139
  • 1
  • 1
  • 7