Sepehr
Sepehr

Reputation: 49

Javascript DOM style disables css hover effect

I'm a beginner in javascript and I create a simple project to understand DOM style but faced with a problem. there is a p tag with a red background color and blue color hover effect. I put an onclick event on the p that when user clicks on the p, its background color changes to orange. the problem is when the background color changes with onclick event, the hover effect will be useless then. so is there any problem or this is the routine behavior of javascript?

<html>

<head>
  <style>
    #p2 {
      background-color: red;
    }
    
    #p2:hover {
      background-color: blue;
    }
  </style>
</head>

<body>
  <p id="p2" onclick="test()"> text </p>
  <script>
    function test() {
      document.getElementById("p2").style.backgroundColor = "orange";
    }
  </script>
</body>

</html>

I searched in Stackoverflow but unfortunately, these similar questions 1 and 2 didn't help.

Upvotes: 1

Views: 91

Answers (5)

Gohchi
Gohchi

Reputation: 469

My recommendation is to define the classes with the same priority to prevent using !important; (that could generate other problems)

<html>

<head>
  <style>
    #p2.red {
      background-color: red;
    }

    #p2.orange {
      background-color: orange;
    }
    
    #p2:hover {
      background-color: blue;
    }
  </style>
</head>

<body>
  <p id="p2" class="red" onclick="test(this)"> text </p>
  <script>
    function test(element) {
      element.classList.toggle("orange");
    }
  </script>
</body>

</html>

Upvotes: 2

imvain2
imvain2

Reputation: 15847

The problem here is due to inline styles having the highest specificity. There are many solutions for this, using !important is generally a bad method of solving it as its difficult to work with the bigger the project gets and various other reasons.

As a beginner now is the time to get into good habits. So for my answer, I got rid of both your inline onclick and your inline style change.

I'm using an event listener and querySelector to target your paragraph.

Then I'm adding a class to that element (you can use toggle to add/remove on click too).

For the CSS, I target the element via #p2.orange (orange is my class name). And I place it ABOVE the hover in the CSS itself.

const p = document.querySelector("#p2");

p.addEventListener("click",() => {
  p.classList.add("orange");
});
#p2 {
  background-color: red;
}

#p2.orange{
  background-color:orange;
}

#p2:hover {
  background-color: blue;
}
<p id="p2"> text </p>

Upvotes: 2

JMP
JMP

Reputation: 4467

You can use CSS variables to change the :hover colour.

:root{--clr:#0000ff;}

sets the initial colour,

background-color: var(--clr);

assigns the variable to the background-color style.

document.querySelector(':root').style.setProperty('--clr','orange');

then changes the variable from JavaScript.

<html>

<head>
  <style>

    :root{
      --clr:#0000ff;
    }

    #p2 {
      background-color: red;
    }
    
    #p2:hover {
      background-color: var(--clr);
    }
  </style>
</head>

<body>
  <p id="p2" onclick="test()"> text </p>
  <script>
    function test() {
     document.querySelector(':root').style.setProperty('--clr','orange');
    }
  </script>
</body>

</html>

Upvotes: 1

milklizard
milklizard

Reputation: 228

Because inline styles have higher specificity, it will override your css properties. You can counteract this by adding !important to your hover style:

<html>

<head>
  <style>
    #p2 {
      background-color: red;
    }
    
    #p2:hover {
      background-color: blue !important;
    }
  </style>
</head>

<body>
  <p id="p2" onclick="test()"> text </p>
  <script>
    function test() {
      document.getElementById("p2").style.backgroundColor = "orange";
    }
  </script>
</body>

</html>

Upvotes: 1

Ahmar
Ahmar

Reputation: 591

This is routine behavior of JavaScript.

When you change the background color of an element using JavaScript like: document.getElementById("p2").style.backgroundColor = "orange" it directly modifies the inline style of that element which takes precedence over any styles defined in the CSS, including the hover effect.

Here's a list if CSS Specificity Hierarchy.

Upvotes: 1

Related Questions