1

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.

1
  • 4
    This is because inline styles have a higher specificity Commented Jun 8, 2023 at 14:20

5 Answers 5

2

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>

Sign up to request clarification or add additional context in comments.

Comments

2

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>

2 Comments

isn't it an inline style when you are using inline "onclick" event?
there is onclick event on inline elements. you can run the snippet to test it.
1

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.

Comments

1

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>

Comments

1

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.